build system and configrun-sid.
* Makefile.am (all-local): Create version.h file with $(VERSION) in it.
* Makefile.in: Regenerated.
+2001-09-17 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ Changes to many generated files -- incorporate bochs into
+ build system and configrun-sid.
+
2001-07-24 Ben Elliston <bje@redhat.com>
* Makefile.am (install-data-local): Remove target.
+2001-07-10 matthew green <mrg@redhat.com>
+
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * configure: Regenerate.
+
2001-06-26 Frank Ch. Eigler <fche@redhat.com>
* Makefile.am (ACLOCAL_AMFLAGS): Refer to $srcdir.
2001-03-26 Frank Ch. Eigler <fche@redhat.com>
- * Makefile.am (install-data-local): Install COPYING.SID in $prefix.
- * Makefile.in: Regenerated.
+ * Makefile.am (install-data-local): Install COPYING.SID in $prefix.
+ * Makefile.in: Regenerated.
+
+2001-03-22 Ben Elliston <bje@redhat.com>
+
+ * Makefile.in: Regenerate.
+ * configure: Likewise.
+ * aclocal.m4: Likewise.
2001-03-21 Ben Elliston <bje@redhat.com>
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
target = @target@
AUTOMAKE_OPTIONS = foreign
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
Check for gdb components attached to processors other than the main
cpu. Adjust the enable-threshold of target-sched accordingly.
+2001-10-12 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * configrun-sid.in: Add -EL as default option for x86.
+
2001-10-04 Frank Ch. Eigler <fche@redhat.com>
* configrun-sid.in: Throughout, set boolean attributes only to
2001-10-03 Frank Ch. Eigler <fche@redhat.com>
- * configrun-sid.in (gdb): Add cfgroot relationship.
+ * configrun-sid.in (gdb): Add cfgroot relationship.
2001-09-27 Frank Ch. Eigler <fche@redhat.com>
- * configrun-sid.in (icache, dcache): New options.
+ * configrun-sid.in (icache, dcache): New options.
+
+2001-09-14 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * configrun-sid.in: Add x86 support.
+ * i386-elf-sid: New file.
2001-08-07 Ben Elliston <bje@redhat.com>
FAM3SCRIPTS = m68k-elf-sid
endif
+
+if SIDTARGET_X86
+FAM11SCRIPTS = i386-elf-sid
+endif
+
ALLFAMSCRIPTS = $(FAM0SCRIPTS) $(FAM1SCRIPTS) $(FAM2SCRIPTS) $(FAM3SCRIPTS) \
$(FAM4SCRIPTS) $(FAM5SCRIPTS) $(FAM6SCRIPTS) $(FAM7SCRIPTS) \
- $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS)
+ $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS) $(FAM11SCRIPTS) \
+ $(FAM12SCRIPTS)
bin_SCRIPTS = configrun-sid $(ALLFAMSCRIPTS)
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I $(srcdir)/../config
@SIDTARGET_M68K_TRUE@FAM3SCRIPTS = @SIDTARGET_M68K_TRUE@m68k-elf-sid
+@SIDTARGET_X86_TRUE@FAM11SCRIPTS = @SIDTARGET_X86_TRUE@i386-elf-sid
+
ALLFAMSCRIPTS = $(FAM0SCRIPTS) $(FAM1SCRIPTS) $(FAM2SCRIPTS) $(FAM3SCRIPTS) \
$(FAM4SCRIPTS) $(FAM5SCRIPTS) $(FAM6SCRIPTS) $(FAM7SCRIPTS) \
- $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS)
+ $(FAM8SCRIPTS) $(FAM9SCRIPTS) $(FAM10SCRIPTS) $(FAM11SCRIPTS) \
+ $(FAM12SCRIPTS)
bin_SCRIPTS = configrun-sid $(ALLFAMSCRIPTS)
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
%cpu_comptype = (
"arm" => "hw-cpu-arm7t",
"thumb" => "hw-cpu-arm7t",
+ "x86" => "hw-cpu-x86",
# INSERT NEW ENTRIES HERE
"m32r" => "hw-cpu-m32r/d"
);
%cpu_defaultendian = (
+ "x86" => "-EL",
"m32r" => "-EB"
);
%gloss_comptype = (
"arm" => "sw-gloss-arm/angel",
"thumb" => "sw-gloss-arm/angel",
+ "x86" => "sw-gloss-generic/libgloss",
# INSERT NEW ENTRIES HERE
"m32r" => "sw-gloss-m32r/libgloss"
);
%gloss_memspecs = (
"arm" => "0x00000000,0x00800000",
"thumb" => "0x00000000,0x00800000",
+ "x86" => "0x00000,0x500000",
# INSERT NEW ENTRIES HERE
"m32r" => "0x00000000,0x00800000"
);
set gloss verbose? $opt_verbose
connect-bus gloss target-memory $bus_upstream
";
+ if ($opt_cpu eq "x86")
+ {
+ $second_section .= "set gloss syscall-numbering-scheme cygmon\n";
+ }
if ($#exec_args >= 0) {
$second_section .= "# args
"sched" => "sched_component_library",
"tclapi" => "tcl_bridge_library",
"timers" => "timer_component_library",
- "uart" => "uart_component_library"
+ "uart" => "uart_component_library",
+ "x86" => "x86_component_library"
);
$second_section .= "connect-bus cpu data-memory $bus_upstream\n";
}
+if ($opt_cpu eq "x86")
+ {
+ $second_section .= "set cpu memory-mode cygmon\n";
+ }
+
if ($opt_gprof)
{
$second_section .= "# gprof connections
# --engine
if ($opt_engine eq "pbb")
{
- $second_section .= "set cpu engine-type pbb\n";
+# FIXME: the x86 component should support this setting
+ if ($opt_cpu ne "x86")
+ {
+ $second_section .= "set cpu engine-type pbb\n";
+ }
}
elsif ($opt_engine eq "scache")
{
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:1098: checking ARM family support" >&5
+echo "configure:1044: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:1058: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:1128: checking MIPS family support" >&5
+echo "configure:1072: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:1142: checking M32R family support" >&5
+echo "configure:1086: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:1156: checking M68K family support" >&5
+echo "configure:1100: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:1186: checking PPC family support" >&5
+echo "configure:1114: checking PPC family support" >&5
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
--- /dev/null
+#! /bin/sh
+
+exec `dirname $0`/configrun-sid --cpu x86 $@
2001-10-29 Frank Ch. Eigler <fche@redhat.com>
+ * pregen-configs.in (mep): Add --tksm for some configurations.
+
+2001-10-29 Frank Ch. Eigler <fche@redhat.com>
+
* (*.conf): Regenerated with memory component tweaks.
2001-10-26 Frank Ch. Eigler <fche@redhat.com>
* (*.conf): Regenerated with reset-net etc. tweaks.
+2001-10-19 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * i386-gdb.conf: New file.
+ * pregen-configs.in: Add lines for i386-gdb.conf.
+
+2001-10-17 Dave Brolley <brolley@redhat.com>
+
+ * All configs using --gdb regenerated.
+
+2001-10-12 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * i386-gloss.conf: New file.
+ * pregen-configs.in: Add code to generate i386-gloss.conf.
+
2001-10-04 Frank Ch. Eigler <fche@redhat.com>
* (*.conf): Regenerated without superfluous bool attr settings.
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I $(srcdir)/../../config
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:14 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
# args: --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL --tksm
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libtclapi.la tcl_bridge_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:13 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
# args: --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:37 EST 2001
# args: --cpu=arm --no-run --gdb=5000 -EL --tksm
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libtclapi.la tcl_bridge_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:11 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:37 EST 2001
# args: --cpu=arm --no-run --gdb=5000 -EL
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
# args: --cpu=arm --no-run --gdb=5000 -EB
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.30 2001/11/08 21:55:10 fche Exp
-# run by bje @ scooby.brisbane.redhat.com (Linux) at Sun Nov 18 22:33:00 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
# args: --cpu=arm --no-run --board=pid7t-redboot-uart1:5000 -EL --tksm
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libtclapi.la tcl_bridge_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
# first section
new hw-cpu-arm7t cpu
new hw-mapper-basic cpu-mapper
# sid configuration file
-# created by Id: configrun-sid.in,v 1.30 2001/11/08 21:55:10 fche Exp
-# run by bje @ scooby.brisbane.redhat.com (Linux) at Sun Nov 18 22:33:00 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
# args: --cpu=arm --no-run --board=pid7t-redboot-uart1:5000 -EL
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
# first section
new hw-cpu-arm7t cpu
new hw-mapper-basic cpu-mapper
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
# args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EL --tksm
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libtclapi.la tcl_bridge_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
# args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EL
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
# sid configuration file
-# created by Id: configrun-sid.in,v 1.28 2001/10/29 17:44:36 fche Exp
-# run by fche @ tooth (Linux) at Mon Oct 29 13:08:12 EST 2001
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:38 EST 2001
# args: --cpu=arm --no-run --gdb=5000 --board=pid7t-uart1:gdb -EB
load libaudio.la audio_component_library
load libcache.la cache_component_library
load libsched.la sched_component_library
load libtimers.la timer_component_library
load libuart.la uart_component_library
+load libx86.la x86_component_library
set main persistent? true
# first section
new hw-cpu-arm7t cpu
--- /dev/null
+# sid configuration file
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:40 EST 2001
+# args: --cpu=x86 --no-run --gdb=5000
+load libaudio.la audio_component_library
+load libcache.la cache_component_library
+load libcgencpu.la cgen_component_library
+load libconsoles.la console_component_library
+load libgdb.la gdb_component_library
+load libgloss.la gloss_component_library
+load libglue.la glue_component_library
+load libhd44780u.la hd44780u_component_library
+load libide.la ide_component_library
+load libinterrupt.la interrupt_component_library
+load libloader.la loader_component_library
+load libmapper.la mapper_component_library
+load libmemory.la mem_component_library
+load libmmu.la mmu_component_library
+load libparport.la parport_component_library
+load libprof.la prof_component_library
+load librtc.la rtc_component_library
+load libsched.la sched_component_library
+load libtimers.la timer_component_library
+load libuart.la uart_component_library
+load libx86.la x86_component_library
+set main persistent? true
+# first section
+new hw-cpu-x86 cpu
+new hw-mapper-basic cpu-mapper
+new hw-glue-sequence-8 init-sequence
+new hw-glue-sequence-1 hw-reset-net
+new hw-glue-sequence-8 deinit-sequence
+new hw-glue-sequence-1 yield-net
+new hw-glue-sequence-2 cache-flush-net
+new sid-sched-host-accurate host-sched
+new sid-sched-sim target-sched
+# gloss
+new sw-gloss-generic/libgloss gloss
+# cpu gdb
+new sw-debug-gdb cpu-gdb
+new sid-io-socket-server cpu-gdb-socket
+# memory region 1 (0x00000,0x500000)
+new hw-memory-ram/rom-basic mem1
+# second section
+# settings
+set cpu step-insn-count 10000
+set host-sched num-clients 10 # large enough?
+set target-sched num-clients 10 # large enough?
+# pin connections
+connect-pin main perform-activity -> host-sched advance
+connect-pin main perform-activity -> target-sched advance
+connect-pin main starting -> init-sequence input
+connect-pin main stopping -> deinit-sequence input
+connect-pin init-sequence output-0 -> hw-reset-net input
+connect-pin hw-reset-net output-0 -> cpu reset!
+connect-pin target-sched 0-event -> cpu step!
+connect-pin target-sched 0-control <- cpu step-cycles
+connect-pin yield-net output-0 -> cpu yield
+connect-pin yield-net output-0 -> host-sched yield
+connect-bus cpu insn-memory cpu-mapper access-port
+connect-bus cpu data-memory cpu-mapper access-port
+set cpu memory-mode cygmon
+# gloss
+relate gloss cpu cpu
+connect-pin init-sequence output-2 -> gloss reset
+connect-pin cpu trap <-> gloss trap
+connect-pin cpu trap-code -> gloss trap-code
+set gloss verbose? 0
+connect-bus gloss target-memory cpu-mapper access-port
+set gloss syscall-numbering-scheme cygmon
+# cpu-gdb
+relate cpu-gdb cpu cpu
+relate cpu-gdb cfgroot main
+relate cpu-gdb target-schedulers target-sched
+relate cpu-gdb host-schedulers host-sched
+connect-pin cpu-gdb process-signal -> main stop!
+connect-pin init-sequence output-3 -> cpu-gdb init
+connect-pin deinit-sequence output-5 -> cpu-gdb deinit
+connect-pin cpu-gdb yield -> yield-net input
+connect-pin cpu-gdb flush-icache -> cache-flush-net input
+connect-pin cache-flush-net output-1 -> cpu flush-icache
+connect-pin cpu-gdb restart -> hw-reset-net input
+set cpu-gdb exit-on-detach? 1
+# cpu-gdb-socket
+connect-pin init-sequence output-2 -> cpu-gdb-socket init
+connect-pin deinit-sequence output-6 -> cpu-gdb-socket fini
+connect-pin cpu-gdb-socket rx -> cpu-gdb remote-rx
+connect-pin cpu-gdb-socket tx <- cpu-gdb remote-tx
+connect-pin host-sched 6-event -> cpu-gdb-socket poll-event
+connect-pin host-sched 6-control <- cpu-gdb-socket poll-control
+set cpu-gdb-socket sockaddr-local 0.0.0.0:5000
+# gdb w/ gloss
+connect-pin gloss trap-chain <-> cpu-gdb trap
+connect-pin gloss trap-code-chain -> cpu-gdb trap-code
+connect-pin gloss process-signal -> cpu-gdb gloss-process-signal
+connect-pin gloss debug-tx -> cpu-gdb target-tx
+relate cpu-gdb gloss gloss
+set cpu-gdb enable-Z-packet? false
+set cpu-gdb operating-mode? false
+set cpu endian little
+# memory region 1 (0x00000,0x500000) configuration
+set mem1 size 5242880
+connect-bus cpu-mapper mem1:[0,5242879] mem1 read-write-port
--- /dev/null
+# sid configuration file
+# created by Id: configrun-sid.in,v 1.99 2001/10/29 17:44:36 fche Exp
+# run by fche @ tooth (Linux) at Mon Oct 29 13:01:39 EST 2001
+# args: --cpu=x86 --no-run a.out
+load libaudio.la audio_component_library
+load libcache.la cache_component_library
+load libcgencpu.la cgen_component_library
+load libconsoles.la console_component_library
+load libgdb.la gdb_component_library
+load libgloss.la gloss_component_library
+load libglue.la glue_component_library
+load libhd44780u.la hd44780u_component_library
+load libide.la ide_component_library
+load libinterrupt.la interrupt_component_library
+load libloader.la loader_component_library
+load libmapper.la mapper_component_library
+load libmemory.la mem_component_library
+load libmmu.la mmu_component_library
+load libparport.la parport_component_library
+load libprof.la prof_component_library
+load librtc.la rtc_component_library
+load libsched.la sched_component_library
+load libtimers.la timer_component_library
+load libuart.la uart_component_library
+load libx86.la x86_component_library
+# first section
+new hw-cpu-x86 cpu
+new hw-mapper-basic cpu-mapper
+new hw-glue-sequence-8 init-sequence
+new hw-glue-sequence-1 hw-reset-net
+new hw-glue-sequence-8 deinit-sequence
+new hw-glue-sequence-1 yield-net
+new hw-glue-sequence-2 cache-flush-net
+new sid-sched-host-accurate host-sched
+new sid-sched-sim target-sched
+# gloss
+new sw-gloss-generic/libgloss gloss
+# gloss <-> stdio
+new sid-io-stdio stdio
+# cpu loader
+new sw-load-elf cpu-loader
+# memory region 1 (0x00000,0x500000)
+new hw-memory-ram/rom-basic mem1
+# second section
+# settings
+set cpu step-insn-count 10000
+set host-sched num-clients 10 # large enough?
+set target-sched num-clients 10 # large enough?
+# pin connections
+connect-pin main perform-activity -> host-sched advance
+connect-pin main perform-activity -> target-sched advance
+connect-pin main starting -> init-sequence input
+connect-pin main stopping -> deinit-sequence input
+connect-pin init-sequence output-0 -> hw-reset-net input
+connect-pin hw-reset-net output-0 -> cpu reset!
+connect-pin target-sched 0-event -> cpu step!
+connect-pin target-sched 0-control <- cpu step-cycles
+connect-pin yield-net output-0 -> cpu yield
+connect-pin yield-net output-0 -> host-sched yield
+connect-bus cpu insn-memory cpu-mapper access-port
+connect-bus cpu data-memory cpu-mapper access-port
+set cpu memory-mode cygmon
+# gloss
+relate gloss cpu cpu
+connect-pin init-sequence output-2 -> gloss reset
+connect-pin cpu trap <-> gloss trap
+connect-pin cpu trap-code -> gloss trap-code
+set gloss verbose? 0
+connect-bus gloss target-memory cpu-mapper access-port
+set gloss syscall-numbering-scheme cygmon
+# gloss <-> stdio
+set host-sched 0-regular? 1
+set host-sched 0-time 150 # apprx. human perception limit
+connect-pin host-sched 0-event -> stdio poll
+connect-pin gloss debug-tx -> stdio stdout
+connect-pin gloss debug-rx <- stdio stdin
+# gloss w/o gdb
+connect-pin gloss process-signal -> main stop!
+connect-pin gloss process-signal -> yield-net input
+# cpu loader
+set cpu-loader file "a.out"
+connect-bus cpu-loader load-accessor-data cpu-mapper access-port
+connect-bus cpu-loader load-accessor-insn cpu-mapper access-port # don't trace loading
+connect-pin init-sequence output-1 -> cpu-loader load!
+connect-pin cpu-loader start-pc-set -> cpu start-pc-set!
+connect-pin cpu-loader endian-set -> cpu endian-set!
+connect-pin cpu-loader error -> main stop!
+# memory region 1 (0x00000,0x500000) configuration
+set mem1 size 5242880
+connect-bus cpu-mapper mem1:[0,5242879] mem1 read-write-port
crs --cpu=arm --no-run --gdb=5000 --board=cma110:cma222-uart1:gdb -EL --tksm
mvic sid.conf arm-cma-tksm.conf
+
+crs --cpu=x86 --no-run a.out
+mvic a.out.conf i386-gloss.conf
+
+crs --cpu=x86 --no-run --gdb=5000
+mvic sid.conf i386-gdb.conf
+
DIRECTORY DSO COMPONENT_LIBRARY MAINTAINERS
audio libaudio.la audio_component_library Red Hat
+bochs libx86.la x86_component_library Red Hat
cache libcache.la cache_component_library Red Hat
cfgroot libconfig.la config_component_library Red Hat
cgen-cpu libcgencpu.la cgen_component_library Red Hat
hw-cache-basic Basic 16kb direct-mapped cache
hw-cache-* Other memory caches (ref. component docs)
hw-cpu-arm7t ARM7 / ARM7T CPU model
+hw-cpu-x86 X86 CPU model
hw-cpu-m32r/d M32R/D CPU model
hw-disk-ide IDE hard drive model (controller + drives)
hw-glue-bus-mux Bus multiplexer
+2001-11-13 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * CATALOG: Document the x86_component_library. Add
+ hw-cpu-x86.
+
+2001-10-01 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * tconfig.in: Add x86 support.
+
2001-09-24 Frank Ch. Eigler <fche@redhat.com>
* configure.in (lcd_libs): Set HAVE_CURSES_LIBRARY if found some
- usable curses library.
+ usable curses library.
* config.in, configure: Regenerated.
2001-07-25 Frank Ch. Eigler <fche@redhat.com>
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
info: info-recursive
dvi-am:
dvi: dvi-recursive
-check-am:
+check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
-install-info-am:
-install-info: install-info-recursive
all-recursive-am: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info all-recursive-am install-exec-am install-exec \
-install-data-am install-data install-am install uninstall-am uninstall \
-all-local all-redirect all-am all installdirs-am installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-local all-redirect all-am all \
+installdirs-am installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
all-local:
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
--- /dev/null
+2001-11-15 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * bochs.h [BX_SUPPORT_SID] (BX_VGA_MEM_READ): Change
+ expansion to 0 from NULL to prevent compiler warnings.
+
+ * cpu/cpu-sid.h: Remove #define for LOG_THIS; it
+ was causing the compiler to issue redefinition warnings.
+ * cpu/cpu-sid.cc: Add #define for LOG_THIS, to
+ prevent compiler warnings.
+ * cpu/init-sid.cc: Likewise.
+ * memory/memory-sid.cc: Likewise.
+
+2001-11-13 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/cpu-sid.cc: Added proper copyright notice.
+ * cpu/cpu-sid.h: Likewise.
+ * cpu/debugstuff-sid.cc: Likewise.
+ * cpu/exception-sid.cc: Likewise.
+ * cpu/fetchdecode-sid.cc: Likewise.
+ * cpu/init-sid.cc: Likewise.
+ * cpu/x86-memory-modes.cc: Likewise.
+ * cpu/x86.cc: Likewise.
+ * cpu/x86.h: Likewise.
+ * memory/memory-sid.cc: Likewise.
+ * memory/memory-sid.h: Likewise.
+ * cpu/debugstuff-sid.cc: Remove unneeded debug message.
+ * README: New file.
+
+2001-11-09 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/debugstuff-sid.cc (dbg_set_reg): Remove some checks that
+ bochs performed when writing to the eflags register. They were
+ causing some gdb testsuite failures.
+ * memory/memory-sid.cc: Add exception handling to read_physical
+ and write_physical.
+
+2001-11-07 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/x86-memory-modes.cc: Change memory mode setup to use
+ sidcpuutil.h write_data_memory functions.
+ * cpu/x86-memory-modes.cc: Change default memory mode's gdt to
+ more closely resemble cygmon mode's.
+ * cpu/x86.cc: Remove write_memory and read_memory implementations.
+ * cpu/x86.h: Make sid_mem_c's read_physical and write_physical
+ friends of x86_cpu.
+ * cpu/x86.h: Remove write_memory and read_memory declarations.
+ * memory/memory-sid.cc: Rewrite write_physical and read_physical
+ implementations to use sidcpuutil.h's write_data_memory_* and
+ read_data_memory_* members.
+
+2001-10-15 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in (AC_CHECK_SIZEOF*): Give default sizes for
+ canadian-cross builds.
+ * configure: Regenerated.
+
+2001-10-12 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/x86.cc: Add blocking_on_syscall again.
+ * cpu/x86.h: Add blocking_on_syscall again.
+ * cpu/exception-sid.cc: Add trap to breakpoint comment.
+
+ * bochs.h: Include debug/debug.h.
+ * cpu/Makefile.am: Add debug.h to INCLUDES and added debugstuff-sid.cc
+ to libcpu_la_SOURCES.
+ * cpu/cpu-sid.cc: Add detail to error reporting.
+ * cpu/cpu-sid.h: Add dbg_get_eflags, dbg_get_reg, dbg_set_reg, INT3
+ removed verbose_p.
+ * cpu/exception-sid.cc: Intercept vector == 0x03 to call do_breakpoint.
+ * cpu/fetchdecode-sid.cc: Change BxOpcodeInfo to call sid version of INT3.
+ * cpu/soft_int-sid.cc: Include INT3 implementation.
+ * cpu/x86-memory-modes.cc: Change limit_scaled's to the proper value,
+ 0xffffffff.
+ * cpu/x86.cc: Remove blocking_on_syscall, remove watchable_register "pc".
+ * cpu/x86.cc: Add call to create_gdb_register_attrs.
+ * cpu/x86.cc: Change do_syscall to use yield() rather than
+ blocking_on_syscall.
+ * cpu/x86.cc (step_insn): Catch cpu_exception, and add call to signal_trap
+ when enable_step_trap_p is set.
+ * cpu/x86.cc: Add implementations for do_breakpoint, flush_icache,
+ dgb_get_reg, dbg_set_reg, remove set_endian.
+ * cpu/x86.h: Add do_breakpoint, remove set_endian and blocking_on_syscall.
+ * cpu/x86.h: Change x86 component to a basic_bi_endian_cpu from a
+ basic_little_endian_cpu.
+
+2001-10-01 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * Makefile.am: Add conditional compiling of cpu/* fpu/* and
+ memory/* files.
+ * components.cxx: Add info to generate stub when sid not
+ configured for x86 target.
+ * cpu/x86.h: Add verbose_p member.
+ * cpu/x86.cc: Add verbose_p support.
+
+2001-09-28 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in: Removed AC_OUTPUT calls for nonexistent subdirs.
+ * configure: Regenerated.
+
+2001-09-24 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * fpu/*: Add fpu support to bochs component.
+
+2001-09-23 Frank Ch. Eigler <fche@redhat.com>
+
+ * configure.in (with_nogui): Hard-code --with-nogui.
+ * configure: Regenerated.
+
+2001-09-18 Frank Ch. Eigler <fche@redhat.com>
+
+ * memory/misc_mem.cc (BX_MEM_C): Use sprintf, not snprintf, for
+ portability to Solaris.
+
+2001-09-18 Frank Ch. Eigler <fche@redhat.com>
+
+ * cpu/cpu.cc (prefetch): Make itranslate_* call conditional on
+ BX_SUPPORT_PAGING.
+ * cpu/cpu.h ({i,d}translate_linear): Make declaration conditional.
+ * cpu/main-hack.cc (main): Comment out if BX_SUPPORT_SID.
+
+2001-09-13 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/*: Remove deprecated files: memory-base.h memory-bochs.cc
+ memory-bochs.h memory-sid.cc memory-sid.h misc_mem.cc.
+ * memory/*: Remove deprecated files: memory-base.h memory-bochs.cc
+ memory-bochs.h.
+ * cpu/x86-memory-modes.cc: Add support for cygmon protected
+ memory mode.
+ * cpu/x86.cc: Add proper handling of signal_trap return values
+ to do_syscall().
+ * cpu/x86.h: Add memory-mode member to x86_cpu.
+
+2001-08-30 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * cpu/*: Make changes to support syscalls.
+
+2001-08-20 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ Subclass BX_CPU_C to create sid_cpu_c class.
+
+ Make changes to fetch/decode code; bochs now runs test asm program.
--- /dev/null
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I ../../config
+
+pkglib_LTLIBRARIES = libx86.la
+
+if SIDTARGET_X86
+SUBDIRLIST = fpu cpu memory .
+SUBLIBLIST = fpu/libfpu.la cpu/libcpu.la memory/libmemory.la
+else
+SUBDIRLIST =
+SUBLIBLIST =
+endif
+
+SUBDIRS = $(SUBDIRLIST)
+
+INCLUDES = -I$(top_builddir)/.. -I$(top_builddir)/../../include -I$(srcdir)/../../include -I$(srcdir)/cpu -I$(srcdir)/memory
+
+libx86_la_SOURCES = components.cxx
+libx86_la_LDFLAGS = -module -no-undefined
+libx86_la_LIBADD = $(SUBLIBLIST)
+libx86_la_DEPENDENCIES = $(SUBLIBLIST)
+
+AUTOHEADER = echo "Not running autoheader"
+
--- /dev/null
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I ../../config
+
+pkglib_LTLIBRARIES = libx86.la
+@SIDTARGET_X86_TRUE@SUBDIRLIST = @SIDTARGET_X86_TRUE@fpu cpu memory .
+@SIDTARGET_X86_FALSE@SUBDIRLIST =
+@SIDTARGET_X86_TRUE@SUBLIBLIST = @SIDTARGET_X86_TRUE@fpu/libfpu.la cpu/libcpu.la memory/libmemory.la
+@SIDTARGET_X86_FALSE@SUBLIBLIST =
+
+SUBDIRS = $(SUBDIRLIST)
+
+INCLUDES = -I$(top_builddir)/.. -I$(top_builddir)/../../include -I$(srcdir)/../../include -I$(srcdir)/cpu -I$(srcdir)/memory
+
+libx86_la_SOURCES = components.cxx
+libx86_la_LDFLAGS = -module -no-undefined
+libx86_la_LIBADD = $(SUBLIBLIST)
+libx86_la_DEPENDENCIES = $(SUBLIBLIST)
+
+AUTOHEADER = echo "Not running autoheader"
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libx86_la_OBJECTS = components.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+aclocal.m4 config.guess config.h.in config.sub configure configure.in \
+install-sh ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DIST_SUBDIRS = fpu cpu memory .
+DEP_FILES = .deps/components.P
+SOURCES = $(libx86_la_SOURCES)
+OBJECTS = $(libx86_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cxx .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \
+ ../../config/am_rpm_init.m4 ../../config/cgen-maint.m4 \
+ ../../config/docbuild.m4 ../../config/libstdc++.m4 \
+ ../../config/libtool.m4 ../../config/ltdl.m4 \
+ ../../config/sidtargets.m4
+ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-pkglibLTLIBRARIES:
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+
+distclean-pkglibLTLIBRARIES:
+
+maintainer-clean-pkglibLTLIBRARIES:
+
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libx86.la: $(libx86_la_OBJECTS) $(libx86_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(pkglibdir) $(libx86_la_LDFLAGS) $(libx86_la_OBJECTS) $(libx86_la_LIBADD) $(LIBS)
+.cxx.o:
+ $(CXXCOMPILE) -c $<
+.cxx.lo:
+ $(LTCXXCOMPILE) -c $<
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(DIST_SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-pkglibLTLIBRARIES
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am: uninstall-pkglibLTLIBRARIES
+uninstall: uninstall-recursive
+all-am: Makefile $(LTLIBRARIES) config.h
+all-redirect: all-recursive-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+ $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-pkglibLTLIBRARIES \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-hdr clean-pkglibLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-hdr distclean-pkglibLTLIBRARIES \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-depend distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-pkglibLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-pkglibLTLIBRARIES distclean-pkglibLTLIBRARIES \
+clean-pkglibLTLIBRARIES maintainer-clean-pkglibLTLIBRARIES \
+uninstall-pkglibLTLIBRARIES install-pkglibLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool install-data-recursive \
+uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+This is the sid x86 component. It is based heavily on code from bochs
+1.2.1. I have tried to "wrap" the bochs code as much as possible so
+that new bochs releases can be easily incorporated. The design looks
+something like this:
+
++-----------------------------------------------------+
+| |
+| x86_cpu object (see cpu/x86.h) |<---+
+| |<-+ |
+| +---------------------------------------------+ | | |
+| | sid_cpu_c object (see cpu/cpu-sid.h) | | | |
+| | | | | |
+| | x86_cpu * ------------------------------------+ |
+| | | | |
+| +---------------------------------------------+ | |
+| +---------------------------------------------+ | |
+| | sid_mem_c object (see memory/memory-sid.h) | | |
+| | | | |
+| | x86_cpu * --------------------------------------+
+| | | |
+| +---------------------------------------------+ |
++-----------------------------------------------------+
+
+The sid_cpu_c class inherits from bx_cpu_c which is the main bochs cpu
+class. Likewise, sid_mem_c inherits from bx_mem_c, the main bochs
+memory class. Anytime a bochs member function needed to be changed to
+work in the sid framework, I overrode the function in either sid_cpu_c
+or sid_mem_c.
+
--- /dev/null
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
+
+# serial 41 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+AC_ARG_WITH(pic,
+ [ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+ pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([DllMain (0, 0, 0);],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);],
+ [lt_cv_need_dllmain=yes],[lt_cv_need_dllmain=no])])
+
+ case $host in
+ *-*-cygwin*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ *-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ esac
+ ;;
+ ])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+dnl sidtargets.m4 -*- m4 -*-
+
+dnl Copyright (C) 1999, 2000, 2001 Red Hat.
+dnl This file is part of SID and is licensed under the GPL.
+dnl See the file COPYING.SID for conditions for redistribution.
+
+dnl Use CY_SIDTARGET_CHECK in configure.in to respond to the builder's
+dnl selection of --target/--enable-targets
+
+AC_DEFUN(CY_SIDTARGET_CHECK, [
+
+
+dnl Assume all targets if $host==$target or $target==NONE
+sid_host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host`
+sid_target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target`
+
+if test "$sid_host" = "$sid_target" -o "$target" = "NONE"
+then
+ AC_MSG_WARN(Assuming --enable-targets=all)
+ all_targets=""
+ sidtarget_default=1
+else
+ all_targets="$target"
+ sidtarget_default=0
+fi
+
+
+AC_ARG_ENABLE(targets,
+[ --enable-targets=LIST support given additional targets, or all],
+[
+ case "${enable_targets}" in
+ all) sidtarget_default=1 ;;
+ no) sidtarget_default=0 ;;
+ *) all_targets="${all_targets} `echo ${enable_targets} | sed -e 's-,- -g'`" ;;
+ esac
+])
+
+dnl Enumerate known chip families
+sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
+sidtarget_mips=$sidtarget_default
+sidtarget_m32r=$sidtarget_default
+sidtarget_m68k=$sidtarget_default
+sidtarget_ppc=$sidtarget_default
+
+dnl Iterate over all listed targets
+for targ in $all_targets
+do
+ case "$targ" in
+ arm*) sidtarget_arm=1 ;;
+ thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
+ mips*) sidtarget_mips=1 ;;
+ m32r*) sidtarget_m32r=1 ;;
+ m68k*) sidtarget_m68k=1 ;;
+ powerpc*) sidtarget_ppc=1 ;;
+ ppc*) sidtarget_ppc=1 ;;
+ *) AC_MSG_WARN("Unknown target $targ") ;;
+ esac
+done
+
+dnl Ensure at least one of these variables is non-zero.
+case 1 in
+ ${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
+ ${sidtarget_mips}) ;;
+ ${sidtarget_m32r}) ;;
+ ${sidtarget_m68k}) ;;
+ ${sidtarget_ppc}) ;;
+ *) AC_MSG_WARN([No selected sid targets: use --enable-targets or --target])
+ ;;
+esac
+
+dnl Report results SIDTARGET_family
+dnl nb: Use "x$sidtarget_family" in the tested expression to prevent
+dnl syntax errors in configure when sidtarget_family is left unset.
+
+AC_MSG_CHECKING(ARM family support)
+AC_SUBST(sidtarget_arm)
+AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
+AC_MSG_RESULT($sidtarget_arm)
+
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
+AC_MSG_CHECKING(MIPS family support)
+AC_SUBST(sidtarget_mips)
+AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
+AC_MSG_RESULT($sidtarget_mips)
+
+AC_MSG_CHECKING(M32R family support)
+AC_SUBST(sidtarget_m32r)
+AM_CONDITIONAL(SIDTARGET_M32R,[test "x$sidtarget_m32r" = x1])
+AC_MSG_RESULT($sidtarget_m32r)
+
+AC_MSG_CHECKING(M68K family support)
+AC_SUBST(sidtarget_m68k)
+AM_CONDITIONAL(SIDTARGET_M68K,[test "x$sidtarget_m68k" = x1])
+AC_MSG_RESULT($sidtarget_m68k)
+
+AC_MSG_CHECKING(PPC family support)
+AC_SUBST(sidtarget_ppc)
+AM_CONDITIONAL(SIDTARGET_PPC,[test "x$sidtarget_ppc" = x1])
+AC_MSG_RESULT($sidtarget_ppc)
+
+])
+
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+//
+// bochs.h is the master header file for all C++ code. It includes all
+// the system header files needed by bochs, and also includes all the bochs
+// C++ header files. Because bochs.h and the files that it includes has
+// structure and class definitions, it cannot be called from C code.
+//
+
+#ifndef BX_BOCHS_H
+# define BX_BOCHS_H 1
+
+extern "C" {
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef WIN32
+# include <unistd.h>
+#else
+# include <io.h>
+#endif
+#include <time.h>
+#ifdef macintosh
+# include <types.h>
+# include <stat.h>
+# include <utime.h>
+#else
+# ifndef WIN32
+# include <sys/time.h>
+# endif
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+#include <ctype.h>
+#include <string.h>
+#include <fcntl.h>
+#ifdef macintosh
+# include "macutils.h"
+# define SuperDrive "[fd:]"
+#endif
+}
+
+// Hacks for win32: always return regular file.
+#ifdef WIN32
+#ifndef __MINGW32__
+# define S_ISREG(st_mode) 1
+# define S_ISCHR(st_mode) 0
+
+// VCPP includes also are missing these
+# define off_t long
+# define ssize_t int
+
+// win32 has snprintf though with different name.
+#define snprintf _snprintf
+#endif
+
+#endif
+
+#define BX_SUPPORT_SID 1
+
+#if BX_SUPPORT_SID
+# include "config.h" /* generated by configure script from config.h.in */
+# include "debug/debug.h"
+# include "bxversion.h"
+#else
+# include "config.h" /* generated by configure script from config.h.in */
+# include "osdep.h" /* platform dependent includes and defines */
+# include "debug/debug.h"
+# include "bxversion.h"
+#endif
+
+
+#if BX_SUPPORT_SID
+class sid_mem_c;
+#define BX_MEM_DECL sid_mem_c
+#else
+#define BX_MEM_DECL BX_MEM_C
+#endif // BX_SUPPORT_SID
+
+//
+// some macros to interface the CPU and memory to external environment
+// so that these functions can be redirected to the debugger when
+// needed.
+//
+
+#if ((BX_DEBUGGER == 1) && (BX_NUM_SIMULATORS >= 2))
+// =-=-=-=-=-=-=- Redirected to cosimulation debugger -=-=-=-=-=-=-=
+#define BX_VGA_MEM_READ(addr) bx_dbg_ucmem_read(addr)
+#define BX_VGA_MEM_WRITE(addr, val) bx_dbg_ucmem_write(addr, val)
+#if BX_SUPPORT_A20
+# define A20ADDR(x) ( (x) & bx_pc_system.a20_mask )
+#else
+# define A20ADDR(x) (x)
+#endif
+#define BX_INP(addr, len) bx_dbg_inp(addr, len)
+#define BX_OUTP(addr, val, len) bx_dbg_outp(addr, val, len)
+#define BX_HRQ (bx_pc_system.HRQ)
+#define BX_RAISE_HLDA() bx_dbg_raise_HLDA()
+#define BX_TICK1()
+#define BX_INTR bx_pc_system.INTR
+#define BX_SET_INTR(b) bx_dbg_set_INTR(b)
+#if BX_SIM_ID == 0
+# define BX_CPU_C bx_cpu0_c
+# define BX_CPU bx_cpu0
+# define BX_MEM_C bx_mem0_c
+# define BX_MEM bx_mem0
+#else
+# define BX_CPU_C bx_cpu1_c
+# define BX_CPU bx_cpu1
+# define BX_MEM_C bx_mem1_c
+# define BX_MEM bx_mem1
+#endif
+#define BX_SET_ENABLE_A20(enabled) bx_dbg_async_pin_request(BX_DBG_ASYNC_PENDING_A20, \
+ enabled)
+#define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20()
+#error FIXME: cosim mode not fixed yet
+
+#else
+
+// =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#if BX_SUPPORT_SID
+#define BX_VGA_MEM_READ(addr) 0
+#define BX_VGA_MEM_WRITE(addr, val)
+#else
+#define BX_VGA_MEM_READ(addr) (bx_devices.vga->mem_read(addr))
+#define BX_VGA_MEM_WRITE(addr, val) bx_devices.vga->mem_write(addr, val)
+#endif
+#if BX_SUPPORT_A20
+# define A20ADDR(x) ( (x) & bx_pc_system.a20_mask )
+#else
+# define A20ADDR(x) (x)
+#endif
+//
+// some pc_systems functions just redirect to the IO devices so optimize
+// by eliminating call here
+//
+// #define BX_INP(addr, len) bx_pc_system.inp(addr, len)
+// #define BX_OUTP(addr, val, len) bx_pc_system.outp(addr, val, len)
+#define BX_INP(addr, len) bx_devices.inp(addr, len)
+#define BX_OUTP(addr, val, len) bx_devices.outp(addr, val, len)
+#define BX_HRQ (bx_pc_system.HRQ)
+#define BX_RAISE_HLDA() bx_pc_system.raise_HLDA()
+#if BX_SUPPORT_SID
+#define BX_TICK1()
+#else
+#define BX_TICK1() bx_pc_system.tick1()
+#endif // BX_SUPPORT_SID
+#define BX_TICKN(n) bx_pc_system.tickn(n)
+#define BX_INTR bx_pc_system.INTR
+#define BX_SET_INTR(b) bx_pc_system.set_INTR(b)
+#define BX_CPU_C bx_cpu_c
+#define BX_MEM_C bx_mem_c
+#if BX_SMP_PROCESSORS==1
+#define BX_CPU(x) (&bx_cpu)
+#define BX_MEM(x) (&bx_mem)
+#else
+#define BX_CPU(x) (bx_cpu_array[x])
+#define BX_MEM(x) (bx_mem_array[x])
+#endif
+
+#define BX_SET_ENABLE_A20(enabled) bx_pc_system.set_enable_a20(enabled)
+#define BX_GET_ENABLE_A20() bx_pc_system.get_enable_a20()
+
+#endif
+
+// you can't use static member functions on the CPU, if there are going
+// to be 2 cpus. Check this early on.
+#if (BX_SMP_PROCESSORS>1)
+# if (BX_USE_CPU_SMF!=0)
+# error For SMP simulation, BX_USE_CPU_SMF must be 0.
+# endif
+#endif
+
+
+// #define BX_IAC() bx_pc_system.IAC()
+#define BX_IAC() bx_devices.pic->IAC()
+//#define BX_IAC() bx_dbg_IAC()
+
+//
+// Ways for the the external environment to report back information
+// to the debugger.
+//
+
+#if BX_DEBUGGER
+# define BX_DBG_ASYNC_INTR bx_guard.async.irq
+# define BX_DBG_ASYNC_DMA bx_guard.async.dma
+#if (BX_NUM_SIMULATORS > 1)
+// for multiple simulators, we always need this info, since we're
+// going to replay it.
+# define BX_DBG_DMA_REPORT(addr, len, what, val) \
+ bx_dbg_dma_report(addr, len, what, val)
+# define BX_DBG_IAC_REPORT(vector, irq) \
+ bx_dbg_iac_report(vector, irq)
+# define BX_DBG_A20_REPORT(val) \
+ bx_dbg_a20_report(val)
+# define BX_DBG_IO_REPORT(addr, size, op, val) \
+ bx_dbg_io_report(addr, size, op, val)
+# define BX_DBG_UCMEM_REPORT(addr, size, op, val)
+#else
+// for a single simulator debug environment, we can optimize a little
+// by conditionally calling, as per requested.
+
+# define BX_DBG_DMA_REPORT(addr, len, what, val) \
+ if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val)
+# define BX_DBG_IAC_REPORT(vector, irq) \
+ if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq)
+# define BX_DBG_A20_REPORT(val) \
+ if (bx_guard.report.a20) bx_dbg_a20_report(val)
+# define BX_DBG_IO_REPORT(addr, size, op, val) \
+ if (bx_guard.report.io) bx_dbg_io_report(addr, size, op, val)
+# define BX_DBG_UCMEM_REPORT(addr, size, op, val) \
+ if (bx_guard.report.ucmem) bx_dbg_ucmem_report(addr, size, op, val)
+#endif // #if (BX_NUM_SIMULATORS > 1)
+
+#else // #if BX_DEBUGGER
+// debugger not compiled in, use empty stubs
+# define BX_DBG_ASYNC_INTR 1
+# define BX_DBG_ASYNC_DMA 1
+# define BX_DBG_DMA_REPORT(addr, len, what, val)
+# define BX_DBG_IAC_REPORT(vector, irq)
+# define BX_DBG_A20_REPORT(val)
+# define BX_DBG_IO_REPORT(addr, size, op, val)
+# define BX_DBG_UCMEM_REPORT(addr, size, op, val)
+#endif // #if BX_DEBUGGER
+
+extern Bit8u DTPageDirty[];
+#if BX_DYNAMIC_TRANSLATION
+# define BX_DYN_DIRTY_PAGE(page) DTPageDirty[page] = 1;
+#else
+# define BX_DYN_DIRTY_PAGE(page)
+#endif
+
+#define MAGIC_LOGNUM 0x12345678
+
+// Log Level defines
+#define LOGLEV_DEBUG 0
+#define LOGLEV_INFO 1
+#define LOGLEV_ERROR 2
+#define LOGLEV_PANIC 3
+#define MAX_LOGLEV 4
+
+typedef class logfunctions {
+ char *prefix;
+ int type;
+// values of onoff: 0=ignore, 1=report, 2=fatal
+#define ACT_IGNORE 0
+#define ACT_REPORT 1
+#define ACT_FATAL 2
+ int onoff[MAX_LOGLEV];
+ class iofunctions *logio;
+public:
+ logfunctions(void);
+ logfunctions(class iofunctions *);
+ ~logfunctions(void);
+
+ void info(char *fmt, ...);
+ void error(char *fmt, ...);
+ void panic(char *fmt, ...);
+ void ldebug(char *fmt, ...);
+ void fatal (char *prefix, char *fmt, va_list ap);
+ void setprefix(char *);
+ void settype(int);
+ void setio(class iofunctions *);
+ void setonoff(int loglev, int value) { onoff[loglev] = value; }
+} logfunc_t;
+
+class iofunctions {
+ int showtick,magic;
+ FILE *logfd;
+ class logfunctions *log;
+ void init(void);
+ void flush(void);
+ char *getlevel(int i) {
+ static char *loglevel[] = {
+ "DEBUG",
+ "INFO",
+ "ERROR",
+ "PANIC",
+ };
+ return loglevel[i];
+ }
+
+ char *getclass(int i) {
+ char *logclass[] = {
+ "IO ",
+ "FD ",
+ "GEN ",
+ "CMOS",
+ "CD ",
+ "DMA ",
+ "ETH ",
+ "G2H ",
+ "HD ",
+ "KBD ",
+ "NE2K",
+ "PAR ",
+ "PCI ",
+ "PIC ",
+ "PIT ",
+ "SB16",
+ "SER ",
+ "VGA ",
+ "ST ",
+ "DEV ",
+ "MEM ",
+ "DIS ",
+ "GUI ",
+ "IOAP",
+ "APIC",
+ "CPU0",
+ "CPU1",
+ "CPU2",
+ "CPU3",
+ "CPU4",
+ "CPU5",
+ "CPU6",
+ "CPU7",
+ "CPU8",
+ "CPU9",
+ "CPUa",
+ "CPUb",
+ "CPUc",
+ "CPUd",
+ "CPUe",
+ "CPUf",
+ };
+ return logclass[i];
+ }
+
+// Log Class defines
+#define IOLOG 0
+#define FDLOG 1
+#define GENLOG 2
+#define CMOSLOG 3
+#define CDLOG 4
+#define DMALOG 5
+#define ETHLOG 6
+#define G2HLOG 7
+#define HDLOG 8
+#define KBDLOG 9
+#define NE2KLOG 10
+#define PARLOG 11
+#define PCILOG 12
+#define PICLOG 13
+#define PITLOG 14
+#define SB16LOG 15
+#define SERLOG 16
+#define VGALOG 17
+#define STLOG 18 // state_file.cc
+#define DEVLOG 19
+#define MEMLOG 20
+#define DISLOG 21
+#define GUILOG 22
+#define IOAPICLOG 23
+#define APICLOG 24
+#define CPU0LOG 25
+#define CPU1LOG 26
+#define CPU2LOG 27
+#define CPU3LOG 28
+#define CPU4LOG 29
+#define CPU5LOG 30
+#define CPU6LOG 31
+#define CPU7LOG 32
+#define CPU8LOG 33
+#define CPU9LOG 34
+#define CPU10LOG 35
+#define CPU11LOG 36
+#define CPU12LOG 37
+#define CPU13LOG 38
+#define CPU14LOG 39
+#define CPU15LOG 40
+
+
+public:
+ iofunctions(void);
+ iofunctions(FILE *);
+ iofunctions(int);
+ iofunctions(char *);
+ ~iofunctions(void);
+
+ void out(int facility, int level, char *pre, char *fmt, va_list ap);
+
+ void init_log(char *fn);
+ void init_log(int fd);
+ void init_log(FILE *fs);
+ int get_n_logfns () { return n_logfn; }
+ logfunc_t *get_logfn (int index) { return logfn_list[index]; }
+ void add_logfn (logfunc_t *fn);
+ void set_log_action (int loglevel, int action);
+protected:
+ int n_logfn;
+#define MAX_LOGFNS 64
+ logfunc_t *logfn_list[MAX_LOGFNS];
+ char *logfn;
+};
+
+typedef class iofunctions iofunc_t;
+
+
+#define SAFE_GET_IOFUNC() \
+ ((io==NULL)? (io=new iofunc_t("/dev/stderr")) : io)
+#define SAFE_GET_GENLOG() \
+ ((genlog==NULL)? (genlog=new logfunc_t(SAFE_GET_IOFUNC())) : genlog)
+/* #define NO_LOGGING */
+#ifndef NO_LOGGING
+
+#define BX_INFO(x) (LOG_THIS info) x
+#define BX_DEBUG(x) (LOG_THIS ldebug) x
+#define BX_ERROR(x) (LOG_THIS error) x
+#define BX_PANIC(x) (LOG_THIS panic) x
+
+#else
+
+#define EMPTY do { } while(0)
+
+#define BX_INFO(x) EMPTY
+#define BX_DEBUG(x) EMPTY
+#define BX_ERROR(x) EMPTY
+#define BX_PANIC(x) (LOG_THIS panic) x
+
+#endif
+
+extern iofunc_t *io;
+extern logfunc_t *genlog;
+
+#if BX_SUPPORT_SID
+#else
+#include "state_file.h"
+#endif
+
+#ifndef UNUSED
+# define UNUSED(x) ((void)x)
+#endif
+
+#define uint8 Bit8u
+#define uint16 Bit16u
+#define uint32 Bit32u
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+#if BX_SUPPORT_SID
+#include "cpu/cpu-sid.h"
+#else
+# include "cpu/cpu.h"
+#endif
+#endif
+
+#if BX_DISASM
+# include "disasm/disasm.h"
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+# include "dynamic/dynamic.h"
+#endif
+
+
+typedef struct {
+ Boolean floppy;
+ Boolean keyboard;
+ Boolean video;
+ Boolean disk;
+ Boolean pit;
+ Boolean pic;
+ Boolean bios;
+ Boolean cmos;
+ Boolean a20;
+ Boolean interrupts;
+ Boolean exceptions;
+ Boolean unsupported;
+ Boolean temp;
+ Boolean reset;
+ Boolean debugger;
+ Boolean mouse;
+ Boolean io;
+ Boolean xms;
+ Boolean v8086;
+ Boolean paging;
+ Boolean creg;
+ Boolean dreg;
+ Boolean dma;
+ Boolean unsupported_io;
+ Boolean serial;
+ Boolean cdrom;
+#ifdef MAGIC_BREAKPOINT
+ Boolean magic_break_enabled;
+#endif /* MAGIC_BREAKPOINT */
+#if BX_SUPPORT_APIC
+ Boolean apic;
+ Boolean ioapic;
+#endif
+#if BX_DEBUG_LINUX
+ Boolean linux_syscall;
+#endif
+ void* record_io;
+ } bx_debug_t;
+
+#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%s\n", #x, __FILE__, __LINE__));} while (0)
+void bx_signal_handler (int signum);
+void bx_atexit(void);
+#if BX_DEBUGGER
+extern bx_debug_t bx_dbg;
+#endif
+
+
+#define BX_FLOPPY_NONE 10 // floppy not present
+#define BX_FLOPPY_1_2 11 // 1.2M 5.25"
+#define BX_FLOPPY_1_44 12 // 1.44M 3.5"
+#define BX_FLOPPY_2_88 13 // 2.88M 3.5"
+#define BX_FLOPPY_720K 14 // 720K 3.5"
+
+
+#define BX_READ 10
+#define BX_WRITE 11
+#define BX_RW 12
+
+
+#if BX_SUPPORT_SID
+#include "memory/memory-sid.h"
+#else
+#include "memory/memory.h"
+#endif
+
+enum PCS_OP { PCS_CLEAR, PCS_SET, PCS_TOGGLE };
+
+#if BX_SUPPORT_SID
+#else
+#include "pc_system.h"
+
+#include "gui/gui.h"
+extern bx_gui_c bx_gui;
+#include "iodev/iodev.h"
+#endif // BX_SUPPORT_SID
+
+
+
+
+
+
+
+/* --- EXTERNS --- */
+
+#if BX_SUPPORT_SID==0
+#if ( BX_PROVIDE_DEVICE_MODELS==1 )
+extern bx_devices_c bx_devices;
+#endif
+#endif // BX_SUPPORT_SID
+
+#define BX_EJECTED 10
+#define BX_INSERTED 11
+
+
+#define BX_RESET_SOFTWARE 10
+#define BX_RESET_HARDWARE 11
+
+
+typedef struct {
+ char path[512];
+ unsigned type;
+ unsigned initial_status;
+ } bx_floppy_options;
+
+typedef struct {
+ Boolean present;
+ char path[512];
+ unsigned int cylinders;
+ unsigned int heads;
+ unsigned int spt;
+ } bx_disk_options;
+
+struct bx_cdrom_options
+{
+ Boolean present;
+ char dev[512];
+ Boolean inserted;
+};
+
+typedef struct {
+ char *path;
+ unsigned long address;
+ } bx_rom_options;
+
+typedef struct {
+ char *path;
+ } bx_vgarom_options;
+
+typedef struct {
+ size_t megs;
+ } bx_mem_options;
+
+typedef struct {
+ char *path;
+ Boolean cmosImage;
+ unsigned int time0;
+ } bx_cmos_options;
+
+typedef struct {
+ int valid;
+ unsigned ioaddr;
+ unsigned irq;
+ unsigned char macaddr[6];
+ char *ethmod;
+ char *ethdev;
+ } bx_ne2k_options;
+
+typedef struct {
+// These options are used for a special hack to load a
+// 32bit OS directly into memory, so it can be run without
+// any of the 16bit real mode or BIOS assistance. This
+// is for the development of freemware, so we don't have
+// to implement real mode up front.
+#define Load32bitOSLinux 1
+#define Load32bitOSNullKernel 2 // being developed for freemware
+ unsigned whichOS;
+ char *path;
+ char *iolog;
+ char *initrd;
+ } bx_load32bitOSImage_t;
+
+
+typedef struct {
+ char *midifile, *wavefile, *logfile;
+ unsigned int midimode, wavemode, loglevel;
+ Bit32u dmatimer;
+ } bx_sb16_options;
+
+typedef struct {
+ bx_floppy_options floppya;
+ bx_floppy_options floppyb;
+ bx_disk_options diskc;
+ bx_disk_options diskd;
+ bx_cdrom_options cdromd;
+ bx_rom_options rom;
+ bx_vgarom_options vgarom;
+ bx_mem_options memory;
+ bx_sb16_options sb16;
+ char bootdrive[2];
+ unsigned long vga_update_interval;
+ unsigned long keyboard_serial_delay;
+ unsigned long floppy_command_delay;
+ unsigned long ips;
+ Boolean mouse_enabled;
+ Boolean private_colormap;
+ Boolean i440FXSupport;
+ bx_cmos_options cmos;
+ bx_ne2k_options ne2k;
+ Boolean newHardDriveSupport;
+ bx_load32bitOSImage_t load32bitOSImage;
+ // one array item for each log level, indexed by LOGLEV_*.
+ // values: 0=ignore event, 1=report event in log, 2=fatal
+ unsigned char log_actions[MAX_LOGLEV];
+ } bx_options_t;
+
+extern bx_options_t bx_options;
+
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+#else
+// # include "external_interface.h"
+#endif
+
+#define BX_USE_PS2_MOUSE 1
+
+int bx_bochs_init(int argc, char *argv[]);
+
+#include "instrument.h"
+
+#endif /* BX_BOCHS_H */
--- /dev/null
+// This file is generated by "make bxversion.h"
+#define VER_STRING "1.2.1"
+#define REL_STRING "June 12, 2001"
--- /dev/null
+// components.cxx - definitions for this component library. -*- C++ -*-
+
+// Copyright (C) 1999, 2000 Red Hat.
+// This file is part of SID and is licensed under the GPL.
+// See the file COPYING.SID for conditions for redistribution.
+
+#include "tconfig.h"
+#include "config.h"
+
+#include <sidcomp.h>
+#include <sidso.h>
+
+#include <vector>
+#include <string>
+
+#include "x86.h"
+
+using std::vector;
+using std::string;
+
+using sid::component;
+using sid::component_library;
+using sid::COMPONENT_LIBRARY_MAGIC;
+
+
+
+// ----------------------------------------------------------------------------
+
+
+static
+vector<string>
+compX86ListTypes()
+{
+ vector<string> types;
+
+
+#if SIDTARGET_X86
+ types.push_back("hw-cpu-x86");
+#endif
+
+ return types;
+}
+
+
+static
+component*
+compX86Create(const string& typeName)
+{
+#if SIDTARGET_X86
+ try {
+
+ if(typeName == "hw-cpu-x86")
+ {
+ return new x86_cpu();
+ }
+ }
+ catch (...) { }
+#endif
+ return 0;
+}
+
+
+static
+void
+compX86Delete(component* c)
+{
+#if SIDTARGET_X86
+ delete dynamic_cast<sidutil::basic_cpu*>(c);
+#endif
+}
+
+
+
+// static object
+extern const component_library x86_component_library;
+
+const component_library x86_component_library DLLEXPORT =
+{
+ COMPONENT_LIBRARY_MAGIC,
+ & compX86ListTypes,
+ & compX86Create,
+ & compX86Delete
+};
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+ if test x"$HOST_CC" != x; then
+ CC_FOR_BUILD="$HOST_CC"
+ else
+ if test x"$CC" != x; then
+ CC_FOR_BUILD="$CC"
+ else
+ CC_FOR_BUILD=cc
+ fi
+ fi
+fi
+
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # Netbsd (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ # Determine the machine/vendor (is the vendor relevant).
+ case "${UNAME_MACHINE}" in
+ amiga) machine=m68k-cbm ;;
+ arm32) machine=arm-unknown ;;
+ atari*) machine=m68k-atari ;;
+ sun3*) machine=m68k-sun ;;
+ mac68k) machine=m68k-apple ;;
+ macppc) machine=powerpc-apple ;;
+ hp3[0-9][05]) machine=m68k-hp ;;
+ ibmrt|romp-ibm) machine=romp-ibm ;;
+ *) machine=${UNAME_MACHINE}-unknown ;;
+ esac
+ # The Operating System including object format.
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_help_string=`cd /; ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ *ia64)
+ echo "${UNAME_MACHINE}-unknown-linux"
+ exit 0
+ ;;
+ i?86linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0
+ ;;
+ elf_i?86)
+ echo "${UNAME_MACHINE}-pc-linux"
+ exit 0
+ ;;
+ i?86coff)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0
+ ;;
+ sparclinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ armlinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32arm*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
+ exit 0
+ ;;
+ armelf_linux*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnu"
+ exit 0
+ ;;
+ m68klinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32ppc | elf32ppclinux)
+ # Determine Lib Version
+ cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.c $dummy
+ echo powerpc-unknown-linux-gnu${LIBC}
+ exit 0
+ ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ cat <<EOF >$dummy.s
+ .data
+ \$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+ main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # amask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ elif test "${UNAME_MACHINE}" = "s390"; then
+ echo s390-ibm-linux && exit 0
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i?86:*:5:7*)
+ # Fixed at (any) Pentium or better
+ UNAME_MACHINE=i586
+ if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+ echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i?86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ if test "${UNAME_MACHINE}" = "x86pc"; then
+ UNAME_MACHINE=pc
+ fi
+ echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-W:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+//
+// config.h.in is distributed in the source TAR file. When you run
+// the configure script, it generates config.h with some changes
+// according to your build environment. For example, in config.h.in,
+// SIZEOF_UNSIGNED_CHAR is set to 0. When configure produces config.h
+// it will change "0" to the detected value for your system.
+//
+// config.h contains ONLY preprocessor #defines and a few typedefs.
+// It must be included by both C and C++ files, so it must not
+// contain anything language dependent such as a class declaration.
+//
+
+#ifdef _BX_CONFIG_H_
+#else
+#define _BX_CONFIG_H_ 1
+
+///////////////////////////////////////////////////////////////////
+// USER CONFIGURABLE OPTIONS : EDIT ONLY OPTIONS IN THIS SECTION //
+///////////////////////////////////////////////////////////////////
+
+// I have tested the following combinations:
+// * processors=1, bootstrap=0, ioapic_id=1 (uniprocessor system)
+// * processors=2, bootstrap=0, ioapic_id=2
+// * processors=4, bootstrap=2, ioapic_id=4
+#define BX_SMP_PROCESSORS 1
+#define BX_BOOTSTRAP_PROCESSOR 0
+// choose IOAPIC id to be equal to the number of processors. This leaves
+// one space for each processor to have an ID, starting with 0.
+#define BX_IOAPIC_DEFAULT_ID (BX_SMP_PROCESSORS)
+
+#define BX_ADDRESS_SPACES 1
+// controls how many instances of BX_MEM_C are created. For
+// SMP, use several processors with one shared memory space.
+// For cosimulation, you could use two processors and two address
+// spaces.
+
+#define BX_SUPPORT_APIC 0
+// include in APIC models, required for a multiprocessor system.
+
+#if (BX_SMP_PROCESSORS>1 && !BX_SUPPORT_APIC)
+#error For multiprocessor simulation, BX_SUPPORT_APIC is required.
+#endif
+
+#define BX_DEBUG_LINUX 0
+// if simulating Linux, this provides a few more debugging options
+// such as tracing all system calls.
+
+#define HAVE_LIBREADLINE 0
+#define HAVE_READLINE_HISTORY_H 0
+// adds support for the GNU readline library in the debugger command
+// prompt.
+
+// I rebuilt the code which provides timers to IO devices.
+// Setting this to 1 will introduce a little code which
+// will panic out if cases which shouldn't happen occur.
+// Set this to 0 for optimal performance.
+#define BX_TIMER_DEBUG 1
+
+// Settable A20 line. For efficiency, you can disable
+// having a settable A20 line, eliminating conditional
+// code for every physical memory access. You'll have
+// to tell your software not to mess with the A20 line,
+// and accept it as always being on if you change this.
+// 1 = use settable A20 line. (normal)
+// 0 = A20 is like the rest of the address lines
+
+#define BX_SUPPORT_A20 0
+
+// Processor Instructions Per Second
+// To find out what value to use for the 'ips' directive
+// in your '.bochsrc' file, set BX_SHOW_IPS to 1, and
+// run the software in bochs you plan to use most. Bochs
+// will print out periodic IPS ratings. This will change
+// based on the processor mode at the time, and various
+// other factors. You'll get a reasonable estimate though.
+// When you're done, reset BX_SHOW_IPS to 0, do a
+// 'make all-clean', then 'make' again.
+
+#define BX_SHOW_IPS 0
+
+
+#if (BX_SHOW_IPS) && defined(__MINGW32__)
+#define SIGALRM 14
+#endif
+
+// Paging Options:
+// ---------------
+// Support Paging mechanism.
+// 0 = don't support paging at all (DOS & Minix don't require it)
+// 1 = support paging. (Most other OS's require paging)
+// Use Translation Lookaside Buffer (TLB) for caching
+// paging translations. This will make paging mode
+// more efficient. If you're OS doesn't use paging,
+// then you won't need either.
+// 1 = Use a TLB for effiency
+// 0 = don't use a TLB, walk the page tables for every access
+// BX_TLB_SIZE: Number of entries in TLB
+// BX_TLB_INDEX_OF(lpf): This macro is passed the linear page frame
+// (top 20 bits of the linear address. It must map these bits to
+// one of the TLB cache slots, given the size of BX_TLB_SIZE.
+// There will be a many-to-one mapping to each TLB cache slot.
+// When there are collisions, the old entry is overwritten with
+// one for the newest access.
+
+#define BX_SUPPORT_PAGING 0
+#define BX_USE_TLB 0
+
+#define BX_TLB_SIZE 1024
+#define BX_TLB_INDEX_OF(lpf) (((lpf) & 0x003ff000) >> 12)
+
+
+// Compile in support for DMA & FLOPPY IO. You'll need this
+// if you plan to use the floppy drive emulation. But if
+// you're environment doesn't require it, you can change
+// it to 0.
+
+#define BX_DMA_FLOPPY_IO 0
+
+
+// Default number of Megs of memory to emulate. The
+// 'megs:' directive in the '.bochsrc' file overrides this,
+// allowing per-run settings.
+
+#define BX_DEFAULT_MEM_MEGS 4
+
+
+//
+// x86 hardware tasking. There is some tasking support now.
+// I'm trying to get Linux to boot. The default for this
+// is now 1, but if you don't need x86 tasking (DOS, Win'95),
+// then set this to 0.
+//
+
+#define BX_SUPPORT_TASKING 0
+
+
+// CPU level emulation. Default level is set in
+// the configure script. BX_CPU_LEVEL defines the CPU level
+// to emulate. BX_CPU_LEVEL_HACKED is a hack to define the
+// level of some integer instructions, so they can be tested
+// before the rest of the emulation is up to that level.
+
+#define BX_CPU_LEVEL 0
+#define BX_CPU_LEVEL_HACKED 0
+
+
+// Virtual 8086 mode emulation.
+// 1 = compile in support for v8086 mode.
+// 0 = don't compile in support for v8086 mode.
+
+#define BX_SUPPORT_V8086_MODE 1
+
+// Support shadowing of ROM from C0000 to FFFFF.
+// This allows that region to be written to.
+#define BX_SHADOW_RAM 0
+
+// Number of CMOS registers
+#define BX_NUM_CMOS_REGS 64
+//#define BX_NUM_CMOS_REGS 128
+
+// Use Static Member Funtions to eliminate 'this' pointer passing
+// If you want the efficiency of 'C', you can make all the
+// members of the C++ CPU class to be static.
+// This defaults to 1 since it should improve performance, but when
+// SMP mode is enabled, it will be turned off by configure.
+
+#define BX_USE_CPU_SMF 0
+
+// Use static member functions in IO DEVice emulation modules.
+// For efficiency, use C like functions for IO handling,
+// and declare a device instance at compile time,
+// instead of using 'new' and storing the pointer. This
+// eliminates some overhead, especially for high-use IO
+// devices like the disk drive.
+// 1 = Use static member efficiency (normal)
+// 0 = Use nonstatic member functions (use only if you need
+// multiple instances of a device class
+
+#define BX_USE_HD_SMF 1 // Hard drive
+#define BX_USE_CMOS_SMF 1 // CMOS
+#define BX_USE_DMA_SMF 1 // DMA
+#define BX_USE_FD_SMF 1 // Floppy
+#define BX_USE_KEY_SMF 1 // Keyboard
+#define BX_USE_PAR_SMF 1 // Parallel
+#define BX_USE_PIC_SMF 1 // PIC
+#define BX_USE_PIT_SMF 1 // PIT
+#define BX_USE_SER_SMF 1 // Serial
+#define BX_USE_UM_SMF 1 // Unmapped
+#define BX_USE_VGA_SMF 1 // VGA
+#define BX_USE_SB16_SMF 1 // Sound (SB 16)
+#define BX_USE_DEV_SMF 1 // System Devices (port92)
+#define BX_USE_PCI_SMF 1 // PCI
+#define BX_USE_NE2K_SMF 1 // NE2K
+
+#define BX_SUPPORT_SB16 0
+
+#if BX_SUPPORT_SB16
+// Use virtual methods for the sound output functions
+#define BX_USE_SOUND_VIRTUAL 1
+// Determines which sound output class is to be used.
+// Currently the following are available:
+// bx_sound_linux_c Output for Linux, to /dev/dsp and /dev/midi00
+// bx_sound_windows_c Output for Windows midi and wave mappers
+// bx_sound_output_c Dummy functions, no output
+#define BX_SOUND_OUTPUT_C bx_sound_output_c
+#endif
+
+#define BX_USE_SPECIFIED_TIME0 0
+
+// This enables writing to port 0xe9 and the output
+// is sent to the console. Reading from port 0xe9
+// will return 0xe9 to let you know this is available.
+// Leave this 0 unless you have a reason to use it.
+#define BX_PORT_E9_HACK 0
+
+// This option enables "split hard drive" support, which means
+// that a series of partial hard disk images can be treated
+// as a single large image. If you set up the partition sizes and
+// file sizes correctly, this allows you to store each partition
+// in a separate file, which is very convenient if you want to operate
+// on a single partition (e.g. mount with loopback, create filesystem,
+// fsck, etc.).
+// [[Provide example of partitioning]]
+#define BX_SPLIT_HD_SUPPORT 0
+
+
+// =================================================================
+// BEGIN: OPTIONAL DEBUGGER SECTION
+//
+// These options are only used if you compile in support for the
+// native command line debugging environment. Typically, the debugger
+// is not used, and this section can be ignored.
+// =================================================================
+
+#define BX_MAX_DIRTY_PAGE_TABLE_MEGS 64
+
+// Compile in support for virtual/linear/physical breakpoints.
+// Set to 1, only those you need. Recommend using only linear
+// breakpoints, unless you need others. Less supported means
+// slightly faster execution time.
+#define BX_DBG_SUPPORT_VIR_BPOINT 1
+#define BX_DBG_SUPPORT_LIN_BPOINT 1
+#define BX_DBG_SUPPORT_PHY_BPOINT 1
+
+// You need only define one initial breakpoint into each
+// cpu simulator (emulator) here. Each simulator sets callbacks
+// and variables which the debugger uses from then on.
+#define BX_SIM1_INIT bx_dbg_init_cpu_mem_env0
+#ifndef BX_SIM2_INIT
+#define BX_SIM2_INIT bx_dbg_init_cpu_mem_env1
+#endif
+//#define BX_SIM2_INIT sim2_init
+
+// max number of virtual/linear/physical breakpoints handled
+#define BX_DBG_MAX_VIR_BPOINTS 10
+#define BX_DBG_MAX_LIN_BPOINTS 10
+#define BX_DBG_MAX_PHY_BPOINTS 10
+
+// max file pathname size for debugger commands
+#define BX_MAX_PATH 256
+// max nesting level for debug scripts including other scripts
+#define BX_INFILE_DEPTH 10
+// use this command to include (nest) debug scripts
+#define BX_INCLUDE_CMD "source"
+
+// Use either 32 or 64 bit instruction counter for
+// debugger purposes. Uncomment one of these.
+//#define BX_DBG_ICOUNT_SIZE 32
+#define BX_DBG_ICOUNT_SIZE 64
+
+// Make a call to command line debugger extensions. If set to 1,
+// a call is made. An external routine has a chance to process
+// the command. If it does, than the debugger ignores the command.
+#define BX_DBG_EXTENSIONS 0
+
+// =================================================================
+// END: OPTIONAL DEBUGGER SECTION
+// =================================================================
+
+
+//////////////////////////////////////////////////////////////////////
+// END OF USER CONFIGURABLE OPTIONS : DON'T EDIT ANYTHING BELOW !!! //
+// THIS IS GENERATED BY THE ./configure SCRIPT //
+//////////////////////////////////////////////////////////////////////
+
+
+#define BX_WITH_X11 0
+#define BX_WITH_BEOS 0
+#define BX_WITH_WIN32 0
+#define BX_WITH_MACOS 0
+#define BX_WITH_NOGUI 0
+#define BX_WITH_TERM 0
+#define BX_WITH_RFB 0
+
+
+#define WORDS_BIGENDIAN 0
+
+#define SIZEOF_UNSIGNED_CHAR 0
+#define SIZEOF_UNSIGNED_SHORT 0
+#define SIZEOF_UNSIGNED_INT 0
+#define SIZEOF_UNSIGNED_LONG 0
+#define SIZEOF_UNSIGNED_LONG_LONG 0
+#define SIZEOF_INT_P 0
+
+#define BX_64BIT_CONSTANTS_USE_LL 1
+#if BX_64BIT_CONSTANTS_USE_LL
+// doesn't work on Microsoft Visual C++, maybe others
+#define BX_CONST64(x) (x##LL)
+#else
+#define BX_CONST64(x) (x)
+#endif
+
+#if BX_WITH_WIN32
+ typedef unsigned char Bit8u;
+ typedef signed char Bit8s;
+ typedef unsigned short Bit16u;
+ typedef signed short Bit16s;
+ typedef unsigned int Bit32u;
+ typedef signed int Bit32s;
+#ifdef __MINGW32__
+ typedef unsigned long long Bit64u;
+ typedef signed long long Bit64s;
+ typedef Bit32s ssize_t;
+#else
+ typedef unsigned __int64 Bit64u;
+ typedef signed __int64 Bit64s;
+#endif
+#elif BX_WITH_MACOS
+ typedef unsigned char Bit8u;
+ typedef signed char Bit8s;
+ typedef unsigned short Bit16u;
+ typedef signed short Bit16s;
+ typedef unsigned int Bit32u;
+ typedef signed int Bit32s;
+ typedef unsigned long long Bit64u;
+ typedef signed long long Bit64s;
+#else // #if BX_WITH_WIN32
+
+// Unix like platforms
+
+#if SIZEOF_UNSIGNED_CHAR != 1
+# error "sizeof (unsigned char) != 1"
+#else
+ typedef unsigned char Bit8u;
+ typedef signed char Bit8s;
+#endif
+
+#if SIZEOF_UNSIGNED_SHORT != 2
+# error "sizeof (unsigned short) != 2"
+#else
+ typedef unsigned short Bit16u;
+ typedef signed short Bit16s;
+#endif
+
+#if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int Bit32u;
+ typedef signed int Bit32s;
+#elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long Bit32u;
+ typedef signed long Bit32s;
+#else
+# error "can't find sizeof(type) of 4 bytes!"
+#endif
+
+#if SIZEOF_UNSIGNED_LONG == 8
+ typedef unsigned long Bit64u;
+ typedef signed long Bit64s;
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+ typedef unsigned long long Bit64u;
+ typedef signed long long Bit64s;
+#else
+# error "can't find data type of 8 bytes"
+#endif
+
+#endif // BX_WITH_WIN32
+
+// create an unsigned integer type that is the same size as a pointer.
+// You can typecast a pointer to a bx_pr_equiv_t without losing any
+// bits (and without getting the compiler excited). This is used in
+// the FPU emulation code, where pointers and integers are often
+// used interchangeably.
+#if SIZEOF_INT_P == 4
+ typedef Bit32u bx_ptr_equiv_t;
+#elif SIZEOF_INT_P == 8
+ typedef Bit64u bx_ptr_equiv_t;
+#else
+# error "could not define bx_ptr_equiv_t to size of int*"
+#endif
+
+#if BX_WITH_MACOS == 0
+typedef unsigned int Boolean;
+#endif
+
+#if BX_WITH_MACOS
+# define bx_ptr_t char *
+#else
+# define bx_ptr_t void *
+#endif
+
+#if BX_WITH_WIN32
+# define BX_LITTLE_ENDIAN
+#elif BX_WITH_MACOS
+# define BX_BIG_ENDIAN
+#else
+#if WORDS_BIGENDIAN
+# define BX_BIG_ENDIAN
+#else
+# define BX_LITTLE_ENDIAN
+#endif
+#endif // BX_WITH_WIN32
+
+// for now only term.cc requires a GUI sighandler.
+#define BX_GUI_SIGHANDLER (BX_WITH_TERM)
+
+#define HAVE_SIGACTION 1
+
+// configure will change the definition of "inline" to the value
+// that the C compiler allows. It tests the following keywords to
+// see if any is permitted: inline, __inline__, __inline. If none
+// is permitted, it defines inline to be empty.
+#define inline inline
+
+// inline functions in headers that are compiled with C compiler
+// (e.g. fpu code) are declared with BX_C_INLINE macro. Note that
+// the word "inline" itself may now be redefined by the above #define.
+// Many compilers are known to work with "static inline". If the
+// compiler can put the function inline, it does so and never creates
+// a symbol for the function. If optimization is off, or inline is
+// defined to be empty, the static keyword causes the function to create
+// a symbol that's visible only to that .c file. Each .c file that
+// includes the header will produde another local version of the
+// BX_C_INLINE function (not ideal). However without "static" you can
+// duplicate symbol problems which are even worse.
+#define BX_C_INLINE static inline
+
+// Use BX_CPP_INLINE for all C++ inline functions. Note that the
+// word "inline" itself may now be redefined by the above #define.
+#define BX_CPP_INLINE inline
+
+#define BX_DEBUGGER 0
+#define BX_DISASM 0
+
+#define BX_PROVIDE_CPU_MEMORY 1
+#define BX_PROVIDE_DEVICE_MODELS 0
+#define BX_PROVIDE_BIOS_HOOKS 0
+
+#define BX_EMULATE_HGA_DUMPS 0
+
+#define BX_SUPPORT_VGA 0
+
+#define BX_PROVIDE_MAIN 0
+
+#define BX_INSTRUMENTATION 0
+
+#define BX_USE_LOADER 0
+
+// for debugger, CPU simulator handle ID
+// 0 is the default, for using only one CPU simulator
+// 1 is for the 2nd CPU simulator
+#define BX_SIM_ID 0
+#define BX_NUM_SIMULATORS 1
+
+// limited i440FX PCI support
+#define BX_PCI_SUPPORT 0
+
+// dynamic translation (future: not supported yet)
+#define BX_DYNAMIC_TRANSLATION 0
+#define BX_DYNAMIC_CPU_I386 0
+#define BX_DYNAMIC_CPU_SPARC 0
+
+#define BX_SUPPORT_FPU 0
+
+#define BX_HAVE_SELECT 0
+#define BX_HAVE_SNPRINTF 0
+#define BX_HAVE_STRTOULL 0
+#define BX_HAVE_STRTOUQ 0
+#define BX_HAVE_STRDUP 0
+
+// set if your compiler does not permit an empty struct
+#define BX_NO_EMPTY_STRUCTS 0
+
+// set if your compiler does not understand __attribute__ after a struct
+#define BX_NO_ATTRIBUTES 0
+#if BX_NO_ATTRIBUTES
+#define GCC_ATTRIBUTE(x) /* attribute not supported */
+#else
+#define GCC_ATTRIBUTE __attribute__
+#endif
+
+// set if your compiler does not allow label at the end of a {} block
+#define BX_NO_BLANK_LABELS 0
+
+// set if you don't have <hash_map.h>, used in debug/dbg_main.c
+#define BX_HAVE_HASH_MAP 0
+
+// Support x86 hardware debugger registers and facilites.
+// These are the debug facilites offered by the x86 architecture,
+// not the optional built-in debugger.
+#define BX_X86_DEBUGGER 0
+
+#define BX_SUPPORT_CDROM 0
+
+#if BX_SUPPORT_CDROM
+ // This is the C++ class name to use if we are supporting
+ // low-level CDROM.
+# define LOWLEVEL_CDROM cdrom_interface
+#endif
+
+// NE2K network emulation
+#define BX_NE2K_SUPPORT 0
+
+#endif // _BX_CONFIG_H
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+# Free Software Foundation, Inc.
+#
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 \
+ | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | hppa64 \
+ | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+ | alphaev6[78] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+ | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+ | mips64vr5000 | miprs64vr5000el | mcore \
+ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+ | thumb | d10v | fr30 | avr)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ # FIXME: clean up the formatting here.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+ | xmp-* | ymp-* \
+ | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+ | hppa2.0n-* | hppa64-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+ | alphaev6[78]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+ | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+ | mipstx39-* | mipstx39el-* | mcore-* \
+ | f301-* | armv*-* | s390-* | sv1-* | t3e-* \
+ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+ | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
+ | bs2000-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ i386-go32 | go32)
+ basic_machine=i386-unknown
+ os=-go32
+ ;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos)
+ basic_machine=i386-unknown
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc | sparcv9)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i[34567]86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -*MiNT)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -*MiNT)
+ vendor=atari
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
--- /dev/null
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+ --with-x use the X Window System"
+ac_help="$ac_help
+ --enable-processors select number of processors (1,2,4)"
+ac_help="$ac_help
+ --enable-cpu-level select cpu level (3,4,5,6)"
+ac_help="$ac_help
+ --enable-dynamic enable dynamic translation support"
+ac_help="$ac_help
+ --enable-apic enable APIC support"
+ac_help="$ac_help
+ --enable-split-hd allows split hard disk image"
+ac_help="$ac_help
+ --enable-ne2000 enable limited ne2000 support"
+ac_help="$ac_help
+ --enable-pci enable limited i440FX PCI support"
+ac_help="$ac_help
+ --enable-port-e9-hack writes to port e9 go to console"
+ac_help="$ac_help
+ --enable-cpp use .cpp as C++ suffix"
+ac_help="$ac_help
+ --enable-debugger compile in support for Bochs internal debugger"
+ac_help="$ac_help
+ --enable-disasm compile in support for disassembler"
+ac_help="$ac_help
+ --enable-readline use readline library with debugger"
+ac_help="$ac_help
+ --enable-loader support calling external loader from debugger"
+ac_help="$ac_help
+ --enable-instrumentation compile in support for instrumentation"
+ac_help="$ac_help
+ --enable-simid=0 or 1 CPU simulator ID if using more than one"
+ac_help="$ac_help
+ --enable-num-sim=1 or 2 number of CPU simulators"
+ac_help="$ac_help
+ --enable-time0=n start at n instead of using time()"
+ac_help="$ac_help
+ --enable-vga use VGA emulation"
+ac_help="$ac_help
+ --enable-fpu compile in FPU emulation"
+ac_help="$ac_help
+ --enable-x86-debugger x86 debugger support"
+ac_help="$ac_help
+ --enable-cdrom CDROM support"
+ac_help="$ac_help
+ --enable-sb16 Sound Blaster 16 Support"
+ac_help="$ac_help
+ --enable-hga-dumps=Nmicroseconds copy memory to HGA video buffer every N useconds"
+ac_help="$ac_help
+ --with-x11 use X11 GUI"
+ac_help="$ac_help
+ --with-beos use BeOS GUI"
+ac_help="$ac_help
+ --with-win32 use Win32 GUI"
+ac_help="$ac_help
+ --with-win32-vcpp use Win32 GUI/Visual C++ environment"
+ac_help="$ac_help
+ --with-macos use Macintosh/CodeWarrior environment"
+ac_help="$ac_help
+ --with-nogui no native GUI, just use blank stubs"
+ac_help="$ac_help
+ --with-term textmode terminal environment"
+ac_help="$ac_help
+ --with-rfb use RFB protocol, works with VNC viewer"
+ac_help="$ac_help
+ --enable-targets=LIST support given additional targets, or all"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+sitefile=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -site-file | --site-file | --site-fil | --site-fi | --site-f)
+ ac_prev=sitefile ;;
+ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+ sitefile="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=components.cxx
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$sitefile"; then
+ if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+ fi
+else
+ CONFIG_SITE="$sitefile"
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in ../../config $srcdir/../../config; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in ../../config $srcdir/../../config" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:652: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:705: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:762: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=sidcomp
+
+VERSION=0.1
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:808: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:821: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:834: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:847: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:860: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:874: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:897: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 902 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:930: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 935 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:961: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1067: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1088: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1108: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1138: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1189: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1221: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1232 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1263: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1268: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1277: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1296: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1339: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1369: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1372: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1408: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1424: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1461: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1491: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1523: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1555: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1622 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1623: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1644: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1649 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1656: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1764: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1794: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1845: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1877: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1888 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1919: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1924: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1933: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1952: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1988: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CXX="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+ echo "$ac_t""$CXX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:2020: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 2031 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:2036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cxx_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cxx_cross=no
+ else
+ ac_cv_prog_cxx_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+ { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:2062: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:2067: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.C <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2076: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+else
+ ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:2095: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+ ac_cv_prog_cxx_g=yes
+else
+ ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:2127: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2156: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2185: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 2200 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 2217 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2223: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 2234 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# If we find X, set shell vars x_includes and x_libraries to the
+# paths, otherwise set no_x=yes.
+# Uses ac_ vars as temps to allow command line to override cache and checks.
+# --without-x overrides everything else, but does not touch the cache.
+echo $ac_n "checking for X""... $ac_c" 1>&6
+echo "configure:2269: checking for X" >&5
+
+# Check whether --with-x or --without-x was given.
+if test "${with_x+set}" = set; then
+ withval="$with_x"
+ :
+fi
+
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
+if test "x$with_x" = xno; then
+ # The user explicitly disabled X.
+ have_x=disabled
+else
+ if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
+ # Both variables are already set.
+ have_x=yes
+ else
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # One or both of the vars are not set, and there is no cached value.
+ac_x_includes=NO ac_x_libraries=NO
+rm -fr conftestdir
+if mkdir conftestdir; then
+ cd conftestdir
+ # Make sure to not put "make" in the Imakefile rules, since we grep it out.
+ cat > Imakefile <<'EOF'
+acfindx:
+ @echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
+EOF
+ if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
+ # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
+ for ac_extension in a so sl; do
+ if test ! -f $ac_im_usrlibdir/libX11.$ac_extension &&
+ test -f $ac_im_libdir/libX11.$ac_extension; then
+ ac_im_usrlibdir=$ac_im_libdir; break
+ fi
+ done
+ # Screen out bogus values from the imake configuration. They are
+ # bogus both because they are the default anyway, and because
+ # using them would break gcc on systems where it needs fixed includes.
+ case "$ac_im_incroot" in
+ /usr/include) ;;
+ *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;;
+ esac
+ case "$ac_im_usrlibdir" in
+ /usr/lib | /lib) ;;
+ *) test -d "$ac_im_usrlibdir" && ac_x_libraries="$ac_im_usrlibdir" ;;
+ esac
+ fi
+ cd ..
+ rm -fr conftestdir
+fi
+
+if test "$ac_x_includes" = NO; then
+ # Guess where to find include files, by looking for this one X11 .h file.
+ test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+ # First, try using that file with no special directory specified.
+cat > conftest.$ac_ext <<EOF
+#line 2331 "configure"
+#include "confdefs.h"
+#include <$x_direct_test_include>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2336: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ # We can compile using X headers with no special include directory.
+ac_x_includes=
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ # Look for the header file in a standard set of common directories.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+ for ac_dir in \
+ /usr/X11/include \
+ /usr/X11R6/include \
+ /usr/X11R5/include \
+ /usr/X11R4/include \
+ \
+ /usr/include/X11 \
+ /usr/include/X11R6 \
+ /usr/include/X11R5 \
+ /usr/include/X11R4 \
+ \
+ /usr/local/X11/include \
+ /usr/local/X11R6/include \
+ /usr/local/X11R5/include \
+ /usr/local/X11R4/include \
+ \
+ /usr/local/include/X11 \
+ /usr/local/include/X11R6 \
+ /usr/local/include/X11R5 \
+ /usr/local/include/X11R4 \
+ \
+ /usr/X386/include \
+ /usr/x386/include \
+ /usr/XFree86/include/X11 \
+ \
+ /usr/include \
+ /usr/local/include \
+ /usr/unsupported/include \
+ /usr/athena/include \
+ /usr/local/x11r5/include \
+ /usr/lpp/Xamples/include \
+ \
+ /usr/openwin/include \
+ /usr/openwin/share/include \
+ ; \
+ do
+ if test -r "$ac_dir/$x_direct_test_include"; then
+ ac_x_includes=$ac_dir
+ break
+ fi
+ done
+fi
+rm -f conftest*
+fi # $ac_x_includes = NO
+
+if test "$ac_x_libraries" = NO; then
+ # Check for the libraries.
+
+ test -z "$x_direct_test_library" && x_direct_test_library=Xt
+ test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+ # See if we find them without any special options.
+ # Don't add to $LIBS permanently.
+ ac_save_LIBS="$LIBS"
+ LIBS="-l$x_direct_test_library $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2405 "configure"
+#include "confdefs.h"
+
+int main() {
+${x_direct_test_function}()
+; return 0; }
+EOF
+if { (eval echo configure:2412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$ac_save_LIBS"
+# First see if replacing the include by lib works.
+# Check X11 before X11Rn because it is often a symlink to the current release.
+for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \
+ /usr/X11/lib \
+ /usr/X11R6/lib \
+ /usr/X11R5/lib \
+ /usr/X11R4/lib \
+ \
+ /usr/lib/X11 \
+ /usr/lib/X11R6 \
+ /usr/lib/X11R5 \
+ /usr/lib/X11R4 \
+ \
+ /usr/local/X11/lib \
+ /usr/local/X11R6/lib \
+ /usr/local/X11R5/lib \
+ /usr/local/X11R4/lib \
+ \
+ /usr/local/lib/X11 \
+ /usr/local/lib/X11R6 \
+ /usr/local/lib/X11R5 \
+ /usr/local/lib/X11R4 \
+ \
+ /usr/X386/lib \
+ /usr/x386/lib \
+ /usr/XFree86/lib/X11 \
+ \
+ /usr/lib \
+ /usr/local/lib \
+ /usr/unsupported/lib \
+ /usr/athena/lib \
+ /usr/local/x11r5/lib \
+ /usr/lpp/Xamples/lib \
+ /lib/usr/lib/X11 \
+ \
+ /usr/openwin/lib \
+ /usr/openwin/share/lib \
+ ; \
+do
+ for ac_extension in a so sl; do
+ if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
+ ac_x_libraries=$ac_dir
+ break 2
+ fi
+ done
+done
+fi
+rm -f conftest*
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+ # Didn't find X anywhere. Cache the known absence of X.
+ ac_cv_have_x="have_x=no"
+else
+ # Record where we found X for the cache.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+fi
+fi
+ fi
+ eval "$ac_cv_have_x"
+fi # $with_x != no
+
+if test "$have_x" != yes; then
+ echo "$ac_t""$have_x" 1>&6
+ no_x=yes
+else
+ # If each of the values was on the command line, it overrides each guess.
+ test "x$x_includes" = xNONE && x_includes=$ac_x_includes
+ test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
+ # Update the cache value to reflect the command line values.
+ ac_cv_have_x="have_x=yes \
+ ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+ echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
+fi
+
+if test "$no_x" = yes; then
+ # Not all programs may use this symbol, but it does not hurt to define it.
+ cat >> confdefs.h <<\EOF
+#define X_DISPLAY_MISSING 1
+EOF
+
+ X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS=
+else
+ if test -n "$x_includes"; then
+ X_CFLAGS="$X_CFLAGS -I$x_includes"
+ fi
+
+ # It would also be nice to do this for all -L options, not just this one.
+ if test -n "$x_libraries"; then
+ X_LIBS="$X_LIBS -L$x_libraries"
+ # For Solaris; some versions of Sun CC require a space after -R and
+ # others require no space. Words are not sufficient . . . .
+ case "`(uname -sr) 2>/dev/null`" in
+ "SunOS 5"*)
+ echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
+echo "configure:2518: checking whether -R must be followed by a space" >&5
+ ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 2521 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_R_nospace=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_nospace=no
+fi
+rm -f conftest*
+ if test $ac_R_nospace = yes; then
+ echo "$ac_t""no" 1>&6
+ X_LIBS="$X_LIBS -R$x_libraries"
+ else
+ LIBS="$ac_xsave_LIBS -R $x_libraries"
+ cat > conftest.$ac_ext <<EOF
+#line 2544 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ ac_R_space=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_R_space=no
+fi
+rm -f conftest*
+ if test $ac_R_space = yes; then
+ echo "$ac_t""yes" 1>&6
+ X_LIBS="$X_LIBS -R $x_libraries"
+ else
+ echo "$ac_t""neither works" 1>&6
+ fi
+ fi
+ LIBS="$ac_xsave_LIBS"
+ esac
+ fi
+
+ # Check for system-dependent libraries X programs must link with.
+ # Do this before checking for the system-independent R6 libraries
+ # (-lICE), since we may need -lsocket or whatever for X linking.
+
+ if test "$ISC" = yes; then
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet"
+ else
+ # Martyn.Johnson@cl.cam.ac.uk says this is needed for Ultrix, if the X
+ # libraries were built with DECnet support. And karl@cs.umb.edu says
+ # the Alpha needs dnet_stub (dnet does not exist).
+ echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
+echo "configure:2583: checking for dnet_ntoa in -ldnet" >&5
+ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2591 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_lib_dnet_dnet_ntoa = no; then
+ echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
+echo "configure:2624: checking for dnet_ntoa in -ldnet_stub" >&5
+ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldnet_stub $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2632 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dnet_ntoa();
+
+int main() {
+dnet_ntoa()
+; return 0; }
+EOF
+if { (eval echo configure:2643: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT,
+ # to get the SysV transport functions.
+ # chad@anasazi.com says the Pyramis MIS-ES running DC/OSx (SVR4)
+ # needs -lnsl.
+ # The nsl library prevents programs from opening the X display
+ # on Irix 5.2, according to dickey@clark.net.
+ echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
+echo "configure:2672: checking for gethostbyname" >&5
+if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2677 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char gethostbyname(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
+choke me
+#else
+gethostbyname();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_gethostbyname=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_gethostbyname = no; then
+ echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:2721: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2729 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:2740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # lieder@skyler.mavd.honeywell.com says without -lsocket,
+ # socket/setsockopt and other routines are undefined under SCO ODT
+ # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary
+ # on later versions), says simon@lia.di.epfl.ch: it contains
+ # gethostby* variants that don't use the nameserver (or something).
+ # -lsocket must be given before -lnsl if both are needed.
+ # We assume that if connect needs -lnsl, so does gethostbyname.
+ echo $ac_n "checking for connect""... $ac_c" 1>&6
+echo "configure:2770: checking for connect" >&5
+if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2775 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char connect(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+connect();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_connect=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_connect=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_connect = no; then
+ echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:2819: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2827 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:2838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
+ echo $ac_n "checking for remove""... $ac_c" 1>&6
+echo "configure:2862: checking for remove" >&5
+if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2867 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char remove(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_remove) || defined (__stub___remove)
+choke me
+#else
+remove();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_remove=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_remove=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_remove = no; then
+ echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
+echo "configure:2911: checking for remove in -lposix" >&5
+ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lposix $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2919 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char remove();
+
+int main() {
+remove()
+; return 0; }
+EOF
+if { (eval echo configure:2930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+
+ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
+ echo $ac_n "checking for shmat""... $ac_c" 1>&6
+echo "configure:2954: checking for shmat" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2959 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shmat(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shmat) || defined (__stub___shmat)
+choke me
+#else
+shmat();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shmat=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $ac_cv_func_shmat = no; then
+ echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
+echo "configure:3003: checking for shmat in -lipc" >&5
+ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lipc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3011 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shmat();
+
+int main() {
+shmat()
+; return 0; }
+EOF
+if { (eval echo configure:3022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ fi
+ fi
+
+ # Check for libraries that X11R6 Xt/Xaw programs need.
+ ac_save_LDFLAGS="$LDFLAGS"
+ test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries"
+ # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to
+ # check for ICE first), but we must link in the order -lSM -lICE or
+ # we get undefined symbols. So assume we have SM if we have ICE.
+ # These have to be linked with before -lX11, unlike the other
+ # libraries we check for below, so use a different variable.
+ # --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
+ echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
+echo "configure:3055: checking for IceConnectionNumber in -lICE" >&5
+ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lICE $X_EXTRA_LIBS $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3063 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char IceConnectionNumber();
+
+int main() {
+IceConnectionNumber()
+; return 0; }
+EOF
+if { (eval echo configure:3074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ LDFLAGS="$ac_save_LDFLAGS"
+
+fi
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:3100: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 3107 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 3122 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:3133: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3153 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:3166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:3190: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 3197 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:3204: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+echo $ac_n "checking size of unsigned char""... $ac_c" 1>&6
+echo "configure:3230: checking size of unsigned char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_char'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_unsigned_char=1
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3238 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(unsigned char));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_unsigned_char=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_unsigned_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char
+EOF
+
+
+echo $ac_n "checking size of unsigned short""... $ac_c" 1>&6
+echo "configure:3269: checking size of unsigned short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_short'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_unsigned_short=2
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3277 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(unsigned short));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_unsigned_short=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_unsigned_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+EOF
+
+
+echo $ac_n "checking size of unsigned int""... $ac_c" 1>&6
+echo "configure:3308: checking size of unsigned int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_int'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_unsigned_int=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3316 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(unsigned int));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_unsigned_int=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_unsigned_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+EOF
+
+
+echo $ac_n "checking size of unsigned long""... $ac_c" 1>&6
+echo "configure:3347: checking size of unsigned long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_unsigned_long=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3355 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(unsigned long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3366: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_unsigned_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_unsigned_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+EOF
+
+
+echo $ac_n "checking size of unsigned long long""... $ac_c" 1>&6
+echo "configure:3386: checking size of unsigned long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_unsigned_long_long'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_unsigned_long_long=8
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3394 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(unsigned long long));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_unsigned_long_long=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_unsigned_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_unsigned_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+EOF
+
+
+echo $ac_n "checking size of int *""... $ac_c" 1>&6
+echo "configure:3425: checking size of int *" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int_p'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_sizeof_int_p=4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3433 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof(int *));
+ exit(0);
+}
+EOF
+if { (eval echo configure:3444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_sizeof_int_p=`cat conftestval`
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_sizeof_int_p=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int_p" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT_P $ac_cv_sizeof_int_p
+EOF
+
+
+for ac_func in select
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3466: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3471 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_SELECT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in snprintf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3524: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3529 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3552: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_SNPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strtoull
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3582: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3587 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRTOULL 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strtouq
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3640: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3645 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRTOUQ 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strdup
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3698: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3703 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRDUP 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking if compiler allows empty structs""... $ac_c" 1>&6
+echo "configure:3755: checking if compiler allows empty structs" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3757 "configure"
+#include "confdefs.h"
+
+int main() {
+typedef struct { } junk;
+; return 0; }
+EOF
+if { (eval echo configure:3764: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+
+ cat >> confdefs.h <<\EOF
+#define BX_NO_EMPTY_STRUCTS 1
+EOF
+
+ echo "$ac_t""no" 1>&6
+
+fi
+rm -f conftest*
+
+echo $ac_n "checking if compiler allows __attribute__""... $ac_c" 1>&6
+echo "configure:3782: checking if compiler allows __attribute__" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3784 "configure"
+#include "confdefs.h"
+
+int main() {
+typedef struct { } __attribute__ ((packed)) junk;
+; return 0; }
+EOF
+if { (eval echo configure:3791: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_NO_ATTRIBUTES 1
+EOF
+
+
+fi
+rm -f conftest*
+
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking for hash_map.h""... $ac_c" 1>&6
+echo "configure:3817: checking for hash_map.h" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3819 "configure"
+#include "confdefs.h"
+#include <hash_map.h>
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3826: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_HASH_MAP 1
+EOF
+
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
+fi
+rm -f conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+
+echo $ac_n "checking for number of processors""... $ac_c" 1>&6
+echo "configure:3851: checking for number of processors" >&5
+# Check whether --enable-processors or --disable-processors was given.
+if test "${enable_processors+set}" = set; then
+ enableval="$enable_processors"
+ case "$enableval" in
+ 1)
+ echo "$ac_t""1" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 1
+EOF
+
+ ;;
+ 2)
+ echo "$ac_t""2" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+ ;;
+ 4)
+ echo "$ac_t""4" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 4
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 4
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+ ;;
+ *)
+ echo " "
+ echo "WARNING: processors != 1,2,4 can work, but you need to modify rombios.c manually"
+ echo "$ac_t""$enable_val" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS $enable_val
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID $enable_val
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_USE_CPU_SMF 0
+EOF
+
+ ;;
+ esac
+ bx_procs="$enableval"
+
+else
+
+ echo "$ac_t""1" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SMP_PROCESSORS 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_BOOTSTRAP_PROCESSOR 0
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_IOAPIC_DEFAULT_ID 1
+EOF
+
+ bx_procs=1
+
+
+fi
+
+
+echo $ac_n "checking if compiler allows blank labels""... $ac_c" 1>&6
+echo "configure:3955: checking if compiler allows blank labels" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3957 "configure"
+#include "confdefs.h"
+
+int main() {
+ { label1: }
+; return 0; }
+EOF
+if { (eval echo configure:3964: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_NO_BLANK_LABELS 1
+EOF
+
+
+fi
+rm -f conftest*
+
+echo $ac_n "checking if compiler allows LL for 64-bit constants""... $ac_c" 1>&6
+echo "configure:3982: checking if compiler allows LL for 64-bit constants" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3984 "configure"
+#include "confdefs.h"
+
+int main() {
+ { 42LL; }
+; return 0; }
+EOF
+if { (eval echo configure:3991: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&6
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_64BIT_CONSTANTS_USE_LL 0
+EOF
+
+
+fi
+rm -f conftest*
+
+echo $ac_n "checking for cpu level""... $ac_c" 1>&6
+echo "configure:4009: checking for cpu level" >&5
+# Check whether --enable-cpu-level or --disable-cpu-level was given.
+if test "${enable_cpu_level+set}" = set; then
+ enableval="$enable_cpu_level"
+ case "$enableval" in
+ 3)
+ echo "$ac_t""3" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 3
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 3
+EOF
+
+ ;;
+ 4)
+ echo "$ac_t""4" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 4
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 4
+EOF
+
+ ;;
+ 5)
+ echo "$ac_t""5" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 5
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 5
+EOF
+
+ ;;
+ 6)
+ echo "$ac_t""6" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 6
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 6
+EOF
+
+ ;;
+ *)
+ echo " "
+ echo "ERROR: you must supply a valid CPU level to --enable-cpu-level"
+ exit 1
+ ;;
+ esac
+ bx_cpu_level=$enableval
+ if test "$bx_procs" -gt 1 -a "$enableval" -lt 6; then
+ echo "ERROR: with >1 processor, use --enable-cpu-level=6"
+ exit 1
+ fi
+
+else
+
+ # for multiprocessors, cpu level must be 6
+ if test "$bx_procs" -gt 1; then
+ echo "$ac_t""6" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 6
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 6
+EOF
+
+ bx_cpu_level=6
+ else
+ echo "$ac_t""5" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL 5
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_CPU_LEVEL_HACKED 5
+EOF
+
+ bx_cpu_level=5
+ fi
+
+
+fi
+
+
+
+echo $ac_n "checking for dynamic translation support""... $ac_c" 1>&6
+echo "configure:4103: checking for dynamic translation support" >&5
+# Check whether --enable-dynamic or --disable-dynamic was given.
+if test "${enable_dynamic+set}" = set; then
+ enableval="$enable_dynamic"
+ if test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 0
+EOF
+
+ DYNAMIC_VAR=''
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+ else
+ if test "$enableval" = yes; then
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "You must specify a CPU type to dynamic-translation option"
+ echo \!\!\!Error\!\!\!
+ exit 1
+ fi
+ case "$enableval" in
+ i386)
+ cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_CPU_I386 1
+EOF
+
+ AS_DYNAMIC_OBJS='$(X86_OBJS)'
+ AS_DYNAMIC_INCS='$(X86_H)'
+ ;;
+ sparc)
+ cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_CPU_SPARC 1
+EOF
+
+ AS_DYNAMIC_OBJS='$(SPARC_OBJS).o'
+ AS_DYNAMIC_INCS='$(SPARC_H)'
+ ;;
+ *)
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "Sorry, dynamic translation is not yet available on your platform"
+ echo \!\!\!Error\!\!\!
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+ exit 1 ;;
+ esac
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 1
+EOF
+
+ DYNAMIC_VAR='$(DYNAMIC_LIB)'
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DYNAMIC_TRANSLATION 0
+EOF
+
+ DYNAMIC_VAR=''
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+
+
+fi
+
+
+
+
+
+echo $ac_n "checking for APIC support""... $ac_c" 1>&6
+echo "configure:4176: checking for APIC support" >&5
+# Check whether --enable-apic or --disable-apic was given.
+if test "${enable_apic+set}" = set; then
+ enableval="$enable_apic"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 1
+EOF
+
+ IOAPIC_OBJS='ioapic.o'
+ APIC_OBJS='apic.o'
+ else
+ echo "$ac_t""no" 1>&6
+ if test "$bx_procs" -gt 1; then
+ echo "Number of processors = $bx_procs"
+ echo "ERROR: With processors > 1 you must use --enable-apic"
+ exit 1
+ fi
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 0
+EOF
+
+ IOAPIC_OBJS=''
+ APIC_OBJS=''
+ fi
+
+else
+
+ if test "$bx_procs" -gt 1 -o "$bx_cpu_level" -gt 5; then
+ # enable APIC by default, if processors>1 or if cpulevel>5
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 1
+EOF
+
+ IOAPIC_OBJS='ioapic.o'
+ APIC_OBJS='apic.o'
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_APIC 0
+EOF
+
+ IOAPIC_OBJS=''
+ APIC_OBJS=''
+ fi
+
+
+fi
+
+
+
+
+echo $ac_n "checking for split hard disk image support""... $ac_c" 1>&6
+echo "configure:4231: checking for split hard disk image support" >&5
+# Check whether --enable-split-hd or --disable-split-hd was given.
+if test "${enable_split_hd+set}" = set; then
+ enableval="$enable_split_hd"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 0
+EOF
+
+ fi
+else
+
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SPLIT_HD_SUPPORT 1
+EOF
+
+
+
+fi
+
+
+
+echo $ac_n "checking for NE2000 support""... $ac_c" 1>&6
+echo "configure:4262: checking for NE2000 support" >&5
+# Check whether --enable-ne2000 or --disable-ne2000 was given.
+if test "${enable_ne2000+set}" = set; then
+ enableval="$enable_ne2000"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 1
+EOF
+
+ NE2K_OBJS='ne2k.o eth.o eth_null.o'
+ ac_safe=`echo "net/bpf.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for net/bpf.h""... $ac_c" 1>&6
+echo "configure:4275: checking for net/bpf.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4280 "configure"
+#include "confdefs.h"
+#include <net/bpf.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ NE2K_OBJS="$NE2K_OBJS eth_fbsd.o"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 0
+EOF
+
+ NE2K_OBJS=''
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_NE2K_SUPPORT 0
+EOF
+
+ NE2K_OBJS=''
+
+
+fi
+
+
+
+
+echo $ac_n "checking for i440FX PCI support""... $ac_c" 1>&6
+echo "configure:4330: checking for i440FX PCI support" >&5
+# Check whether --enable-pci or --disable-pci was given.
+if test "${enable_pci+set}" = set; then
+ enableval="$enable_pci"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 1
+EOF
+
+ PCI_OBJ='pci.o'
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 0
+EOF
+
+ PCI_OBJ=''
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PCI_SUPPORT 0
+EOF
+
+ PCI_OBJ=''
+
+
+fi
+
+
+
+
+echo $ac_n "checking for port e9 hack""... $ac_c" 1>&6
+echo "configure:4365: checking for port e9 hack" >&5
+# Check whether --enable-port-e9-hack or --disable-port-e9-hack was given.
+if test "${enable_port_e9_hack+set}" = set; then
+ enableval="$enable_port_e9_hack"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 1
+EOF
+
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 0
+EOF
+
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_PORT_E9_HACK 0
+EOF
+
+
+
+fi
+
+
+
+echo $ac_n "checking for use of .cpp as suffix""... $ac_c" 1>&6
+echo "configure:4396: checking for use of .cpp as suffix" >&5
+# Check whether --enable-cpp or --disable-cpp was given.
+if test "${enable_cpp+set}" = set; then
+ enableval="$enable_cpp"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ SUFFIX_LINE='.SUFFIXES: .cpp'
+ CPP_SUFFIX='cpp'
+ else
+ echo "$ac_t""no" 1>&6
+ SUFFIX_LINE='.SUFFIXES: .cc'
+ CPP_SUFFIX='cc'
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ SUFFIX_LINE='.SUFFIXES: .cc'
+ CPP_SUFFIX='cc'
+
+
+fi
+
+
+
+
+if test "$enable_cpp" = yes; then
+ echo "moving .cc source files to .cpp"
+ sourcefiles=`find . -name "*.cc" -print`
+ if test "$sourcefiles" != ""; then
+ for ccname in $sourcefiles
+ do
+ cppname=`echo $ccname | sed -e "s/\.cc$/.cpp/"`
+ echo "mv $ccname $cppname"
+ mv $ccname $cppname
+ done
+ else
+ echo "no more .cc source files to rename"
+ fi
+fi
+
+
+echo $ac_n "checking for Bochs internal debugger support""... $ac_c" 1>&6
+echo "configure:4438: checking for Bochs internal debugger support" >&5
+# Check whether --enable-debugger or --disable-debugger was given.
+if test "${enable_debugger+set}" = set; then
+ enableval="$enable_debugger"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 1
+EOF
+
+ DEBUGGER_VAR='$(DEBUGGER_LIB)'
+ bx_debugger=1
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 0
+EOF
+
+ DEBUGGER_VAR=''
+ bx_debugger=0
+ fi
+
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DEBUGGER 0
+EOF
+
+ DEBUGGER_VAR=''
+ bx_debugger=0
+
+
+fi
+
+
+
+echo $ac_n "checking for disassembler support""... $ac_c" 1>&6
+echo "configure:4476: checking for disassembler support" >&5
+# Check whether --enable-disasm or --disable-disasm was given.
+if test "${enable_disasm+set}" = set; then
+ enableval="$enable_disasm"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DISASM 1
+EOF
+
+ DISASM_VAR='$(DISASM_LIB)'
+ else
+ echo "$ac_t""no" 1>&6
+ if test "$bx_debugger" = 1; then
+ echo "ERROR: debugger is enabled, so --enable-disasm is required"
+ exit 1
+ fi
+ cat >> confdefs.h <<\EOF
+#define BX_DISASM 0
+EOF
+
+ DISASM_VAR=''
+ fi
+else
+
+ if test "$bx_debugger" = 1; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DISASM 1
+EOF
+
+ DISASM_VAR='$(DISASM_LIB)'
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_DISASM 0
+EOF
+
+ DISASM_VAR=''
+ fi
+
+
+fi
+
+
+
+echo $ac_n "checking whether to use readline""... $ac_c" 1>&6
+echo "configure:4523: checking whether to use readline" >&5
+# Check whether --enable-readline or --disable-readline was given.
+if test "${enable_readline+set}" = set; then
+ enableval="$enable_readline"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ want_readline=yes
+ else
+ echo "$ac_t""no" 1>&6
+ want_readline=no
+ fi
+else
+ # default is yes
+ echo "$ac_t""yes" 1>&6
+ want_readline=yes
+
+fi
+
+
+
+if test "$want_readline" = yes; then
+ echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
+echo "configure:4545: checking for readline in -lreadline" >&5
+ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lreadline $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4553 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char readline();
+
+int main() {
+readline()
+; return 0; }
+EOF
+if { (eval echo configure:4564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ if test "$bx_debugger" = 1; then
+ # only add readline library if debugger is on
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBREADLINE 1
+EOF
+
+ READLINE_LIB='-lreadline'
+ fi
+
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for readline/history.h""... $ac_c" 1>&6
+echo "configure:4599: checking for readline/history.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4604 "configure"
+#include "confdefs.h"
+#include <readline/history.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:4609: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_READLINE_HISTORY_H 1
+EOF
+
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for loader support""... $ac_c" 1>&6
+echo "configure:4637: checking for loader support" >&5
+# Check whether --enable-loader or --disable-loader was given.
+if test "${enable_loader+set}" = set; then
+ enableval="$enable_loader"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 1
+EOF
+
+ BX_LOADER_OBJS='bx_loader.o loader.o'
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 0
+EOF
+
+ BX_LOADER_OBJS=''
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_USE_LOADER 0
+EOF
+
+ BX_LOADER_OBJS=''
+
+
+fi
+
+
+
+
+
+INSTRUMENT_DIR='instrument/stubs'
+
+echo $ac_n "checking for instrumentation support""... $ac_c" 1>&6
+echo "configure:4675: checking for instrumentation support" >&5
+# Check whether --enable-instrumentation or --disable-instrumentation was given.
+if test "${enable_instrumentation+set}" = set; then
+ enableval="$enable_instrumentation"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 1
+EOF
+
+ INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+ elif test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 0
+EOF
+
+ INSTRUMENT_VAR=''
+ else
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 1
+EOF
+
+ INSTRUMENT_DIR=$enableval
+ INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_INSTRUMENTATION 0
+EOF
+
+ INSTRUMENT_VAR=''
+
+
+fi
+
+
+
+
+# Check whether --enable-simid or --disable-simid was given.
+if test "${enable_simid+set}" = set; then
+ enableval="$enable_simid"
+ if test "$enableval" = yes; then
+ cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+ elif test "$enableval" = no; then
+ cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+ else
+ cat >> confdefs.h <<EOF
+#define BX_SIM_ID $enableval
+EOF
+
+ fi
+else
+
+ cat >> confdefs.h <<\EOF
+#define BX_SIM_ID 0
+EOF
+
+
+
+fi
+
+
+# Check whether --enable-num-sim or --disable-num-sim was given.
+if test "${enable_num_sim+set}" = set; then
+ enableval="$enable_num_sim"
+ if test "$enableval" = yes; then
+ cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+ elif test "$enableval" = no; then
+ cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+ else
+ cat >> confdefs.h <<EOF
+#define BX_NUM_SIMULATORS $enableval
+EOF
+
+ fi
+else
+
+ cat >> confdefs.h <<\EOF
+#define BX_NUM_SIMULATORS 1
+EOF
+
+
+
+fi
+
+
+# Check whether --enable-time0 or --disable-time0 was given.
+if test "${enable_time0+set}" = set; then
+ enableval="$enable_time0"
+ if test "$enableval" = yes; then
+ cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 917385580
+EOF
+
+ elif test "$enableval" = no; then
+ cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 0
+EOF
+
+ else
+ cat >> confdefs.h <<EOF
+#define BX_USE_SPECIFIED_TIME0 $enableval
+EOF
+
+ fi
+else
+
+ cat >> confdefs.h <<\EOF
+#define BX_USE_SPECIFIED_TIME0 0
+EOF
+
+
+
+fi
+
+
+
+
+echo $ac_n "checking for VGA emulation""... $ac_c" 1>&6
+echo "configure:4810: checking for VGA emulation" >&5
+# Check whether --enable-vga or --disable-vga was given.
+if test "${enable_vga+set}" = set; then
+ enableval="$enable_vga"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 1
+EOF
+
+ VIDEO_OBJS='$(VIDEO_OBJS_VGA)'
+ else
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 0
+EOF
+
+ VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_VGA 0
+EOF
+
+ VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+
+
+fi
+
+
+
+echo $ac_n "checking for FPU emulation""... $ac_c" 1>&6
+echo "configure:4844: checking for FPU emulation" >&5
+FPU_VAR=''
+FPU_GLUE_OBJ=''
+# Check whether --enable-fpu or --disable-fpu was given.
+if test "${enable_fpu+set}" = set; then
+ enableval="$enable_fpu"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 1
+EOF
+
+ FPU_VAR='$(FPU_LIB)'
+ FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+ elif test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 0
+EOF
+
+ else
+ echo " "
+ echo "ERROR: --enable-fpu does not accept a path"
+ exit 1
+ fi
+
+else
+
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_FPU 1
+EOF
+
+ FPU_VAR='$(FPU_LIB)'
+ FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+
+
+fi
+
+
+
+
+
+
+echo $ac_n "checking for x86 debugger support""... $ac_c" 1>&6
+echo "configure:4889: checking for x86 debugger support" >&5
+# Check whether --enable-x86-debugger or --disable-x86-debugger was given.
+if test "${enable_x86_debugger+set}" = set; then
+ enableval="$enable_x86_debugger"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 1
+EOF
+
+ elif test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 0
+EOF
+
+ else
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 1
+EOF
+
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_X86_DEBUGGER 0
+EOF
+
+
+
+fi
+
+
+echo $ac_n "checking for CDROM support""... $ac_c" 1>&6
+echo "configure:4925: checking for CDROM support" >&5
+# Check whether --enable-cdrom or --disable-cdrom was given.
+if test "${enable_cdrom+set}" = set; then
+ enableval="$enable_cdrom"
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&6
+ CDROM_OBJS='cdrom.o'
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 1
+EOF
+
+ elif test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ CDROM_OBJS=''
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 0
+EOF
+
+ else
+ echo "$ac_t""yes" 1>&6
+ CDROM_OBJS='cdrom.o'
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 1
+EOF
+
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ CDROM_OBJS=''
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_CDROM 0
+EOF
+
+
+
+fi
+
+
+
+
+echo $ac_n "checking for Sound Blaster 16 support""... $ac_c" 1>&6
+echo "configure:4967: checking for Sound Blaster 16 support" >&5
+# Check whether --enable-sb16 or --disable-sb16 was given.
+if test "${enable_sb16+set}" = set; then
+ enableval="$enable_sb16"
+ if test "$enableval" = no; then
+ echo "$ac_t""no" 1>&6
+ SB16_OBJS=''
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 0
+EOF
+
+ else
+ case "$enableval" in
+ dummy)
+ SB16_OBJS='$(SB16_DUMMY_OBJS)'
+ cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_output_c
+EOF
+
+ echo "$ac_t""dummy" 1>&6
+ ;;
+ linux)
+ SB16_OBJS='$(SB16_LINUX_OBJS)'
+ cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_linux_c
+EOF
+
+ echo "$ac_t""linux" 1>&6
+ ;;
+ win)
+ SB16_OBJS='$(SB16_WIN_OBJS)'
+ cat >> confdefs.h <<\EOF
+#define BX_SOUND_OUTPUT_C bx_sound_windows_c
+EOF
+
+ echo "$ac_t""win" 1>&6
+ ;;
+ *)
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "You must pass one of dummy, linux, win to --enable-sb16"
+ exit 1 ;;
+ esac
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 1
+EOF
+
+ fi
+else
+
+ echo "$ac_t""no" 1>&6
+ SB16_OBJS=''
+ cat >> confdefs.h <<\EOF
+#define BX_SUPPORT_SB16 0
+EOF
+
+
+
+fi
+
+
+
+
+# Check whether --enable-hga-dumps or --disable-hga-dumps was given.
+if test "${enable_hga_dumps+set}" = set; then
+ enableval="$enable_hga_dumps"
+ cat >> confdefs.h <<EOF
+#define BX_EMULATE_HGA_DUMPS $enableval
+EOF
+
+fi
+
+
+PRIMARY_TARGET='bochs'
+
+cat >> confdefs.h <<\EOF
+#define BX_PROVIDE_DEVICE_MODELS 0
+EOF
+
+IODEV_LIB_VAR='iodev/libiodev.a'
+cat >> confdefs.h <<\EOF
+#define BX_PROVIDE_CPU_MEMORY 1
+EOF
+
+NONINLINE_VAR='$(NONINLINE_OBJS)'
+
+
+
+
+
+
+
+# Check whether --with-x11 or --without-x11 was given.
+if test "${with_x11+set}" = set; then
+ withval="$with_x11"
+ :
+fi
+
+
+# Check whether --with-beos or --without-beos was given.
+if test "${with_beos+set}" = set; then
+ withval="$with_beos"
+ :
+fi
+
+
+# Check whether --with-win32 or --without-win32 was given.
+if test "${with_win32+set}" = set; then
+ withval="$with_win32"
+ :
+fi
+
+
+# Check whether --with-win32-vcpp or --without-win32-vcpp was given.
+if test "${with_win32_vcpp+set}" = set; then
+ withval="$with_win32_vcpp"
+ :
+fi
+
+
+# Check whether --with-macos or --without-macos was given.
+if test "${with_macos+set}" = set; then
+ withval="$with_macos"
+ :
+fi
+
+
+# Check whether --with-nogui or --without-nogui was given.
+if test "${with_nogui+set}" = set; then
+ withval="$with_nogui"
+ :
+fi
+
+
+# Check whether --with-term or --without-term was given.
+if test "${with_term+set}" = set; then
+ withval="$with_term"
+ :
+fi
+
+
+# Check whether --with-rfb or --without-rfb was given.
+if test "${with_rfb+set}" = set; then
+ withval="$with_rfb"
+ :
+fi
+
+
+echo $ac_n "checking for gui library to use""... $ac_c" 1>&6
+echo "configure:5116: checking for gui library to use" >&5
+
+with_nogui=yes
+
+if (test "$with_x11" != yes) && \
+ (test "$with_beos" != yes) && \
+ (test "$with_win32" != yes) && \
+ (test "$with_nogui" != yes) && \
+ (test "$with_win32_vcpp" != yes) && \
+ (test "$with_term" != yes) && \
+ (test "$with_rfb" != yes) && \
+ (test "$with_macos" != yes); then
+ with_x11=yes
+fi
+
+DASH="-"
+SLASH="/"
+CXXFP=""
+CFP=""
+OFP="-o "
+MAKELIB="ar rv \$@"
+RMCOMMAND="rm -f "
+LINK="\$(CXX) -o \$@ \$(CXXFLAGS)"
+EXE=""
+COMMAND_SEPARATOR="&& \\"
+CD_UP_ONE="echo done"
+CD_UP_TWO="echo done"
+
+if test "$with_x11" = yes; then
+ echo "$ac_t""X windows" 1>&6
+ if test "$no_x" = yes; then
+ echo ERROR: X windows gui was selected, but X windows libraries were not found.
+ exit 1
+ fi
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_X11 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_X11)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_X)'
+elif test "$with_win32" = yes; then
+ echo "$ac_t""win32" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_WIN32 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_WIN32)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32)'
+elif test "$with_beos" = yes; then
+ echo "$ac_t""beos" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_BEOS 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_BEOS)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_BEOS)'
+elif test "$with_rfb" = yes; then
+ echo "$ac_t""rfb" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_RFB 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_RFB)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_RFB)'
+elif test "$with_win32_vcpp" = yes; then
+ echo "$ac_t""win32-vcpp" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_WIN32 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_WIN32)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32_VCPP)'
+
+ CC="cl"
+ CXX="$CC"
+ #C_OPT="/Zi" # for debugging
+ C_OPT="/O2" # optimize for speed
+ CFLAGS="/nologo /G6 /MT /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS $C_OPT"
+ CXXFLAGS="$CFLAGS"
+ DASH="/"
+ SLASH="\\"
+ CXXFP="/Tp"
+ CFP="/Tc"
+ OFP="/Fo"
+ MAKELIB="lib.exe /nologo /subsystem:console /machine:I386 /verbose /out:\$@"
+ RMCOMMAND="-del"
+ RANLIB="echo"
+ #L_OPT="/debug" # for debugging
+ L_OPT="" # no debug info
+ LINK="link $L_OPT /nologo /subsystem:console /incremental:no /machine:I386 /out:\$@ BINMODE.OBJ"
+ EXE=".exe"
+ PRIMARY_TARGET="bochs.exe"
+ COMMAND_SEPARATOR=""
+ CD_UP_ONE="cd .."
+ CD_UP_TWO="cd ..\.."
+ cat >> confdefs.h <<\EOF
+#define BX_64BIT_CONSTANTS_USE_LL 0
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define inline __inline
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_NO_EMPTY_STRUCTS 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_NO_ATTRIBUTES 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_HASH_MAP 0
+EOF
+
+elif test "$with_macos" = yes; then
+ echo "$ac_t""macos" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_MACOS 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define BX_HAVE_STRDUP 0
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_MACOS)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_MACOS)'
+elif test "$with_term" = yes; then
+ echo "$ac_t""term" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_TERM 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_TERM)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_TERM)'
+ use_curses=yes
+else
+ echo "$ac_t""none" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BX_WITH_NOGUI 1
+EOF
+
+ GUI_OBJS='$(GUI_OBJS_NOGUI)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_NOGUI)'
+fi
+
+if test "$use_curses" = yes; then
+ echo $ac_n "checking for mvaddch in -lcurses""... $ac_c" 1>&6
+echo "configure:5264: checking for mvaddch in -lcurses" >&5
+ac_lib_var=`echo curses'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5272 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ GUI_LINK_OPTS_TERM='-lcurses'
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for mvaddch in -lncurses""... $ac_c" 1>&6
+echo "configure:5304: checking for mvaddch in -lncurses" >&5
+ac_lib_var=`echo ncurses'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lncurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5312 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5323: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ GUI_LINK_OPTS_TERM='-lncurses'
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ echo $ac_n "checking for mvaddch in -ltermlib""... $ac_c" 1>&6
+echo "configure:5344: checking for mvaddch in -ltermlib" >&5
+ac_lib_var=`echo termlib'_'mvaddch | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ltermlib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5352 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char mvaddch();
+
+int main() {
+mvaddch()
+; return 0; }
+EOF
+if { (eval echo configure:5363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ GUI_LINK_OPTS_TERM='-ltermlib'
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "$GUI_LINK_OPTS_TERM" = ""; then
+ echo Curses library not found: tried curses, ncurses, and termlib.
+ exit 1
+ fi
+fi
+
+if test "$with_rfb" = yes; then
+ # first see if compiler takes "-pthread" argument
+ echo $ac_n "checking for -pthread arg to compiler""... $ac_c" 1>&6
+echo "configure:5392: checking for -pthread arg to compiler" >&5
+ CFLAGS_SAVE="$CFLAGS"
+ CFLAGS="$CFLAGS -pthread"
+ cat > conftest.$ac_ext <<EOF
+#line 5396 "configure"
+#include "confdefs.h"
+ #include <pthread.h>
+int main() {
+ pthread_create(0,0,0,0);
+; return 0; }
+EOF
+if { (eval echo configure:5403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+
+ # it compiles with -pthread
+ echo "$ac_t""yes" 1>&6
+ CXXFLAGS="$CXXFLAGS -pthread"
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+
+ echo "$ac_t""no" 1>&6
+ # now try with -lpthread
+ CFLAGS="$CFLAGS_SAVE"
+ echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
+echo "configure:5419: checking for pthread_create in -lpthread" >&5
+ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lpthread $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 5427 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pthread_create();
+
+int main() {
+pthread_create()
+; return 0; }
+EOF
+if { (eval echo configure:5438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ # it compiles with -lpthread
+ RFB_LIBS='-lpthread'
+
+else
+ echo "$ac_t""no" 1>&6
+
+ echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
+
+fi
+
+
+fi
+rm -f conftest*
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Extract the first word of "gzip", so it can be a program name with args.
+set dummy gzip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5490: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GZIP" in
+ /*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GZIP="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+GZIP="$ac_cv_path_GZIP"
+if test -n "$GZIP"; then
+ echo "$ac_t""$GZIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "tar", so it can be a program name with args.
+set dummy tar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:5525: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_TAR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$TAR" in
+ /*)
+ ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_TAR="$TAR" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_TAR="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+TAR="$ac_cv_path_TAR"
+if test -n "$TAR"; then
+ echo "$ac_t""$TAR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+
+sid_host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host`
+sid_target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target`
+
+if test "$sid_host" = "$sid_target" -o "$target" = "NONE"
+then
+ echo "configure: warning: Assuming --enable-targets=all" 1>&2
+ all_targets=""
+ sidtarget_default=1
+else
+ all_targets="$target"
+ sidtarget_default=0
+fi
+
+
+# Check whether --enable-targets or --disable-targets was given.
+if test "${enable_targets+set}" = set; then
+ enableval="$enable_targets"
+
+ case "${enable_targets}" in
+ all) sidtarget_default=1 ;;
+ no) sidtarget_default=0 ;;
+ *) all_targets="${all_targets} `echo ${enable_targets} | sed -e 's-,- -g'`" ;;
+ esac
+
+fi
+
+
+sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
+sidtarget_mips=$sidtarget_default
+sidtarget_m32r=$sidtarget_default
+sidtarget_m68k=$sidtarget_default
+sidtarget_ppc=$sidtarget_default
+
+for targ in $all_targets
+do
+ case "$targ" in
+ arm*) sidtarget_arm=1 ;;
+ thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
+ mips*) sidtarget_mips=1 ;;
+ m32r*) sidtarget_m32r=1 ;;
+ m68k*) sidtarget_m68k=1 ;;
+ powerpc*) sidtarget_ppc=1 ;;
+ ppc*) sidtarget_ppc=1 ;;
+ *) echo "configure: warning: "Unknown target $targ"" 1>&2 ;;
+ esac
+done
+
+case 1 in
+ ${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
+ ${sidtarget_mips}) ;;
+ ${sidtarget_m32r}) ;;
+ ${sidtarget_m68k}) ;;
+ ${sidtarget_ppc}) ;;
+ *) echo "configure: warning: No selected sid targets: use --enable-targets or --target" 1>&2
+ ;;
+esac
+
+
+echo $ac_n "checking ARM family support""... $ac_c" 1>&6
+echo "configure:5623: checking ARM family support" >&5
+
+
+
+if test "x$sidtarget_arm" = x1; then
+ SIDTARGET_ARM_TRUE=
+ SIDTARGET_ARM_FALSE='#'
+else
+ SIDTARGET_ARM_TRUE='#'
+ SIDTARGET_ARM_FALSE=
+fi
+echo "$ac_t""$sidtarget_arm" 1>&6
+
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:5637: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
+echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
+echo "configure:5651: checking MIPS family support" >&5
+
+
+
+if test "x$sidtarget_mips" = x1; then
+ SIDTARGET_MIPS_TRUE=
+ SIDTARGET_MIPS_FALSE='#'
+else
+ SIDTARGET_MIPS_TRUE='#'
+ SIDTARGET_MIPS_FALSE=
+fi
+echo "$ac_t""$sidtarget_mips" 1>&6
+
+echo $ac_n "checking M32R family support""... $ac_c" 1>&6
+echo "configure:5665: checking M32R family support" >&5
+
+
+
+if test "x$sidtarget_m32r" = x1; then
+ SIDTARGET_M32R_TRUE=
+ SIDTARGET_M32R_FALSE='#'
+else
+ SIDTARGET_M32R_TRUE='#'
+ SIDTARGET_M32R_FALSE=
+fi
+echo "$ac_t""$sidtarget_m32r" 1>&6
+
+echo $ac_n "checking M68K family support""... $ac_c" 1>&6
+echo "configure:5679: checking M68K family support" >&5
+
+
+
+if test "x$sidtarget_m68k" = x1; then
+ SIDTARGET_M68K_TRUE=
+ SIDTARGET_M68K_FALSE='#'
+else
+ SIDTARGET_M68K_TRUE='#'
+ SIDTARGET_M68K_FALSE=
+fi
+echo "$ac_t""$sidtarget_m68k" 1>&6
+
+echo $ac_n "checking PPC family support""... $ac_c" 1>&6
+echo "configure:5693: checking PPC family support" >&5
+
+
+
+if test "x$sidtarget_ppc" = x1; then
+ SIDTARGET_PPC_TRUE=
+ SIDTARGET_PPC_FALSE='#'
+else
+ SIDTARGET_PPC_TRUE='#'
+ SIDTARGET_PPC_FALSE=
+fi
+echo "$ac_t""$sidtarget_ppc" 1>&6
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile cpu/Makefile memory/Makefile fpu/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CXX@%$CXX%g
+s%@CPP@%$CPP%g
+s%@X_CFLAGS@%$X_CFLAGS%g
+s%@X_PRE_LIBS@%$X_PRE_LIBS%g
+s%@X_LIBS@%$X_LIBS%g
+s%@X_EXTRA_LIBS@%$X_EXTRA_LIBS%g
+s%@DYNAMIC_VAR@%$DYNAMIC_VAR%g
+s%@AS_DYNAMIC_OBJS@%$AS_DYNAMIC_OBJS%g
+s%@AS_DYNAMIC_INCS@%$AS_DYNAMIC_INCS%g
+s%@IOAPIC_OBJS@%$IOAPIC_OBJS%g
+s%@APIC_OBJS@%$APIC_OBJS%g
+s%@BX_SPLIT_HD_SUPPORT@%$BX_SPLIT_HD_SUPPORT%g
+s%@NE2K_OBJS@%$NE2K_OBJS%g
+s%@PCI_OBJ@%$PCI_OBJ%g
+s%@SUFFIX_LINE@%$SUFFIX_LINE%g
+s%@CPP_SUFFIX@%$CPP_SUFFIX%g
+s%@DEBUGGER_VAR@%$DEBUGGER_VAR%g
+s%@DISASM_VAR@%$DISASM_VAR%g
+s%@READLINE_LIB@%$READLINE_LIB%g
+s%@BX_LOADER_OBJS@%$BX_LOADER_OBJS%g
+s%@INSTRUMENT_DIR@%$INSTRUMENT_DIR%g
+s%@INSTRUMENT_VAR@%$INSTRUMENT_VAR%g
+s%@VIDEO_OBJS@%$VIDEO_OBJS%g
+s%@FPU_VAR@%$FPU_VAR%g
+s%@FPU_GLUE_OBJ@%$FPU_GLUE_OBJ%g
+s%@CDROM_OBJS@%$CDROM_OBJS%g
+s%@SB16_OBJS@%$SB16_OBJS%g
+s%@IODEV_LIB_VAR@%$IODEV_LIB_VAR%g
+s%@NONINLINE_VAR@%$NONINLINE_VAR%g
+s%@INLINE_VAR@%$INLINE_VAR%g
+s%@EXTERNAL_DEPENDENCY@%$EXTERNAL_DEPENDENCY%g
+s%@RFB_LIBS@%$RFB_LIBS%g
+s%@GUI_OBJS@%$GUI_OBJS%g
+s%@GUI_LINK_OPTS@%$GUI_LINK_OPTS%g
+s%@GUI_LINK_OPTS_TERM@%$GUI_LINK_OPTS_TERM%g
+s%@DASH@%$DASH%g
+s%@SLASH@%$SLASH%g
+s%@CXXFP@%$CXXFP%g
+s%@CFP@%$CFP%g
+s%@OFP@%$OFP%g
+s%@MAKELIB@%$MAKELIB%g
+s%@RMCOMMAND@%$RMCOMMAND%g
+s%@LINK@%$LINK%g
+s%@EXE@%$EXE%g
+s%@PRIMARY_TARGET@%$PRIMARY_TARGET%g
+s%@COMMAND_SEPARATOR@%$COMMAND_SEPARATOR%g
+s%@CD_UP_ONE@%$CD_UP_ONE%g
+s%@CD_UP_TWO@%$CD_UP_TWO%g
+s%@GZIP@%$GZIP%g
+s%@TAR@%$TAR%g
+s%@sidtarget_arm@%$sidtarget_arm%g
+s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
+s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
+s%@sidtarget_mips@%$sidtarget_mips%g
+s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
+s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
+s%@sidtarget_m32r@%$sidtarget_m32r%g
+s%@SIDTARGET_M32R_TRUE@%$SIDTARGET_M32R_TRUE%g
+s%@SIDTARGET_M32R_FALSE@%$SIDTARGET_M32R_FALSE%g
+s%@sidtarget_m68k@%$sidtarget_m68k%g
+s%@SIDTARGET_M68K_TRUE@%$SIDTARGET_M68K_TRUE%g
+s%@SIDTARGET_M68K_FALSE@%$SIDTARGET_M68K_FALSE%g
+s%@sidtarget_ppc@%$sidtarget_ppc%g
+s%@SIDTARGET_PPC_TRUE@%$SIDTARGET_PPC_TRUE%g
+s%@SIDTARGET_PPC_FALSE@%$SIDTARGET_PPC_FALSE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile cpu/Makefile memory/Makefile fpu/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
--- /dev/null
+dnl // Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.4)
+AC_INIT(components.cxx)
+AC_CONFIG_AUX_DIR(../../config)
+AM_CONFIG_HEADER(config.h)
+
+AM_INIT_AUTOMAKE(sidcomp,0.1)
+AM_MAINTAINER_MODE
+AC_EXEEXT
+AM_PROG_LIBTOOL
+
+changequote(<<, >>)
+changequote([, ])
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_PATH_XTRA
+
+AC_C_BIGENDIAN
+AC_C_INLINE
+AC_CHECK_SIZEOF(unsigned char, 1)
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned long, 4)
+AC_CHECK_SIZEOF(unsigned long long, 8)
+AC_CHECK_SIZEOF(int *, 4)
+AC_CHECK_FUNCS(select, AC_DEFINE(BX_HAVE_SELECT))
+AC_CHECK_FUNCS(snprintf, AC_DEFINE(BX_HAVE_SNPRINTF))
+AC_CHECK_FUNCS(strtoull, AC_DEFINE(BX_HAVE_STRTOULL))
+AC_CHECK_FUNCS(strtouq, AC_DEFINE(BX_HAVE_STRTOUQ))
+AC_CHECK_FUNCS(strdup, AC_DEFINE(BX_HAVE_STRDUP))
+
+AC_MSG_CHECKING(if compiler allows empty structs)
+AC_TRY_COMPILE([], [typedef struct { } junk;],
+ AC_MSG_RESULT(yes),
+ [
+ AC_DEFINE(BX_NO_EMPTY_STRUCTS)
+ AC_MSG_RESULT(no)
+ ])
+
+AC_MSG_CHECKING(if compiler allows __attribute__)
+AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;],
+ AC_MSG_RESULT(yes),
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_NO_ATTRIBUTES)
+ ])
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_MSG_CHECKING(for hash_map.h)
+AC_TRY_COMPILE([#include <hash_map.h>], [],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_HAVE_HASH_MAP)
+ ], AC_MSG_RESULT(no))
+AC_LANG_RESTORE
+
+AC_MSG_CHECKING(for number of processors)
+AC_ARG_ENABLE(processors,
+ [ --enable-processors select number of processors (1,2,4)],
+ [case "$enableval" in
+ 1)
+ AC_MSG_RESULT(1)
+ AC_DEFINE(BX_SMP_PROCESSORS, 1)
+ AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+ AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 1)
+ ;;
+ 2)
+ AC_MSG_RESULT(2)
+ AC_DEFINE(BX_SMP_PROCESSORS, 2)
+ AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+ AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 2)
+ AC_DEFINE(BX_USE_CPU_SMF, 0)
+ ;;
+ 4)
+ AC_MSG_RESULT(4)
+ AC_DEFINE(BX_SMP_PROCESSORS, 4)
+ AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 2)
+ AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 4)
+ AC_DEFINE(BX_USE_CPU_SMF, 0)
+ ;;
+ *)
+ echo " "
+ echo "WARNING: processors != [1,2,4] can work, but you need to modify rombios.c manually"
+ AC_MSG_RESULT($enable_val)
+ AC_DEFINE(BX_SMP_PROCESSORS, $enable_val)
+ AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+ AC_DEFINE(BX_IOAPIC_DEFAULT_ID, $enable_val)
+ AC_DEFINE(BX_USE_CPU_SMF, 0)
+ ;;
+ esac
+ bx_procs="$enableval"
+ ],
+ [
+ AC_MSG_RESULT(1)
+ AC_DEFINE(BX_SMP_PROCESSORS, 1)
+ AC_DEFINE(BX_BOOTSTRAP_PROCESSOR, 0)
+ AC_DEFINE(BX_IOAPIC_DEFAULT_ID, 1)
+ bx_procs=1
+ ]
+ )
+
+AC_MSG_CHECKING(if compiler allows blank labels)
+AC_TRY_COMPILE([], [ { label1: } ],
+ AC_MSG_RESULT(yes),
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_NO_BLANK_LABELS)
+ ])
+
+AC_MSG_CHECKING(if compiler allows LL for 64-bit constants)
+AC_TRY_COMPILE([], [ { 42LL; } ],
+ AC_MSG_RESULT(yes),
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_64BIT_CONSTANTS_USE_LL, 0)
+ ])
+
+AC_MSG_CHECKING(for cpu level)
+AC_ARG_ENABLE(cpu-level,
+ [ --enable-cpu-level select cpu level (3,4,5,6)],
+ [case "$enableval" in
+ 3)
+ AC_MSG_RESULT(3)
+ AC_DEFINE(BX_CPU_LEVEL, 3)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 3)
+ ;;
+ 4)
+ AC_MSG_RESULT(4)
+ AC_DEFINE(BX_CPU_LEVEL, 4)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 4)
+ ;;
+ 5)
+ AC_MSG_RESULT(5)
+ AC_DEFINE(BX_CPU_LEVEL, 5)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 5)
+ ;;
+ 6)
+ AC_MSG_RESULT(6)
+ AC_DEFINE(BX_CPU_LEVEL, 6)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 6)
+ ;;
+ *)
+ echo " "
+ echo "ERROR: you must supply a valid CPU level to --enable-cpu-level"
+ exit 1
+ ;;
+ esac
+ bx_cpu_level=$enableval
+ if test "$bx_procs" -gt 1 -a "$enableval" -lt 6; then
+ echo "ERROR: with >1 processor, use --enable-cpu-level=6"
+ exit 1
+ fi
+ ],
+ [
+ # for multiprocessors, cpu level must be 6
+ if test "$bx_procs" -gt 1; then
+ AC_MSG_RESULT(6)
+ AC_DEFINE(BX_CPU_LEVEL, 6)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 6)
+ bx_cpu_level=6
+ else
+ AC_MSG_RESULT(5)
+ AC_DEFINE(BX_CPU_LEVEL, 5)
+ AC_DEFINE(BX_CPU_LEVEL_HACKED, 5)
+ bx_cpu_level=5
+ fi
+ ]
+ )
+
+
+AC_MSG_CHECKING(for dynamic translation support)
+AC_ARG_ENABLE(dynamic,
+ [ --enable-dynamic enable dynamic translation support],
+ [if test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_DYNAMIC_TRANSLATION, 0)
+ DYNAMIC_VAR=''
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+ else
+ if test "$enableval" = yes; then
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "You must specify a CPU type to dynamic-translation option"
+ echo \!\!\!Error\!\!\!
+ exit 1
+ fi
+ case "$enableval" in
+ i386)
+ AC_DEFINE(BX_DYNAMIC_CPU_I386, 1)
+ AS_DYNAMIC_OBJS='$(X86_OBJS)'
+ AS_DYNAMIC_INCS='$(X86_H)'
+ ;;
+ sparc)
+ AC_DEFINE(BX_DYNAMIC_CPU_SPARC, 1)
+ AS_DYNAMIC_OBJS='$(SPARC_OBJS).o'
+ AS_DYNAMIC_INCS='$(SPARC_H)'
+ ;;
+ *)
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "Sorry, dynamic translation is not yet available on your platform"
+ echo \!\!\!Error\!\!\!
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+ exit 1 ;;
+ esac
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_DYNAMIC_TRANSLATION, 1)
+ DYNAMIC_VAR='$(DYNAMIC_LIB)'
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_DYNAMIC_TRANSLATION, 0)
+ DYNAMIC_VAR=''
+ AS_DYNAMIC_OBJS=''
+ AS_DYNAMIC_INCS=''
+ ]
+ )
+AC_SUBST(DYNAMIC_VAR)
+AC_SUBST(AS_DYNAMIC_OBJS)
+AC_SUBST(AS_DYNAMIC_INCS)
+
+AC_MSG_CHECKING(for APIC support)
+AC_ARG_ENABLE(apic,
+ [ --enable-apic enable APIC support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_APIC, 1)
+ IOAPIC_OBJS='ioapic.o'
+ APIC_OBJS='apic.o'
+ else
+ AC_MSG_RESULT(no)
+ if test "$bx_procs" -gt 1; then
+ echo "Number of processors = $bx_procs"
+ echo "ERROR: With processors > 1 you must use --enable-apic"
+ exit 1
+ fi
+ AC_DEFINE(BX_SUPPORT_APIC, 0)
+ IOAPIC_OBJS=''
+ APIC_OBJS=''
+ fi
+ ],
+ [
+ if test "$bx_procs" -gt 1 -o "$bx_cpu_level" -gt 5; then
+ # enable APIC by default, if processors>1 or if cpulevel>5
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_APIC, 1)
+ IOAPIC_OBJS='ioapic.o'
+ APIC_OBJS='apic.o'
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_APIC, 0)
+ IOAPIC_OBJS=''
+ APIC_OBJS=''
+ fi
+ ]
+ )
+AC_SUBST(IOAPIC_OBJS)
+AC_SUBST(APIC_OBJS)
+
+AC_MSG_CHECKING(for split hard disk image support)
+AC_ARG_ENABLE(split-hd,
+ [ --enable-split-hd allows split hard disk image],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SPLIT_HD_SUPPORT, 1)
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SPLIT_HD_SUPPORT, 0)
+ fi],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SPLIT_HD_SUPPORT, 1)
+ ]
+ )
+AC_SUBST(BX_SPLIT_HD_SUPPORT)
+
+AC_MSG_CHECKING(for NE2000 support)
+AC_ARG_ENABLE(ne2000,
+ [ --enable-ne2000 enable limited ne2000 support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_NE2K_SUPPORT, 1)
+ NE2K_OBJS='ne2k.o eth.o eth_null.o'
+ AC_CHECK_HEADER(net/bpf.h, NE2K_OBJS="$NE2K_OBJS eth_fbsd.o")
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_NE2K_SUPPORT, 0)
+ NE2K_OBJS=''
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_NE2K_SUPPORT, 0)
+ NE2K_OBJS=''
+ ]
+ )
+AC_SUBST(NE2K_OBJS)
+
+
+AC_MSG_CHECKING(for i440FX PCI support)
+AC_ARG_ENABLE(pci,
+ [ --enable-pci enable limited i440FX PCI support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_PCI_SUPPORT, 1)
+ PCI_OBJ='pci.o'
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_PCI_SUPPORT, 0)
+ PCI_OBJ=''
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_PCI_SUPPORT, 0)
+ PCI_OBJ=''
+ ]
+ )
+AC_SUBST(PCI_OBJ)
+
+
+AC_MSG_CHECKING(for port e9 hack)
+AC_ARG_ENABLE(port-e9-hack,
+ [ --enable-port-e9-hack writes to port e9 go to console],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_PORT_E9_HACK, 1)
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_PORT_E9_HACK, 0)
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_PORT_E9_HACK, 0)
+ ]
+ )
+
+
+AC_MSG_CHECKING(for use of .cpp as suffix)
+AC_ARG_ENABLE(cpp,
+ [ --enable-cpp use .cpp as C++ suffix],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ SUFFIX_LINE='.SUFFIXES: .cpp'
+ CPP_SUFFIX='cpp'
+ else
+ AC_MSG_RESULT(no)
+ SUFFIX_LINE='.SUFFIXES: .cc'
+ CPP_SUFFIX='cc'
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ SUFFIX_LINE='.SUFFIXES: .cc'
+ CPP_SUFFIX='cc'
+ ]
+ )
+AC_SUBST(SUFFIX_LINE)
+AC_SUBST(CPP_SUFFIX)
+
+if test "$enable_cpp" = yes; then
+ echo "moving .cc source files to .cpp"
+ sourcefiles=`find . -name "*.cc" -print`
+ if test "$sourcefiles" != ""; then
+ for ccname in $sourcefiles
+ do
+ cppname=`echo $ccname | sed -e "s/\.cc$/.cpp/"`
+ echo "mv $ccname $cppname"
+ mv $ccname $cppname
+ done
+ else
+ echo "no more .cc source files to rename"
+ fi
+fi
+
+
+AC_MSG_CHECKING(for Bochs internal debugger support)
+AC_ARG_ENABLE(debugger,
+ [ --enable-debugger compile in support for Bochs internal debugger],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_DEBUGGER, 1)
+ DEBUGGER_VAR='$(DEBUGGER_LIB)'
+ bx_debugger=1
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_DEBUGGER, 0)
+ DEBUGGER_VAR=''
+ bx_debugger=0
+ fi
+ ],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_DEBUGGER, 0)
+ DEBUGGER_VAR=''
+ bx_debugger=0
+ ]
+ )
+AC_SUBST(DEBUGGER_VAR)
+
+AC_MSG_CHECKING(for disassembler support)
+AC_ARG_ENABLE(disasm,
+ [ --enable-disasm compile in support for disassembler],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_DISASM, 1)
+ DISASM_VAR='$(DISASM_LIB)'
+ else
+ AC_MSG_RESULT(no)
+ if test "$bx_debugger" = 1; then
+ echo "ERROR: debugger is enabled, so --enable-disasm is required"
+ exit 1
+ fi
+ AC_DEFINE(BX_DISASM, 0)
+ DISASM_VAR=''
+ fi],
+ [
+ if test "$bx_debugger" = 1; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_DISASM, 1)
+ DISASM_VAR='$(DISASM_LIB)'
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_DISASM, 0)
+ DISASM_VAR=''
+ fi
+ ]
+ )
+AC_SUBST(DISASM_VAR)
+
+AC_MSG_CHECKING(whether to use readline)
+AC_ARG_ENABLE(readline,
+ [ --enable-readline use readline library with debugger],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ want_readline=yes
+ else
+ AC_MSG_RESULT(no)
+ want_readline=no
+ fi],
+ [ # default is yes
+ AC_MSG_RESULT(yes)
+ want_readline=yes ]
+ )
+
+
+if test "$want_readline" = yes; then
+ AC_CHECK_LIB(readline,
+ readline,
+ [
+ if test "$bx_debugger" = 1; then
+ # only add readline library if debugger is on
+ AC_DEFINE(HAVE_LIBREADLINE, 1)
+ READLINE_LIB='-lreadline'
+ fi
+ ]
+ )
+fi
+ AC_SUBST(READLINE_LIB)
+
+AC_CHECK_HEADER(readline/history.h,
+ AC_DEFINE(HAVE_READLINE_HISTORY_H)
+ )
+
+
+AC_MSG_CHECKING(for loader support)
+AC_ARG_ENABLE(loader,
+ [ --enable-loader support calling external loader from debugger],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_USE_LOADER, 1)
+ BX_LOADER_OBJS='bx_loader.o loader.o'
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_USE_LOADER, 0)
+ BX_LOADER_OBJS=''
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_USE_LOADER, 0)
+ BX_LOADER_OBJS=''
+ ]
+ )
+AC_SUBST(BX_LOADER_OBJS)
+
+
+
+INSTRUMENT_DIR='instrument/stubs'
+
+AC_MSG_CHECKING(for instrumentation support)
+AC_ARG_ENABLE(instrumentation,
+ [ --enable-instrumentation compile in support for instrumentation],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_INSTRUMENTATION, 1)
+ INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+ elif test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_INSTRUMENTATION, 0)
+ INSTRUMENT_VAR=''
+ else
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_INSTRUMENTATION, 1)
+ INSTRUMENT_DIR=$enableval
+ INSTRUMENT_VAR='$(INSTRUMENT_LIB)'
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_INSTRUMENTATION, 0)
+ INSTRUMENT_VAR=''
+ ]
+ )
+AC_SUBST(INSTRUMENT_DIR)
+AC_SUBST(INSTRUMENT_VAR)
+
+AC_ARG_ENABLE(simid,
+ [ --enable-simid=0 or 1 CPU simulator ID if using more than one],
+ [if test "$enableval" = yes; then
+ AC_DEFINE(BX_SIM_ID, 0)
+ elif test "$enableval" = no; then
+ AC_DEFINE(BX_SIM_ID, 0)
+ else
+ AC_DEFINE_UNQUOTED(BX_SIM_ID, $enableval)
+ fi],
+ [
+ AC_DEFINE(BX_SIM_ID, 0)
+ ]
+ )
+
+AC_ARG_ENABLE(num-sim,
+ [ --enable-num-sim=1 or 2 number of CPU simulators],
+ [if test "$enableval" = yes; then
+ AC_DEFINE(BX_NUM_SIMULATORS, 1)
+ elif test "$enableval" = no; then
+ AC_DEFINE(BX_NUM_SIMULATORS, 1)
+ else
+ AC_DEFINE_UNQUOTED(BX_NUM_SIMULATORS, $enableval)
+ fi],
+ [
+ AC_DEFINE(BX_NUM_SIMULATORS, 1)
+ ]
+ )
+
+AC_ARG_ENABLE(time0,
+ [ --enable-time0=n start at n instead of using time()],
+ [if test "$enableval" = yes; then
+ AC_DEFINE(BX_USE_SPECIFIED_TIME0, 917385580)
+ elif test "$enableval" = no; then
+ AC_DEFINE(BX_USE_SPECIFIED_TIME0, 0)
+ else
+ AC_DEFINE_UNQUOTED(BX_USE_SPECIFIED_TIME0, $enableval)
+ fi],
+ [
+ AC_DEFINE(BX_USE_SPECIFIED_TIME0, 0)
+ ]
+ )
+
+
+
+AC_MSG_CHECKING(for VGA emulation)
+AC_ARG_ENABLE(vga,
+ [ --enable-vga use VGA emulation],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_VGA, 1)
+ VIDEO_OBJS='$(VIDEO_OBJS_VGA)'
+ else
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_VGA, 0)
+ VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_VGA, 0)
+ VIDEO_OBJS='$(VIDEO_OBJS_HGA)'
+ ]
+ )
+AC_SUBST(VIDEO_OBJS)
+
+AC_MSG_CHECKING(for FPU emulation)
+FPU_VAR=''
+FPU_GLUE_OBJ=''
+AC_ARG_ENABLE(fpu,
+ [ --enable-fpu compile in FPU emulation],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_FPU, 1)
+ FPU_VAR='$(FPU_LIB)'
+ FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+ elif test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_SUPPORT_FPU, 0)
+ else
+ echo " "
+ echo "ERROR: --enable-fpu does not accept a path"
+ exit 1
+ fi
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_SUPPORT_FPU, 1)
+ FPU_VAR='$(FPU_LIB)'
+ FPU_GLUE_OBJ='$(FPU_GLUE_OBJ)'
+ ]
+ )
+AC_SUBST(FPU_VAR)
+AC_SUBST(FPU_GLUE_OBJ)
+
+
+
+AC_MSG_CHECKING(for x86 debugger support)
+AC_ARG_ENABLE(x86-debugger,
+ [ --enable-x86-debugger x86 debugger support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_X86_DEBUGGER, 1)
+ elif test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_X86_DEBUGGER, 0)
+ else
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(BX_X86_DEBUGGER, 1)
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BX_X86_DEBUGGER, 0)
+ ]
+ )
+
+AC_MSG_CHECKING(for CDROM support)
+AC_ARG_ENABLE(cdrom,
+ [ --enable-cdrom CDROM support],
+ [if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ CDROM_OBJS='cdrom.o'
+ AC_DEFINE(BX_SUPPORT_CDROM, 1)
+ elif test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ CDROM_OBJS=''
+ AC_DEFINE(BX_SUPPORT_CDROM, 0)
+ else
+ AC_MSG_RESULT(yes)
+ CDROM_OBJS='cdrom.o'
+ AC_DEFINE(BX_SUPPORT_CDROM, 1)
+ fi],
+ [
+ AC_MSG_RESULT(no)
+ CDROM_OBJS=''
+ AC_DEFINE(BX_SUPPORT_CDROM, 0)
+ ]
+ )
+AC_SUBST(CDROM_OBJS)
+
+
+AC_MSG_CHECKING(for Sound Blaster 16 support)
+AC_ARG_ENABLE(sb16,
+ [ --enable-sb16 Sound Blaster 16 Support],
+ [if test "$enableval" = no; then
+ AC_MSG_RESULT(no)
+ SB16_OBJS=''
+ AC_DEFINE(BX_SUPPORT_SB16, 0)
+ else
+ case "$enableval" in
+ dummy)
+ SB16_OBJS='$(SB16_DUMMY_OBJS)'
+ AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_output_c)
+ AC_MSG_RESULT(dummy)
+ ;;
+ linux)
+ SB16_OBJS='$(SB16_LINUX_OBJS)'
+ AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_linux_c)
+ AC_MSG_RESULT(linux)
+ ;;
+ win)
+ SB16_OBJS='$(SB16_WIN_OBJS)'
+ AC_DEFINE(BX_SOUND_OUTPUT_C, bx_sound_windows_c)
+ AC_MSG_RESULT(win)
+ ;;
+ *)
+ echo " "
+ echo \!\!\!Error\!\!\!
+ echo "You must pass one of dummy, linux, win to --enable-sb16"
+ exit 1 ;;
+ esac
+ AC_DEFINE(BX_SUPPORT_SB16, 1)
+ fi],
+
+ [
+ AC_MSG_RESULT(no)
+ SB16_OBJS=''
+ AC_DEFINE(BX_SUPPORT_SB16, 0)
+ ]
+ )
+AC_SUBST(SB16_OBJS)
+
+
+AC_ARG_ENABLE(hga-dumps,
+ [ --enable-hga-dumps=Nmicroseconds copy memory to HGA video buffer every N useconds],
+ AC_DEFINE_UNQUOTED(BX_EMULATE_HGA_DUMPS, $enableval),
+ )
+
+PRIMARY_TARGET='bochs'
+
+AC_DEFINE(BX_PROVIDE_DEVICE_MODELS, 0)
+IODEV_LIB_VAR='iodev/libiodev.a'
+AC_DEFINE(BX_PROVIDE_CPU_MEMORY, 1)
+NONINLINE_VAR='$(NONINLINE_OBJS)'
+
+AC_SUBST(IODEV_LIB_VAR)
+AC_SUBST(NONINLINE_VAR)
+AC_SUBST(INLINE_VAR)
+AC_SUBST(EXTERNAL_DEPENDENCY)
+
+
+AC_ARG_WITH(x11,
+ [ --with-x11 use X11 GUI],
+ )
+
+AC_ARG_WITH(beos,
+ [ --with-beos use BeOS GUI],
+ )
+
+AC_ARG_WITH(win32,
+ [ --with-win32 use Win32 GUI],
+ )
+
+AC_ARG_WITH(win32-vcpp,
+ [ --with-win32-vcpp use Win32 GUI/Visual C++ environment],
+ )
+
+AC_ARG_WITH(macos,
+ [ --with-macos use Macintosh/CodeWarrior environment],
+ )
+
+AC_ARG_WITH(nogui,
+ [ --with-nogui no native GUI, just use blank stubs],
+ )
+
+AC_ARG_WITH(term,
+ [ --with-term textmode terminal environment],
+ )
+
+AC_ARG_WITH(rfb,
+ [ --with-rfb use RFB protocol, works with VNC viewer],
+ )
+
+AC_MSG_CHECKING(for gui library to use)
+
+dnl Disable GUIs for SID use
+with_nogui=yes
+
+dnl // make sure X Windows is default if no other chosen
+if (test "$with_x11" != yes) && \
+ (test "$with_beos" != yes) && \
+ (test "$with_win32" != yes) && \
+ (test "$with_nogui" != yes) && \
+ (test "$with_win32_vcpp" != yes) && \
+ (test "$with_term" != yes) && \
+ (test "$with_rfb" != yes) && \
+ (test "$with_macos" != yes); then
+ with_x11=yes
+fi
+
+dnl // DASH is option prefix for your platform
+dnl // SLASH is directory for your platform
+dnl // CXXFP is C++ File Prefix; the flag that tells the compiler
+dnl // this is a C++ source file
+dnl // CFP is C File Prefix; the flag that tells the compiler
+dnl // this is a C source file
+dnl // OFP is Object File Prefix; the flag that tells the compiler
+dnl // generate an object file with this name
+DASH="-"
+SLASH="/"
+CXXFP=""
+CFP=""
+OFP="-o "
+MAKELIB="ar rv \$@"
+RMCOMMAND="rm -f "
+LINK="\$(CXX) -o \$@ \$(CXXFLAGS)"
+EXE=""
+COMMAND_SEPARATOR="&& \\"
+CD_UP_ONE="echo done"
+CD_UP_TWO="echo done"
+
+if test "$with_x11" = yes; then
+ AC_MSG_RESULT(X windows)
+ if test "$no_x" = yes; then
+ echo ERROR: X windows gui was selected, but X windows libraries were not found.
+ exit 1
+ fi
+ AC_DEFINE(BX_WITH_X11, 1)
+ GUI_OBJS='$(GUI_OBJS_X11)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_X)'
+elif test "$with_win32" = yes; then
+ AC_MSG_RESULT(win32)
+ AC_DEFINE(BX_WITH_WIN32, 1)
+ GUI_OBJS='$(GUI_OBJS_WIN32)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32)'
+elif test "$with_beos" = yes; then
+ AC_MSG_RESULT(beos)
+ AC_DEFINE(BX_WITH_BEOS, 1)
+ GUI_OBJS='$(GUI_OBJS_BEOS)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_BEOS)'
+elif test "$with_rfb" = yes; then
+ AC_MSG_RESULT(rfb)
+ AC_DEFINE(BX_WITH_RFB, 1)
+ GUI_OBJS='$(GUI_OBJS_RFB)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_RFB)'
+elif test "$with_win32_vcpp" = yes; then
+ AC_MSG_RESULT(win32-vcpp)
+ AC_DEFINE(BX_WITH_WIN32, 1)
+ GUI_OBJS='$(GUI_OBJS_WIN32)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_WIN32_VCPP)'
+
+ CC="cl"
+ CXX="$CC"
+ #C_OPT="/Zi" # for debugging
+ C_OPT="/O2" # optimize for speed
+ CFLAGS="/nologo /G6 /MT /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS $C_OPT"
+ CXXFLAGS="$CFLAGS"
+ DASH="/"
+ SLASH="\\"
+ CXXFP="/Tp"
+ CFP="/Tc"
+ OFP="/Fo"
+ MAKELIB="lib.exe /nologo /subsystem:console /machine:I386 /verbose /out:\$@"
+ RMCOMMAND="-del"
+ RANLIB="echo"
+ #L_OPT="/debug" # for debugging
+ L_OPT="" # no debug info
+ LINK="link $L_OPT /nologo /subsystem:console /incremental:no /machine:I386 /out:\$@ BINMODE.OBJ"
+ EXE=".exe"
+ PRIMARY_TARGET="bochs.exe"
+ COMMAND_SEPARATOR=""
+ CD_UP_ONE="cd .."
+ CD_UP_TWO="cd ..\.."
+ AC_DEFINE(BX_64BIT_CONSTANTS_USE_LL, 0)
+ AC_DEFINE(inline, __inline)
+ AC_DEFINE(BX_NO_EMPTY_STRUCTS, 1)
+ AC_DEFINE(BX_NO_ATTRIBUTES, 1)
+ AC_DEFINE(BX_HAVE_HASH_MAP, 0)
+elif test "$with_macos" = yes; then
+ AC_MSG_RESULT(macos)
+ AC_DEFINE(BX_WITH_MACOS, 1)
+ AC_DEFINE(BX_HAVE_STRDUP, 0)
+ GUI_OBJS='$(GUI_OBJS_MACOS)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_MACOS)'
+elif test "$with_term" = yes; then
+ AC_MSG_RESULT(term)
+ AC_DEFINE(BX_WITH_TERM, 1)
+ GUI_OBJS='$(GUI_OBJS_TERM)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_TERM)'
+ use_curses=yes
+else
+ AC_MSG_RESULT(none)
+ AC_DEFINE(BX_WITH_NOGUI, 1)
+ GUI_OBJS='$(GUI_OBJS_NOGUI)'
+ GUI_LINK_OPTS='$(GUI_LINK_OPTS_NOGUI)'
+fi
+
+if test "$use_curses" = yes; then
+ AC_CHECK_LIB(curses, mvaddch, GUI_LINK_OPTS_TERM='-lcurses')
+ AC_CHECK_LIB(ncurses, mvaddch, GUI_LINK_OPTS_TERM='-lncurses')
+ AC_CHECK_LIB(termlib, mvaddch, GUI_LINK_OPTS_TERM='-ltermlib')
+ if test "$GUI_LINK_OPTS_TERM" = ""; then
+ echo Curses library not found: tried curses, ncurses, and termlib.
+ exit 1
+ fi
+fi
+
+if test "$with_rfb" = yes; then
+ # first see if compiler takes "-pthread" argument
+ AC_MSG_CHECKING(for -pthread arg to compiler)
+ CFLAGS_SAVE="$CFLAGS"
+ CFLAGS="$CFLAGS -pthread"
+ AC_TRY_LINK([ #include <pthread.h> ],
+ [ pthread_create(0,0,0,0); ],
+ [
+ # it compiles with -pthread
+ AC_MSG_RESULT(yes)
+ CXXFLAGS="$CXXFLAGS -pthread"
+ ],
+ [
+ AC_MSG_RESULT(no)
+ # now try with -lpthread
+ CFLAGS="$CFLAGS_SAVE"
+ AC_CHECK_LIB(pthread,
+ pthread_create,
+ [
+ # it compiles with -lpthread
+ RFB_LIBS='-lpthread'
+ ],
+ [
+ echo ERROR: --with-rfb requires the pthread library, which could not be found.; exit 1
+ ])
+ ])
+fi
+
+AC_SUBST(RFB_LIBS)
+AC_SUBST(GUI_OBJS)
+AC_SUBST(GUI_LINK_OPTS)
+AC_SUBST(GUI_LINK_OPTS_TERM)
+AC_SUBST(DASH)
+AC_SUBST(SLASH)
+AC_SUBST(CXXFP)
+AC_SUBST(CFP)
+AC_SUBST(OFP)
+AC_SUBST(MAKELIB)
+AC_SUBST(RMCOMMAND)
+AC_SUBST(LINK)
+AC_SUBST(EXE)
+AC_SUBST(PRIMARY_TARGET)
+AC_SUBST(COMMAND_SEPARATOR)
+AC_SUBST(CD_UP_ONE)
+AC_SUBST(CD_UP_TWO)
+
+AC_PATH_PROG(GZIP, gzip)
+AC_PATH_PROG(TAR, tar)
+
+dnl Perform --target/--enable-targets processing.
+CY_SIDTARGET_CHECK
+
+AC_OUTPUT(Makefile cpu/Makefile memory/Makefile fpu/Makefile)
--- /dev/null
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+## sid/include in build tree bochs/cpu component/bochs sid/include in src tree bochs/memory
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../memory -I$(srcdir)/../debug
+
+noinst_LTLIBRARIES = libcpu.la
+
+libcpu_la_SOURCES = exception-sid.cc cpu.cc cpu.h cpu-sid.h cpu-sid.cc init-sid.cc state_file.h main-hack.cc x86.cc access.cc ctrl_xfer8.cc flag_ctrl.cc mult32.cc shift16.cc ctrl_xfer_pro.cc flag_ctrl_pro.cc mult8.cc shift32.cc arith16.cc data_xfer16.cc init.cc paging.cc shift8.cc arith32.cc data_xfer32.cc io.cc proc_ctrl.cc soft_int.cc soft_int-sid.cc arith8.cc data_xfer8.cc io_pro.cc protect_ctrl.cc stack16.cc bcd.cc debugstuff.cc debugstuff-sid.cc lazy_flags.cc protect_ctrl_pro.cc stack32.cc bit.cc decode16.cc logical16.cc resolve16.cc stack_pro.cc decode32.cc logical32.cc resolve32.cc string.cc ctrl_xfer16.cc exception.cc logical8.cc segment_ctrl.cc tasking.cc ctrl_xfer32.cc ctrl_xfer32-sid.cc fetchdecode.cc fetchdecode-sid.cc mult16.cc segment_ctrl_pro.cc vm8086.cc lazy_flags.h x86.h x86-memory-modes.cc
+
+libcpu_la_LDFLAGS = -no-undefined
--- /dev/null
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../memory -I$(srcdir)/../debug
+
+noinst_LTLIBRARIES = libcpu.la
+
+libcpu_la_SOURCES = exception-sid.cc cpu.cc cpu.h cpu-sid.h cpu-sid.cc init-sid.cc state_file.h main-hack.cc x86.cc access.cc ctrl_xfer8.cc flag_ctrl.cc mult32.cc shift16.cc ctrl_xfer_pro.cc flag_ctrl_pro.cc mult8.cc shift32.cc arith16.cc data_xfer16.cc init.cc paging.cc shift8.cc arith32.cc data_xfer32.cc io.cc proc_ctrl.cc soft_int.cc soft_int-sid.cc arith8.cc data_xfer8.cc io_pro.cc protect_ctrl.cc stack16.cc bcd.cc debugstuff.cc debugstuff-sid.cc lazy_flags.cc protect_ctrl_pro.cc stack32.cc bit.cc decode16.cc logical16.cc resolve16.cc stack_pro.cc decode32.cc logical32.cc resolve32.cc string.cc ctrl_xfer16.cc exception.cc logical8.cc segment_ctrl.cc tasking.cc ctrl_xfer32.cc ctrl_xfer32-sid.cc fetchdecode.cc fetchdecode-sid.cc mult16.cc segment_ctrl_pro.cc vm8086.cc lazy_flags.h x86.h x86-memory-modes.cc
+
+libcpu_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libcpu_la_LIBADD =
+libcpu_la_OBJECTS = exception-sid.lo cpu.lo cpu-sid.lo init-sid.lo \
+main-hack.lo x86.lo access.lo ctrl_xfer8.lo flag_ctrl.lo mult32.lo \
+shift16.lo ctrl_xfer_pro.lo flag_ctrl_pro.lo mult8.lo shift32.lo \
+arith16.lo data_xfer16.lo init.lo paging.lo shift8.lo arith32.lo \
+data_xfer32.lo io.lo proc_ctrl.lo soft_int.lo soft_int-sid.lo arith8.lo \
+data_xfer8.lo io_pro.lo protect_ctrl.lo stack16.lo bcd.lo debugstuff.lo \
+debugstuff-sid.lo lazy_flags.lo protect_ctrl_pro.lo stack32.lo bit.lo \
+decode16.lo logical16.lo resolve16.lo stack_pro.lo decode32.lo \
+logical32.lo resolve32.lo string.lo ctrl_xfer16.lo exception.lo \
+logical8.lo segment_ctrl.lo tasking.lo ctrl_xfer32.lo \
+ctrl_xfer32-sid.lo fetchdecode.lo fetchdecode-sid.lo mult16.lo \
+segment_ctrl_pro.lo vm8086.lo x86-memory-modes.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES = .deps/access.P .deps/arith16.P .deps/arith32.P \
+.deps/arith8.P .deps/bcd.P .deps/bit.P .deps/cpu-sid.P .deps/cpu.P \
+.deps/ctrl_xfer16.P .deps/ctrl_xfer32-sid.P .deps/ctrl_xfer32.P \
+.deps/ctrl_xfer8.P .deps/ctrl_xfer_pro.P .deps/data_xfer16.P \
+.deps/data_xfer32.P .deps/data_xfer8.P .deps/debugstuff-sid.P \
+.deps/debugstuff.P .deps/decode16.P .deps/decode32.P \
+.deps/exception-sid.P .deps/exception.P .deps/fetchdecode-sid.P \
+.deps/fetchdecode.P .deps/flag_ctrl.P .deps/flag_ctrl_pro.P \
+.deps/init-sid.P .deps/init.P .deps/io.P .deps/io_pro.P \
+.deps/lazy_flags.P .deps/logical16.P .deps/logical32.P .deps/logical8.P \
+.deps/main-hack.P .deps/mult16.P .deps/mult32.P .deps/mult8.P \
+.deps/paging.P .deps/proc_ctrl.P .deps/protect_ctrl.P \
+.deps/protect_ctrl_pro.P .deps/resolve16.P .deps/resolve32.P \
+.deps/segment_ctrl.P .deps/segment_ctrl_pro.P .deps/shift16.P \
+.deps/shift32.P .deps/shift8.P .deps/soft_int-sid.P .deps/soft_int.P \
+.deps/stack16.P .deps/stack32.P .deps/stack_pro.P .deps/string.P \
+.deps/tasking.P .deps/vm8086.P .deps/x86-memory-modes.P .deps/x86.P
+SOURCES = $(libcpu_la_SOURCES)
+OBJECTS = $(libcpu_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign cpu/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libcpu.la: $(libcpu_la_OBJECTS) $(libcpu_la_DEPENDENCIES)
+ $(CXXLINK) $(libcpu_la_LDFLAGS) $(libcpu_la_OBJECTS) $(libcpu_la_LIBADD) $(LIBS)
+.cc.o:
+ $(CXXCOMPILE) -c $<
+.cc.lo:
+ $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = cpu
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign cpu/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cc
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cc
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+
+
+ void
+BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
+ unsigned length)
+{
+ Bit32u upper_limit;
+
+
+ if ( protected_mode() ) {
+ if ( seg->cache.valid==0 ) {
+ BX_INFO(("seg = %s\n", BX_CPU_THIS_PTR strseg(seg)));
+ BX_INFO(("seg->selector.value = %04x\n", (unsigned) seg->selector.value));
+ BX_INFO(("write_virtual_checks: valid bit = 0\n"));
+ BX_INFO(("CS: %04x\n", (unsigned) BX_CPU_THIS_PTR sregs[1].selector.value));
+ BX_INFO(("IP: %04x\n", (unsigned) BX_CPU_THIS_PTR prev_eip));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if (seg->cache.p == 0) { /* not present */
+ BX_INFO(("write_virtual_checks(): segment not present\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+
+ switch ( seg->cache.type ) {
+ case 0: case 1: // read only
+ case 4: case 5: // read only, expand down
+ case 8: case 9: // execute only
+ case 10: case 11: // execute/read
+ case 12: case 13: // execute only, conforming
+ case 14: case 15: // execute/read-only, conforming
+ BX_INFO(("write_virtual_checks(): no write access to seg\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+
+ case 2: case 3: /* read/write */
+ if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+ BX_INFO(("write_virtual_checks(): write beyond limit, r/w\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+
+ case 6: case 7: /* read write, expand down */
+ if (seg->cache.u.segment.d_b)
+ upper_limit = 0xffffffff;
+ else
+ upper_limit = 0x0000ffff;
+ if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+ (offset > upper_limit) ||
+ ((upper_limit - offset) < (length - 1)) ) {
+ BX_INFO(("write_virtual_checks(): write beyond limit, r/w ED\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+ }
+
+ return;
+ }
+
+ else { /* real mode */
+ if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
+ //BX_INFO(("write_virtual_checks() SEG EXCEPTION: %x:%x + %x\n",
+ // (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length));
+ if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
+ else exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+}
+
+ void
+BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset,
+ unsigned length)
+{
+ Bit32u upper_limit;
+
+
+ if ( protected_mode() ) {
+ if ( seg->cache.valid==0 ) {
+ BX_CPU_THIS_PTR info("seg = %s\n", BX_CPU_THIS_PTR strseg(seg));
+ BX_CPU_THIS_PTR info("seg->selector.value = %04x\n", (unsigned) seg->selector.value);
+ //BX_CPU_THIS_PTR info("read_virtual_checks: valid bit = 0\n");
+ //BX_CPU_THIS_PTR info("CS: %04x\n", (unsigned)
+ //BX_CPU_THIS_PTR sregs[1].selector.value);
+ BX_INFO(("seg = %s\n", BX_CPU_THIS_PTR strseg(seg)));
+ BX_INFO(("seg->selector.value = %04x\n", (unsigned) seg->selector.value));
+ //BX_INFO(("read_virtual_checks: valid bit = 0\n"));
+ //BX_INFO(("CS: %04x\n", (unsigned)
+ // BX_CPU_THIS_PTR sregs[1].selector.value));
+ //BX_INFO(("IP: %04x\n", (unsigned) BX_CPU_THIS_PTR prev_eip));
+ //debug(BX_CPU_THIS_PTR eip);
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if (seg->cache.p == 0) { /* not present */
+ BX_INFO(("read_virtual_checks(): segment not present\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+
+ switch ( seg->cache.type ) {
+ case 0: case 1: /* read only */
+ case 10: case 11: /* execute/read */
+ case 14: case 15: /* execute/read-only, conforming */
+ if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+ BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+
+ case 2: case 3: /* read/write */
+ if ( (offset+length-1) > seg->cache.u.segment.limit_scaled ) {
+ BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+
+ case 4: case 5: /* read only, expand down */
+ if (seg->cache.u.segment.d_b)
+ upper_limit = 0xffffffff;
+ else
+ upper_limit = 0x0000ffff;
+ if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+ (offset > upper_limit) ||
+ ((upper_limit - offset) < (length - 1)) ) {
+ BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+
+ case 6: case 7: /* read write, expand down */
+ if (seg->cache.u.segment.d_b)
+ upper_limit = 0xffffffff;
+ else
+ upper_limit = 0x0000ffff;
+ if ( (offset <= seg->cache.u.segment.limit_scaled) ||
+ (offset > upper_limit) ||
+ ((upper_limit - offset) < (length - 1)) ) {
+ BX_INFO(("read_virtual_checks(): write beyond limit\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ }
+ break;
+
+ case 8: case 9: /* execute only */
+ case 12: case 13: /* execute only, conforming */
+ /* can't read or write an execute-only segment */
+ BX_INFO(("read_virtual_checks(): execute only\n"));
+ exception(int_number(seg), 0, 0);
+ return;
+ break;
+ }
+ return;
+ }
+
+ else { /* real mode */
+ if ( (offset + length - 1) > seg->cache.u.segment.limit_scaled) {
+ //BX_CPU_THIS_PTR info("read_virtual_checks() SEG EXCEPTION: %x:%x + %x\n",
+ // (unsigned) seg->selector.value, (unsigned) offset, (unsigned) length);
+ if (seg == & BX_CPU_THIS_PTR sregs[2]) exception(BX_SS_EXCEPTION, 0, 0);
+ else exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ return;
+ }
+}
+
+
+
+
+ char *
+BX_CPU_C::strseg(bx_segment_reg_t *seg)
+{
+ if (seg == &BX_CPU_THIS_PTR sregs[0]) return("ES");
+ else if (seg == & BX_CPU_THIS_PTR sregs[1]) return("CS");
+ else if (seg == & BX_CPU_THIS_PTR sregs[2]) return("SS");
+ else if (seg == &BX_CPU_THIS_PTR sregs[3]) return("DS");
+ else if (seg == &BX_CPU_THIS_PTR sregs[4]) return("FS");
+ else if (seg == &BX_CPU_THIS_PTR sregs[5]) return("GS");
+ else {
+ BX_INFO(("undefined segment passed to strseg()!\n"));
+ return("??");
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::write_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 1);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 1, BX_WRITE);
+
+ // all checks OK
+ access_linear(laddr, 1, CPL==3, BX_WRITE, (void *) data);
+}
+
+ void
+BX_CPU_C::write_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 2);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 2, BX_WRITE);
+
+ // all checks OK
+ access_linear(laddr, 2, CPL==3, BX_WRITE, (void *) data);
+}
+
+ void
+BX_CPU_C::write_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 4);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 4, BX_WRITE);
+
+ // all checks OK
+ access_linear(laddr, 4, CPL==3, BX_WRITE, (void *) data);
+}
+
+ void
+BX_CPU_C::read_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ read_virtual_checks(seg, offset, 1);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 1, BX_READ);
+
+ // all checks OK
+ access_linear(laddr, 1, CPL==3, BX_READ, (void *) data);
+}
+
+
+ void
+BX_CPU_C::read_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ read_virtual_checks(seg, offset, 2);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 2, BX_READ);
+
+ // all checks OK
+ access_linear(laddr, 2, CPL==3, BX_READ, (void *) data);
+}
+
+
+ void
+BX_CPU_C::read_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ read_virtual_checks(seg, offset, 4);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 4, BX_READ);
+
+ // all checks OK
+ access_linear(laddr, 4, CPL==3, BX_READ, (void *) data);
+}
+
+//////////////////////////////////////////////////////////////
+// special Read-Modify-Write operations //
+// address translation info is kept across read/write calls //
+//////////////////////////////////////////////////////////////
+
+ void
+BX_CPU_C::read_RMW_virtual_byte(unsigned s, Bit32u offset, Bit8u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 1);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 1, BX_READ);
+
+ // all checks OK
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg)
+ access_linear(laddr, 1, CPL==3, BX_RW, (void *) data);
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+ BX_INSTR_LIN_READ(laddr, laddr, 1);
+ BX_INSTR_LIN_WRITE(laddr, laddr, 1);
+ BX_CPU_THIS_PTR mem->read_physical(this, laddr, 1, (void *) data);
+ }
+}
+
+
+ void
+BX_CPU_C::read_RMW_virtual_word(unsigned s, Bit32u offset, Bit16u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 2);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 2, BX_READ);
+
+ // all checks OK
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg)
+ access_linear(laddr, 2, CPL==3, BX_RW, (void *) data);
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+ BX_INSTR_LIN_READ(laddr, laddr, 2);
+ BX_INSTR_LIN_WRITE(laddr, laddr, 2);
+ BX_CPU_THIS_PTR mem->read_physical(this, laddr, 2, data);
+ }
+}
+
+ void
+BX_CPU_C::read_RMW_virtual_dword(unsigned s, Bit32u offset, Bit32u *data)
+{
+ Bit32u laddr;
+ bx_segment_reg_t *seg;
+
+ seg = &BX_CPU_THIS_PTR sregs[s];
+ write_virtual_checks(seg, offset, 4);
+
+ laddr = seg->cache.u.segment.base + offset;
+ BX_INSTR_MEM_DATA(laddr, 4, BX_READ);
+
+ // all checks OK
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg)
+ access_linear(laddr, 4, CPL==3, BX_RW, (void *) data);
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR address_xlation.paddress1 = laddr;
+ BX_INSTR_LIN_READ(laddr, laddr, 4);
+ BX_INSTR_LIN_WRITE(laddr, laddr, 4);
+ BX_CPU_THIS_PTR mem->read_physical(this, laddr, 4, data);
+ }
+}
+
+ void
+BX_CPU_C::write_RMW_virtual_byte(Bit8u val8)
+{
+ BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 1, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg) {
+ // BX_CPU_THIS_PTR address_xlation.pages must be 1
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
+ }
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1, &val8);
+ }
+}
+
+ void
+BX_CPU_C::write_RMW_virtual_word(Bit16u val16)
+{
+ BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 2, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg) {
+ if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
+ }
+ else {
+#ifdef BX_LITTLE_ENDIAN
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
+ &val16);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
+ ((Bit8u *) &val16) + 1);
+#else
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 1,
+ ((Bit8u *) &val16) + 1);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2, 1,
+ &val16);
+#endif
+ }
+ }
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 2, &val16);
+ }
+}
+
+ void
+BX_CPU_C::write_RMW_virtual_dword(Bit32u val32)
+{
+ BX_INSTR_MEM_DATA(BX_CPU_THIS_PTR address_xlation.paddress1, 4, BX_WRITE);
+
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR cr0.pg) {
+ if (BX_CPU_THIS_PTR address_xlation.pages == 1) {
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
+ }
+ else {
+#ifdef BX_LITTLE_ENDIAN
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1,
+ &val32);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2,
+ ((Bit8u *) &val32) + BX_CPU_THIS_PTR address_xlation.len1);
+#else
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1,
+ ((Bit8u *) &val32) + (4 - BX_CPU_THIS_PTR address_xlation.len1));
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2,
+ &val32);
+#endif
+ }
+ }
+ else
+#endif
+ {
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, 4, &val32);
+ }
+}
--- /dev/null
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#include <assert.h>
+
+#define LOG_THIS this->
+
+bx_generic_apic_c *apic_index[APIC_MAX_ID];
+
+bx_generic_apic_c::bx_generic_apic_c ()
+{
+ id = APIC_UNKNOWN_ID;
+ setprefix("[APIC?]");
+ settype(APICLOG);
+ hwreset ();
+}
+
+bx_generic_apic_c::~bx_generic_apic_c ()
+{
+}
+
+// init is called during RESET and when an INIT message is delivered.
+void bx_generic_apic_c::init ()
+{
+}
+
+void bx_generic_apic_c::set_base (Bit32u newbase)
+{
+ BX_INFO(("relocate APIC id=%d to %8x\n", id, newbase));
+ base_addr = newbase;
+}
+
+void bx_generic_apic_c::set_id (Bit8u newid) {
+ // update apic_index
+ if (id != APIC_UNKNOWN_ID) {
+ BX_ASSERT (id < APIC_MAX_ID);
+ if (apic_index[id] != this)
+ BX_PANIC(("inconsistent APIC id table\n"));
+ apic_index[id] = NULL;
+ }
+ id = newid;
+ if (apic_index[id] != NULL)
+ BX_PANIC(("duplicate APIC id assigned\n"));
+ apic_index[id] = this;
+}
+
+char *
+bx_generic_apic_c::get_name () {
+ BX_PANIC(("get_name called on bx_generic_apic_c base class\n"));
+ return NULL;
+}
+
+Boolean
+bx_generic_apic_c::is_selected (Bit32u addr, Bit32u len)
+{
+ if ((addr & ~0xfff) == get_base ()) {
+ if ((addr & 0xf != 0) || (len != 4))
+ BX_INFO(("warning: misaligned or wrong-size APIC write\n"));
+ return true;
+ }
+ return false;
+}
+
+void
+bx_generic_apic_c::read (Bit32u addr, void *data, unsigned len)
+{
+ if ((addr & ~0xf) != ((addr+len-1) & ~0xf))
+ BX_PANIC(("APIC read spans 32-bit boundary\n"));
+ Bit32u value;
+ read_aligned (addr, &value, 4);
+ if ((addr&3) == 0) {
+ *((Bit32u *)data) = value;
+ return;
+ }
+ // handle partial word read, independent of endian-ness.
+ Bit8u bytes[4];
+ bytes[0] = value & 0xff;
+ bytes[1] = (value >> 8) & 0xff;
+ bytes[2] = (value >> 16) & 0xff;
+ bytes[3] = (value >> 24) & 0xff;
+ Bit8u *p1 = bytes+(addr&3);
+ Bit8u *p2 = (Bit8u *)data;
+ for (int i=0; i<len; i++) {
+ if (bx_dbg.apic)
+ BX_INFO(("apic: Copying byte %02x\n", (unsigned int) *p1));
+ *p2++ = *p1++;
+ }
+}
+
+void bx_generic_apic_c::read_aligned (Bit32u address, Bit32u *data, unsigned len)
+{
+ BX_PANIC(("read_aligned not implemented in base class bx_generic_apic_c\n"));
+}
+
+void bx_generic_apic_c::write(Bit32u address, Bit32u *value, unsigned len)
+{
+ BX_PANIC(("write not implemented in base class bx_generic_apic_c\n"));
+}
+
+void bx_generic_apic_c::startup_msg (Bit32u vector)
+{
+ BX_PANIC(("startup message sent to an I/O APIC\n"));
+}
+
+void bx_generic_apic_c::trigger_irq (unsigned num, unsigned from)
+{
+ BX_PANIC(("trigger_irq called on base class\n"));
+}
+
+void bx_generic_apic_c::untrigger_irq (unsigned num, unsigned from)
+{
+ BX_PANIC(("untrigger_irq called on base class\n"));
+}
+
+Boolean bx_generic_apic_c::match_logical_addr (Bit8u address) {
+ BX_PANIC(("match_logical_addr called on base class\n"));
+ return false;
+}
+
+bx_apic_type_t bx_generic_apic_c::get_type () {
+ BX_PANIC(("get_type called on base class"));
+ return APIC_TYPE_NONE;
+}
+
+Bit32u
+bx_generic_apic_c::get_delivery_bitmask (Bit8u dest, Bit8u dest_mode)
+{
+ int mask = 0;
+ if (dest_mode == 0) {
+ // physical
+ if (dest < APIC_MAX_ID)
+ mask = 1<<dest;
+ else if (dest == 0xff) {
+ // physical destination 0xff means everybody. only local APICs can
+ // send this.
+ BX_ASSERT (get_type () == APIC_TYPE_LOCAL_APIC);
+ mask = 0xff;
+ } else BX_PANIC(("bx_generic_apic_c::deliver: illegal physical destination %02x\n", dest));
+ } else {
+ // logical destination. call match_logical_addr for each APIC.
+ if (dest == 0) return 0;
+ for (int i=0; i<APIC_MAX_ID; i++) {
+ if (apic_index[i] && apic_index[i]->match_logical_addr(dest))
+ mask |= (1<<i);
+ }
+ }
+ if (bx_dbg.apic)
+ BX_INFO(("generic::get_delivery_bitmask returning 0x%04x\n", mask));
+ return mask;
+}
+
+Boolean
+bx_generic_apic_c::deliver (Bit8u dest, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode)
+{
+ // return false if we can't deliver for any reason, so that the caller
+ // knows not to clear its IRR.
+ Bit32u deliver_bitmask = get_delivery_bitmask (dest, dest_mode);
+ // mask must include ONLY local APICs, or we will have problems.
+ if (!deliver_bitmask) {
+ if (bx_dbg.apic)
+ BX_INFO(("deliver failed: no APICs in destination bitmask\n"));
+ return false;
+ }
+ switch (delivery_mode) {
+ case 0: // fixed
+ break;
+ case 1: // lowest priority of destinations
+ {
+ // find lowest priority of apics in the mask
+ int lowest_priority = 0x100, lowest_mask = -1;
+ for (int bit=0; bit<APIC_MAX_ID; bit++) {
+ if (deliver_bitmask & (1<<bit)) {
+ bx_local_apic_c *apic = (bx_local_apic_c *)apic_index[bit];
+ if (apic->get_ppr () < lowest_priority) {
+ lowest_priority = apic->get_ppr (); lowest_mask = 1<<bit;
+ }
+ }
+ }
+ deliver_bitmask = lowest_mask;
+ BX_ASSERT (deliver_bitmask >= 0);
+ }
+ break;
+ case 5: // INIT
+ {
+ for (int bit=0; bit<APIC_MAX_ID; bit++) {
+ if (deliver_bitmask & (1<<bit))
+ apic_index[bit]->init ();
+ }
+ }
+ return true;
+ case 6: // Start Up (local apic only)
+ BX_ASSERT (get_type () == APIC_TYPE_LOCAL_APIC);
+ for (int bit=0; bit<APIC_MAX_ID; bit++)
+ if (deliver_bitmask & (1<<bit))
+ apic_index[bit]->startup_msg (vector);
+ return true;
+ case 2: // SMI
+ case 3: // reserved
+ case 4: // NMI
+ case 7: // ExtINT (I/O apic only)
+ default:
+ BX_PANIC(("APIC delivery mode %d not implemented\n", delivery_mode));
+ }
+ // Fixed delivery mode
+ if (bx_dbg.apic)
+ BX_INFO(("delivering vector=0x%02x to bitmask=%04x\n", (int)vector, deliver_bitmask));
+ for (int bit=0; bit<APIC_MAX_ID; bit++) {
+ if (deliver_bitmask & (1<<bit)) {
+ if (apic_index[bit] == NULL)
+ BX_INFO(("IOAPIC: delivering int0x%x to nonexistent id=%d!\n", (unsigned)vector, bit));
+ else {
+ if (bx_dbg.apic)
+ BX_INFO(("IOAPIC: delivering int0x%x to apic#%d\n", (unsigned)vector, bit));
+ apic_index[bit]->trigger_irq (vector, id);
+ }
+ }
+ }
+ return true;
+}
+
+bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu)
+ : bx_generic_apic_c ()
+{
+ char buffer[16];
+ cpu = mycpu;
+ hwreset ();
+}
+
+void
+bx_local_apic_c::hwreset ()
+{
+ /* same as INIT but also sets arbitration ID and APIC ID */
+ init ();
+ /* since id is set explicitly by the function that creates the CPU
+ object, do not mess around with it */
+ // id = APIC_UNKNOWN_ID;
+ arb_id = id;
+}
+
+void
+bx_local_apic_c::init ()
+{
+ bx_generic_apic_c::init ();
+ BX_INFO(("local apic in %s initializing\n",
+ (cpu && cpu->name) ? cpu->name : "?"));
+ // default address for a local APIC, can be moved
+ base_addr = 0xfee00000;
+ err_status = 0;
+ log_dest = 0;
+ dest_format = 0xff;
+ for (int bit=0; bit<BX_LOCAL_APIC_MAX_INTS; bit++) {
+ irr[bit] = isr[bit] = tmr[bit] = 0;
+ }
+ icr_high = icr_low = log_dest = task_priority = 0;
+ spurious_vec = 0xff; // software disabled (bit 8)
+}
+
+BX_CPU_C
+*bx_local_apic_c::get_cpu (Bit8u id)
+{
+ BX_ASSERT (id < APIC_MAX_ID);
+ return cpu;
+}
+
+bx_local_apic_c::~bx_local_apic_c(void)
+{
+ // nothing for now
+}
+
+void bx_local_apic_c::set_id (Bit8u newid) {
+ bx_generic_apic_c::set_id (newid);
+ sprintf (cpu->name, "CPU apicid=%02x", (Bit32u)id);
+ if (id >= 0 && id <= 15) {
+ char buffer[16];
+ sprintf (buffer, "[APIC%x]", id);
+ setprefix(buffer);
+ settype(CPU0LOG + id);
+ sprintf (buffer, "[CPU%x]", id);
+ cpu->setprefix (buffer);
+ } else {
+ BX_INFO (("naming convention for apics requires id=0-15 only"));
+ }
+ if(BX_CPU_LEVEL<2)
+ BX_INFO(( "8086\n" ));
+ else
+ BX_INFO(( "80%d86\n", BX_CPU_LEVEL ));
+}
+
+char *
+bx_local_apic_c::get_name()
+{
+ return cpu->name;
+}
+
+void bx_local_apic_c::set_divide_configuration (Bit32u value) {
+ BX_ASSERT (value == (value & 0x0b));
+ // move bit 3 down to bit 0.
+ value = ((value & 8) >> 1) | (value & 3);
+ BX_ASSERT (value >= 0 && value <= 7);
+ timer_divide_factor = (value==7)? 1 : (2 << value);
+ if (bx_dbg.apic)
+ BX_INFO(("%s: set timer divide factor to %d\n", cpu->name, timer_divide_factor));
+}
+
+void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len)
+{
+ assert (len == 4);
+ if (bx_dbg.apic)
+ BX_INFO(("%s: write %08x to APIC address %08x\n", cpu->name, *data, addr));
+ //assert (!(addr & 0xf));
+ addr &= 0xff0;
+ switch (addr) {
+ case 0x20: // local APIC id
+ id = ((*data)>>24) & 0xf;
+ break;
+ case 0x80: // task priority
+ task_priority = *data & 0xff;
+ break;
+ case 0xb0: // EOI
+ {
+ if (bx_dbg.apic)
+ BX_INFO(("%s: Wrote 0x%04x to EOI\n", cpu->name, *data));
+ int vec = highest_priority_int (isr);
+ if (vec < 0) {
+ BX_INFO(("EOI written without any bit in ISR\n"));
+ } else {
+ if (bx_dbg.apic)
+ BX_INFO(("%s: local apic received EOI, hopefully for vector 0x%02x\n", cpu->name, vec));
+ isr[vec] = 0;
+ service_local_apic ();
+ }
+ if (bx_dbg.apic)
+ print_status ();
+ }
+ break;
+ case 0xd0: // logical destination
+ log_dest = (*data >> 24) & 0xff;
+ break;
+ case 0xe0: // destination format
+ dest_format = (*data >> 28) & 0xf;
+ break;
+ case 0xf0: // spurious interrupt vector
+ spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0);
+ break;
+ case 0x280: // error status reg
+ // Here's what the IA-devguide-3 says on p.7-45:
+ // The ESR is a read/write register and is reset after being written to
+ // by the processor. A write to the ESR must be done just prior to
+ // reading the ESR to allow the register to be updated.
+ // This doesn't seem clear. If the write clears the register, then
+ // wouldn't you always read zero? Otherwise, what does the write do?
+ err_status = 0;
+ break;
+ case 0x300: // interrupt command reg 0-31
+ {
+ icr_low = *data & ~(1<<12); // force delivery status bit = 0 (idle)
+ int dest = (icr_high >> 24) & 0xff;
+ int trig_mode = (icr_low >> 15) & 1;
+ int level = (icr_low >> 14) & 1;
+ int dest_mode = (icr_low >> 11) & 1;
+ int delivery_mode = (icr_low >> 8) & 7;
+ int vector = (icr_low & 0xff);
+ //
+ // deliver will call get_delivery_bitmask to decide who to send to.
+ // This local_apic class redefines get_delivery_bitmask to
+ // implement the destination shorthand field, which doesn't exist
+ // for all APICs.
+ Boolean accepted =
+ deliver (dest, dest_mode, delivery_mode, vector, level, trig_mode);
+ if (!accepted)
+ err_status |= APIC_ERR_TX_ACCEPT_ERR;
+ }
+ break;
+ case 0x310: // interrupt command reg 31-63
+ icr_high = *data & 0xff000000;
+ break;
+ case 0x320: // LVT Timer Reg
+ lvt[APIC_LVT_TIMER] = *data & 0x310ff;
+ break;
+ case 0x330: // LVT Thermal Monitor
+ lvt[APIC_LVT_THERMAL] = *data & 0x117ff;
+ break;
+ case 0x340: // LVT Performance Counter
+ lvt[APIC_LVT_PERFORM] = *data & 0x117ff;
+ break;
+ case 0x350: // LVT LINT0 Reg
+ lvt[APIC_LVT_LINT0] = *data & 0x1f7ff;
+ break;
+ case 0x360: // LVT Lint1 Reg
+ lvt[APIC_LVT_LINT1] = *data & 0x1f7ff;
+ break;
+ case 0x370: // LVT Error Reg
+ lvt[APIC_LVT_ERROR] = *data & 0x117ff;
+ break;
+ case 0x380: // initial count for timer
+ timer_initial = *data;
+ // This should trigger the counter to start. If already started,
+ // restart from the new start value.
+ timer_current = timer_initial;
+ timer_active = true;
+ timer_divide_counter = 0;
+ break;
+ case 0x3e0: // timer divide configuration
+ // only bits 3, 1, and 0 are writable
+ timer_divconf = *data & 0xb;
+ set_divide_configuration (timer_divconf);
+ break;
+ /* all read-only registers go here */
+ case 0x30: // local APIC version
+ case 0x90: // arbitration priority
+ case 0xa0: // processor priority
+ // ISRs not writable
+ case 0x100: case 0x110: case 0x120: case 0x130:
+ case 0x140: case 0x150: case 0x160: case 0x170:
+ // TMRs not writable
+ case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+ case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+ // IRRs not writable
+ case 0x200: case 0x210: case 0x220: case 0x230:
+ case 0x240: case 0x250: case 0x260: case 0x270:
+ // current count for timer
+ case 0x390:
+ // all read-only registers should fall into this line
+ BX_INFO(("warning: write to read-only APIC register 0x%02x\n", addr));
+ break;
+ default:
+ err_status |= APIC_ERR_ILLEGAL_ADDR;
+ // but for now I want to know about it in case I missed some.
+ BX_PANIC(("APIC register %08x not implemented\n", addr));
+ }
+}
+
+void bx_local_apic_c::startup_msg (Bit32u vector)
+{
+ if (cpu->debug_trap & 0x80000000) {
+ cpu->debug_trap &= ~0x80000000;
+ cpu->eip = 0;
+ cpu->load_seg_reg (&cpu->sregs[BX_SEG_REG_CS], vector*0x100);
+ BX_INFO(("%s started up at 0x%x by APIC\n", cpu->name, cpu->eip));
+ } else {
+ BX_INFO(("%s started up by APIC, but was not halted at the time\n", cpu->name));
+ }
+}
+
+void bx_local_apic_c::read_aligned (Bit32u addr, Bit32u *data, unsigned len)
+{
+ assert (len == 4);
+ *data = 0; // default value for unimplemented registers
+ Bit32u addr2 = addr & 0xff0;
+ switch (addr2) {
+ case 0x20: // local APIC id
+ *data = (id) << 24; break;
+ case 0x30: // local APIC version
+ *data = 0x00170011; break;
+ case 0x80: // task priority
+ *data = task_priority & 0xff; break;
+ case 0x90: // arbitration priority
+ *data = get_apr (); break;
+ case 0xa0: // processor priority
+ *data = get_ppr (); break;
+ case 0xb0: // EOI
+ BX_PANIC(("EOI register not writable\n"));
+ break;
+ case 0xd0: // logical destination
+ *data = (log_dest & 0xff) << 24; break;
+ case 0xe0: // destination format
+ *data = ((dest_format & 0xf) << 24) | 0x0fffffff; break;
+ case 0xf0: // spurious interrupt vector
+ *data = spurious_vec; break;
+ // ISRs not writable
+ case 0x100: case 0x110: case 0x120: case 0x130:
+ case 0x140: case 0x150: case 0x160: case 0x170:
+ case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+ case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+ case 0x200: case 0x210: case 0x220: case 0x230:
+ case 0x240: case 0x250: case 0x260: case 0x270:
+ *data = 0;
+ BX_INFO(("reading ISR,TMR,IRR not implemented\n"));
+ break;
+ case 0x280: // error status reg
+ *data = err_status; break;
+ case 0x300: // interrupt command reg 0-31
+ *data = icr_low; break;
+ case 0x310: // interrupt command reg 31-63
+ *data = icr_high; break;
+ case 0x320: // LVT Timer Reg
+ case 0x330: // LVT Thermal Monitor
+ case 0x340: // LVT Performance Counter
+ case 0x350: // LVT LINT0 Reg
+ case 0x360: // LVT Lint1 Reg
+ case 0x370: // LVT Error Reg
+ {
+ int index = (addr2 - 0x320) >> 4;
+ *data = lvt[index];
+ break;
+ }
+ case 0x380: // initial count for timer
+ *data = timer_initial; break;
+ case 0x390: // current count for timer
+ *data = timer_current; break;
+ case 0x3e0: // timer divide configuration
+ *data = timer_divconf; break;
+ default:
+ BX_INFO(("APIC register %08x not implemented\n", addr));
+ }
+ if (bx_dbg.apic)
+ BX_INFO(("%s: read from APIC address %08x = %08x\n", cpu->name, addr, *data));
+}
+
+int
+bx_local_apic_c::highest_priority_int (Bit8u *array)
+{
+ for (int i=0; i<BX_LOCAL_APIC_MAX_INTS; i++)
+ if (array[i]) return i;
+ return -1;
+}
+
+void bx_local_apic_c::service_local_apic ()
+{
+ if (bx_dbg.apic) {
+ BX_INFO(("service_local_apic()\n"));
+ print_status ();
+ }
+ if (cpu->INTR) return; // INTR already up; do nothing
+ // find first interrupt in irr.
+ int first_irr = highest_priority_int (irr);
+ int first_isr = highest_priority_int (isr);
+ if (first_irr < 0) return; // no interrupts, leave INTR=0
+ if (first_isr >= 0 && first_irr >= first_isr) {
+ if (bx_dbg.apic)
+ BX_INFO(("local apic (%s): not delivering int%02x because int%02x is in service\n", cpu->name, first_irr, first_isr));
+ return;
+ }
+ // interrupt has appeared in irr. raise INTR. When the CPU
+ // acknowledges, we will run highest_priority_int again and
+ // return it.
+ if (bx_dbg.apic)
+ BX_INFO(("service_local_apic(): setting INTR=1 for vector 0x%02x\n", first_irr));
+ cpu->set_INTR (1);
+ cpu->int_from_local_apic = 1;
+}
+
+void bx_local_apic_c::trigger_irq (unsigned vector, unsigned from)
+{
+ if (bx_dbg.apic)
+ BX_INFO(("Local apic on %s: trigger interrupt vector=0x%x\n", cpu->name, vector));
+ irr[vector] = 1;
+ service_local_apic ();
+}
+
+void bx_local_apic_c::untrigger_irq (unsigned vector, unsigned from)
+{
+ if (bx_dbg.apic)
+ BX_INFO(("Local apic on %s: untrigger interrupt vector=0x%x\n", cpu->name, vector));
+ // hardware says "no more". clear the bit. If the CPU hasn't yet
+ // acknowledged the interrupt, it will never be serviced.
+ BX_ASSERT (irr[vector] == 1);
+ irr[vector] = 0;
+ if (bx_dbg.apic) print_status ();
+}
+
+Bit8u
+bx_local_apic_c::acknowledge_int ()
+{
+ // CPU calls this when it is ready to service one interrupt
+ if (!cpu->INTR)
+ BX_PANIC(("%s: acknowledged an interrupt, but INTR=0\n", cpu->name));
+ BX_ASSERT (cpu->int_from_local_apic);
+ int vector = highest_priority_int (irr);
+ BX_ASSERT (irr[vector] == 1);
+ if (bx_dbg.apic)
+ BX_INFO(("%s: acknowledge_int returning vector 0x%x\n", cpu->name, vector));
+ // currently isr never gets cleared, so no point
+ //BX_ASSERT (isr[vector] == 0);
+ irr[vector] = 0;
+ isr[vector] = 1;
+ if (bx_dbg.apic) {
+ BX_INFO(("Status after setting isr:\n"));
+ print_status ();
+ }
+ cpu->INTR = 0;
+ cpu->int_from_local_apic = 0;
+ service_local_apic (); // will set INTR again if another is ready
+ return vector;
+}
+
+void bx_local_apic_c::print_status () {
+ BX_INFO(("%s local apic: status is {:\n", cpu->name));
+ for (int vec=0; vec<BX_LOCAL_APIC_MAX_INTS; vec++) {
+ if (irr[vec] || isr[vec]) {
+ BX_INFO(("vec 0x%x: irr=%d, isr=%d\n", vec, (int)irr[vec], (int)isr[vec]));
+ }
+ }
+ BX_INFO(("}\n", cpu->name));
+}
+
+Boolean bx_local_apic_c::match_logical_addr (Bit8u address)
+{
+ if (dest_format != 0xf) {
+ BX_PANIC(("bx_local_apic_c::match_logical_addr: cluster model addressing not implemented"));
+ }
+ // if all address bits are 1, send to all local APICs. SDG3:7-27.
+ if (address == 0xff) {
+ if (bx_dbg.apic) BX_INFO(("%s: MDA=0xff matches everybody\n", cpu->name));
+ return true;
+ }
+ Boolean match = ((address & log_dest) != 0);
+ if (bx_dbg.apic) {
+ BX_INFO(("%s: comparing MDA %02x to my LDR %02x -> %s\n", cpu->name,
+ address, log_dest, match? "Match" : "Not a match"));
+ }
+ return match;
+}
+
+Bit32u
+bx_local_apic_c::get_delivery_bitmask (Bit8u dest, Bit8u dest_mode)
+{
+ int dest_shorthand = (icr_low >> 18) & 3;
+ Bit32u all_mask = (1<<APIC_MAX_ID) - 1;
+ Bit32u mask;
+ switch (dest_shorthand) {
+ case 0: // no shorthand, use real destination value
+ return bx_generic_apic_c::get_delivery_bitmask (dest, dest_mode);
+ case 1: // self
+ return (1<<id);
+ case 2: // all including self
+ mask = all_mask;
+ case 3: // all but self
+ mask = all_mask & ~(1<<id);
+ }
+ // prune nonexistents and I/O apics from list
+ for (int bit=0; bit<APIC_MAX_ID; bit++) {
+ if (!apic_index[bit]
+ || (apic_index[bit]->get_type () != APIC_TYPE_LOCAL_APIC))
+ mask &= ~(1<<bit);
+ }
+ if (bx_dbg.apic)
+ BX_INFO(("local::get_delivery_bitmask returning 0x%04x\n", mask));
+ return mask;
+}
+
+Bit8u bx_local_apic_c::get_ppr ()
+{
+ if (bx_dbg.apic)
+ BX_INFO(("WARNING: Local APIC Processor Priority not implemented, returning 0\n"));
+ // should look at TPR, vector of highest priority isr, etc.
+ return 0;
+}
+
+
+Bit8u bx_local_apic_c::get_apr ()
+{
+ if (bx_dbg.apic)
+ BX_INFO(("WARNING: Local APIC Arbitration Priority not implemented, returning 0\n"));
+ // should look at TPR, vector of highest priority isr, etc.
+ return 0;
+}
+
+
+void
+bx_local_apic_c::periodic (Bit32u usec_delta)
+{
+ if (!timer_active) return;
+ if (bx_dbg.apic)
+ BX_INFO(("%s: bx_local_apic_c::periodic called with %d usec\n",
+ cpu->name, usec_delta));
+ // unless usec_delta is guaranteed to be a multiple of 128, I can't
+ // just divide usec_delta by the divide-down value. Instead, it will
+ // have a similar effect to implement the divide-down by ignoring
+ // some fraction of calls to this function. This can be improved if
+ // more granularity is important.
+ timer_divide_counter = (timer_divide_counter + 1) % timer_divide_factor;
+ if (timer_divide_counter != 0) return;
+ if (timer_current > usec_delta) {
+ timer_current -= usec_delta;
+ //BX_INFO(("%s: local apic timer is now 0x%08x\n", cpu->name, timer_current));
+ return;
+ }
+ // timer reached zero since the last call to periodic.
+ Bit32u timervec = lvt[APIC_LVT_TIMER];
+ if (timervec & 0x20000) {
+ // periodic mode. Always trigger the interrupt when we reach zero.
+ trigger_irq (timervec & 0xff, id);
+ if (timer_initial == 0) {
+ usec_delta = 0;
+ timer_current = 0;
+ } else {
+ // timer_initial might be smaller than usec_delta. I can't trigger
+ // multiple interrupts, so just try to get the timer_current right.
+ while (usec_delta > timer_initial)
+ usec_delta -= timer_initial;
+ timer_current = timer_current + timer_initial - usec_delta;
+ // sanity check. all these are unsigned so I can't check for
+ // negative timer_current.
+ BX_ASSERT ((timer_current + timer_initial) >= usec_delta);
+ }
+ if (bx_dbg.apic)
+ BX_INFO(("%s: local apic timer (periodic) triggered int, reset counter to 0x%08x\n", cpu->name, timer_current));
+ } else {
+ // one-shot mode
+ timer_current = 0;
+ if (timer_active) {
+ trigger_irq (timervec & 0xff, id);
+ timer_active = false;
+ if (bx_dbg.apic)
+ BX_INFO(("%s: local apic timer (one-shot) triggered int\n", cpu->name));
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::INC_RX(BxInstruction_t *i)
+{
+ Bit16u rx;
+
+ rx = ++ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+ SET_FLAGS_OSZAP_16(0, 0, rx, BX_INSTR_INC16);
+}
+
+ void
+BX_CPU_C::DEC_RX(BxInstruction_t *i)
+{
+ Bit16u rx;
+
+ rx = -- BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+ SET_FLAGS_OSZAP_16(0, 0, rx, BX_INSTR_DEC16);
+}
+
+
+ void
+BX_CPU_C::ADD_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, sum_16;
+
+
+ /* op2_16 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ sum_16 = op1_16 + op2_16;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, sum_16);
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &sum_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+
+ void
+BX_CPU_C::ADD_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, sum_16;
+
+
+ /* op1_16 is a register, i->rm_addr is an index of a register */
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ sum_16 = op1_16 + op2_16;
+ /* now write sum back to destination */
+
+ BX_WRITE_16BIT_REG(i->nnn, sum_16);
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+
+ void
+BX_CPU_C::ADD_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, sum_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ sum_16 = op1_16 + op2_16;
+
+ /* now write sum back to destination */
+ AX = sum_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+ void
+BX_CPU_C::ADC_EwGw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op2_16, op1_16, sum_16;
+
+ temp_CF = get_CF();
+
+
+
+
+ /* op2_16 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ sum_16 = op1_16 + op2_16 + temp_CF;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, sum_16);
+ }
+ else {
+ write_RMW_virtual_word(sum_16);
+ }
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::ADC_GwEw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op1_16, op2_16, sum_16;
+
+ temp_CF = get_CF();
+
+
+ /* op1_16 is a register, i->rm_addr is an index of a register */
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ sum_16 = op1_16 + op2_16 + temp_CF;
+
+ /* now write sum back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, sum_16);
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::ADC_AXIw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op1_16, op2_16, sum_16;
+
+ temp_CF = get_CF();
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ sum_16 = op1_16 + op2_16 + temp_CF;
+
+ /* now write sum back to destination */
+ AX = sum_16;
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+ temp_CF);
+}
+
+
+
+
+ void
+BX_CPU_C::SBB_EwGw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op2_16, op1_16, diff_16;
+
+
+ temp_CF = get_CF();
+
+
+ /* op2_16 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - (op2_16 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, diff_16);
+ }
+ else {
+ write_RMW_virtual_word(diff_16);
+ }
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_GwEw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ Bit16u op1_16, op2_16, diff_16;
+
+
+ /* op1_16 is a register, i->rm_addr is an index of a register */
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ diff_16 = op1_16 - (op2_16 + temp_CF);
+
+ /* now write diff back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, diff_16);
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_AXIw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op1_16, op2_16, diff_16;
+
+ temp_CF = get_CF();
+
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ diff_16 = op1_16 - (op2_16 + temp_CF);
+
+ /* now write diff back to destination */
+ AX = diff_16;
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+ temp_CF);
+}
+
+
+
+ void
+BX_CPU_C::SBB_EwIw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op2_16, op1_16, diff_16;
+
+ temp_CF = get_CF();
+
+
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - (op2_16 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, diff_16);
+ }
+ else {
+ write_RMW_virtual_word(diff_16);
+ }
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, diff_16, BX_INSTR_SBB16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SUB_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, diff_16;
+
+
+ /* op2_16 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, diff_16);
+ }
+ else {
+ write_RMW_virtual_word(diff_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+
+ void
+BX_CPU_C::SUB_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, diff_16;
+
+
+ /* op1_16 is a register, i->rm_addr is an index of a register */
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ /* now write diff back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, diff_16);
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+ void
+BX_CPU_C::SUB_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, diff_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ diff_16 = op1_16 - op2_16;
+
+
+ /* now write diff back to destination */
+ AX = diff_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+
+ void
+BX_CPU_C::CMP_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, diff_16;
+
+
+ /* op2_16 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+ void
+BX_CPU_C::CMP_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, diff_16;
+
+
+ /* op1_16 is a register, i->rm_addr is an index of a register */
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+ void
+BX_CPU_C::CMP_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, diff_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+ void
+BX_CPU_C::CBW(BxInstruction_t *i)
+{
+ /* CBW: no flags are effected */
+
+ AX = (Bit8s) AL;
+}
+
+ void
+BX_CPU_C::CWD(BxInstruction_t *i)
+{
+ /* CWD: no flags are affected */
+
+ if (AX & 0x8000) {
+ DX = 0xFFFF;
+ }
+ else {
+ DX = 0x0000;
+ }
+}
+
+
+ void
+BX_CPU_C::XADD_EwGw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit16u op2_16, op1_16, sum_16;
+
+ /* XADD dst(r/m), src(r)
+ * temp <-- src + dst | sum = op2 + op1
+ * src <-- dst | op2 = op1
+ * dst <-- tmp | op1 = sum
+ */
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ sum_16 = op1_16 + op2_16;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ // and write destination into source
+ // Note: if both op1 & op2 are registers, the last one written
+ // should be the sum, as op1 & op2 may be the same register.
+ // For example: XADD AL, AL
+ BX_WRITE_16BIT_REG(i->nnn, op1_16);
+ BX_WRITE_16BIT_REG(i->rm, sum_16);
+ }
+ else {
+ write_RMW_virtual_word(sum_16);
+ /* and write destination into source */
+ BX_WRITE_16BIT_REG(i->nnn, op1_16);
+ }
+
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XADD16);
+#else
+ BX_PANIC(("XADD_EvGv: not supported on < 80486\n"));
+#endif
+}
+
+
+
+ void
+BX_CPU_C::ADD_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, sum_16;
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ sum_16 = op1_16 + op2_16;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, sum_16);
+ }
+ else {
+ write_RMW_virtual_word(sum_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_ADD16);
+}
+
+ void
+BX_CPU_C::ADC_EwIw(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+ Bit16u op2_16, op1_16, sum_16;
+
+ temp_CF = get_CF();
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ sum_16 = op1_16 + op2_16 + temp_CF;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, sum_16);
+ }
+ else {
+ write_RMW_virtual_word(sum_16);
+ }
+
+ SET_FLAGS_OSZAPC_16_CF(op1_16, op2_16, sum_16, BX_INSTR_ADC16,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SUB_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, diff_16;
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, diff_16);
+ }
+ else {
+ write_RMW_virtual_word(diff_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SUB16);
+}
+
+ void
+BX_CPU_C::CMP_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, diff_16;
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMP16);
+}
+
+
+
+ void
+BX_CPU_C::NEG_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, diff_16;
+
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = 0 - op1_16;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, diff_16);
+ }
+ else {
+ write_RMW_virtual_word(diff_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, 0, diff_16, BX_INSTR_NEG16);
+}
+
+
+ void
+BX_CPU_C::INC_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ op1_16++;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+
+ SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_INC16);
+}
+
+
+ void
+BX_CPU_C::DEC_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ op1_16--;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+
+ SET_FLAGS_OSZAP_16(0, 0, op1_16, BX_INSTR_DEC16);
+}
+
+
+ void
+BX_CPU_C::CMPXCHG_EwGw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit16u op2_16, op1_16, diff_16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ diff_16 = AX - op1_16;
+
+ SET_FLAGS_OSZAPC_16(AX, op1_16, diff_16, BX_INSTR_CMP16);
+
+ if (diff_16 == 0) { // if accumulator == dest
+ // ZF = 1
+ set_ZF(1);
+ // dest <-- src
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op2_16);
+ }
+ else {
+ write_RMW_virtual_word(op2_16);
+ }
+ }
+ else {
+ // ZF = 0
+ set_ZF(0);
+ // accumulator <-- dest
+ AX = op1_16;
+ }
+
+#else
+ BX_PANIC(("CMPXCHG_EwGw:\n"));
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::INC_ERX(BxInstruction_t *i)
+{
+ Bit32u erx;
+
+ erx = ++ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+ SET_FLAGS_OSZAP_32(0, 0, erx, BX_INSTR_INC32);
+}
+
+ void
+BX_CPU_C::DEC_ERX(BxInstruction_t *i)
+{
+ Bit32u erx;
+
+ erx = -- BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+ SET_FLAGS_OSZAP_32(0, 0, erx, BX_INSTR_DEC32);
+}
+
+
+
+
+ void
+BX_CPU_C::ADD_EdGd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, sum_32;
+
+ /* op2_32 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ sum_32 = op1_32 + op2_32;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, sum_32);
+ }
+ else {
+ write_RMW_virtual_dword(sum_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+
+ void
+BX_CPU_C::ADD_GdEd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, sum_32;
+
+ /* op1_32 is a register, i->rm_addr is an index of a register */
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ sum_32 = op1_32 + op2_32;
+
+ /* now write sum back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, sum_32);
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+
+ void
+BX_CPU_C::ADD_EAXId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, sum_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ sum_32 = op1_32 + op2_32;
+
+ /* now write sum back to destination */
+ EAX = sum_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+ void
+BX_CPU_C::ADC_EdGd(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, sum_32;
+
+ /* op2_32 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ sum_32 = op1_32 + op2_32 + temp_CF;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, sum_32);
+ }
+ else {
+ write_RMW_virtual_dword(sum_32);
+ }
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::ADC_GdEd(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, sum_32;
+
+ /* op1_32 is a register, i->rm_addr is an index of a register */
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ sum_32 = op1_32 + op2_32 + temp_CF;
+
+ /* now write sum back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, sum_32);
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::ADC_EAXId(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, sum_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ sum_32 = op1_32 + op2_32 + temp_CF;
+
+ /* now write sum back to destination */
+ EAX = sum_32;
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+ temp_CF);
+}
+
+
+
+
+ void
+BX_CPU_C::SBB_EdGd(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ /* op2_32 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - (op2_32 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, diff_32);
+ }
+ else {
+ write_RMW_virtual_dword(diff_32);
+ }
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_GdEd(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ /* op1_32 is a register, i->rm_addr is an index of a register */
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ diff_32 = op1_32 - (op2_32 + temp_CF);
+
+ /* now write diff back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, diff_32);
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_EAXId(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ diff_32 = op1_32 - (op2_32 + temp_CF);
+
+ /* now write diff back to destination */
+ EAX = diff_32;
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+ temp_CF);
+}
+
+
+
+ void
+BX_CPU_C::SBB_EdId(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - (op2_32 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, diff_32);
+ }
+ else {
+ write_RMW_virtual_dword(diff_32);
+ }
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, diff_32, BX_INSTR_SBB32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SUB_EdGd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ /* op2_32 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, diff_32);
+ }
+ else {
+ write_RMW_virtual_dword(diff_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+
+ void
+BX_CPU_C::SUB_GdEd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ /* op1_32 is a register, i->rm_addr is an index of a register */
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ /* now write diff back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, diff_32);
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+ void
+BX_CPU_C::SUB_EAXId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ diff_32 = op1_32 - op2_32;
+
+ /* now write diff back to destination */
+ EAX = diff_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+
+ void
+BX_CPU_C::CMP_EdGd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ /* op2_32 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+ void
+BX_CPU_C::CMP_GdEd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ /* op1_32 is a register, i->rm_addr is an index of a register */
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+ void
+BX_CPU_C::CMP_EAXId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, diff_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+ void
+BX_CPU_C::CWDE(BxInstruction_t *i)
+{
+ /* CBW: no flags are effected */
+
+ EAX = (Bit16s) AX;
+}
+
+ void
+BX_CPU_C::CDQ(BxInstruction_t *i)
+{
+ /* CWD: no flags are affected */
+
+ if (EAX & 0x80000000) {
+ EDX = 0xFFFFFFFF;
+ }
+ else {
+ EDX = 0x00000000;
+ }
+}
+
+// Some info on the opcodes at {0F,A6} and {0F,A7}
+// On 386 steps A0-B0:
+// {OF,A6} = XBTS
+// {OF,A7} = IBTS
+// On 486 steps A0-B0:
+// {OF,A6} = CMPXCHG 8
+// {OF,A7} = CMPXCHG 16|32
+//
+// On 486 >= B steps, and further processors, the
+// CMPXCHG instructions were moved to opcodes:
+// {OF,B0} = CMPXCHG 8
+// {OF,B1} = CMPXCHG 16|32
+
+ void
+BX_CPU_C::CMPXCHG_XBTS(BxInstruction_t *i)
+{
+ BX_INFO(("CMPXCHG_XBTS:\n"));
+ UndefinedOpcode(i);
+}
+
+ void
+BX_CPU_C::CMPXCHG_IBTS(BxInstruction_t *i)
+{
+ BX_INFO(("CMPXCHG_IBTS:\n"));
+ UndefinedOpcode(i);
+}
+
+
+ void
+BX_CPU_C::XADD_EdGd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u op2_32, op1_32, sum_32;
+
+ /* XADD dst(r/m), src(r)
+ * temp <-- src + dst | sum = op2 + op1
+ * src <-- dst | op2 = op1
+ * dst <-- tmp | op1 = sum
+ */
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ sum_32 = op1_32 + op2_32;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ // and write destination into source
+ // Note: if both op1 & op2 are registers, the last one written
+ // should be the sum, as op1 & op2 may be the same register.
+ // For example: XADD AL, AL
+ BX_WRITE_32BIT_REG(i->nnn, op1_32);
+ BX_WRITE_32BIT_REG(i->rm, sum_32);
+ }
+ else {
+ write_RMW_virtual_dword(sum_32);
+ /* and write destination into source */
+ BX_WRITE_32BIT_REG(i->nnn, op1_32);
+ }
+
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XADD32);
+#else
+ BX_PANIC(("XADD_EdGd: not supported on < 80486\n"));
+#endif
+}
+
+
+
+ void
+BX_CPU_C::ADD_EdId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, sum_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ sum_32 = op1_32 + op2_32;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, sum_32);
+ }
+ else {
+ write_RMW_virtual_dword(sum_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_ADD32);
+}
+
+ void
+BX_CPU_C::ADC_EdId(BxInstruction_t *i)
+{
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, sum_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ sum_32 = op1_32 + op2_32 + temp_CF;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, sum_32);
+ }
+ else {
+ write_RMW_virtual_dword(sum_32);
+ }
+
+ SET_FLAGS_OSZAPC_32_CF(op1_32, op2_32, sum_32, BX_INSTR_ADC32,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SUB_EdId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, diff_32);
+ }
+ else {
+ write_RMW_virtual_dword(diff_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SUB32);
+}
+
+ void
+BX_CPU_C::CMP_EdId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, diff_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMP32);
+}
+
+
+
+
+ void
+BX_CPU_C::NEG_Ed(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, diff_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = 0 - op1_32;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, diff_32);
+ }
+ else {
+ write_RMW_virtual_dword(diff_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, 0, diff_32, BX_INSTR_NEG32);
+}
+
+
+ void
+BX_CPU_C::INC_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ op1_32++;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+
+ SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_INC32);
+}
+
+
+ void
+BX_CPU_C::DEC_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ op1_32--;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+
+ SET_FLAGS_OSZAP_32(0, 0, op1_32, BX_INSTR_DEC32);
+}
+
+
+ void
+BX_CPU_C::CMPXCHG_EdGd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u op2_32, op1_32, diff_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ diff_32 = EAX - op1_32;
+
+ SET_FLAGS_OSZAPC_32(EAX, op1_32, diff_32, BX_INSTR_CMP32);
+
+ if (diff_32 == 0) { // if accumulator == dest
+ // ZF = 1
+ set_ZF(1);
+ // dest <-- src
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op2_32);
+ }
+ else {
+ write_RMW_virtual_dword(op2_32);
+ }
+ }
+ else {
+ // ZF = 0
+ set_ZF(0);
+ // accumulator <-- dest
+ EAX = op1_32;
+ }
+#else
+ BX_PANIC(("CMPXCHG_EdGd:\n"));
+#endif
+}
+
+ void
+BX_CPU_C::CMPXCHG8B(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 5) || (BX_CPU_LEVEL_HACKED >= 5)
+ if (i->mod != 0xc0) {
+ BX_INFO(("CMPXCHG8B: dest is reg: #UD\n"));
+ UndefinedOpcode(i);
+ }
+ BX_PANIC(("CMPXCHG8B: not implemented yet\n"));
+#else
+ BX_INFO(("CMPXCHG8B: not implemented yet\n"));
+ UndefinedOpcode(i);
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::ADD_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, sum;
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ sum = op1 + op2;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, sum);
+ }
+ else {
+ write_RMW_virtual_byte(sum);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+
+ void
+BX_CPU_C::ADD_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+
+
+ /* op1 is a register, i->rm_addr is an index of a register */
+ op1 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ sum = op1 + op2;
+
+ /* now write sum back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, sum);
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+ void
+BX_CPU_C::ADD_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+
+
+ op1 = AL;
+
+ op2 = i->Ib;
+
+ sum = op1 + op2;
+
+ /* now write sum back to destination, which is a register */
+ AL = sum;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+
+ void
+BX_CPU_C::ADC_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, sum;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ sum = op1 + op2 + temp_CF;
+
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, sum);
+ }
+ else {
+ write_RMW_virtual_byte(sum);
+ }
+
+ SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8, temp_CF);
+}
+
+
+ void
+BX_CPU_C::ADC_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* op1 is a register, i->rm_addr is an index of a register */
+ op1 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ sum = op1 + op2 + temp_CF;
+
+ SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+ temp_CF);
+
+ /* now write sum back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, sum);
+}
+
+
+ void
+BX_CPU_C::ADC_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ op1 = AL;
+
+ op2 = i->Ib;
+
+ sum = op1 + op2 + temp_CF;
+
+ /* now write sum back to destination, which is a register */
+ AL = sum;
+
+ SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - (op2_8 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, diff_8);
+ }
+ else {
+ write_RMW_virtual_byte(diff_8);
+ }
+
+ SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ /* op1 is a register, i->rm_addr is an index of a register */
+ op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ diff_8 = op1_8 - (op2_8 + temp_CF);
+
+ /* now write diff back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, diff_8);
+
+ SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+
+ op1_8 = AL;
+
+ op2_8 = i->Ib;
+
+ diff_8 = op1_8 - (op2_8 + temp_CF);
+
+ /* now write diff back to destination, which is a register */
+ AL = diff_8;
+
+ SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SBB_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+ op2_8 = i->Ib;
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - (op2_8 + temp_CF);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, diff_8);
+ }
+ else {
+ write_RMW_virtual_byte(diff_8);
+ }
+
+ SET_FLAGS_OSZAPC_8_CF(op1_8, op2_8, diff_8, BX_INSTR_SBB8,
+ temp_CF);
+}
+
+
+
+ void
+BX_CPU_C::SUB_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, diff_8);
+ }
+ else {
+ write_RMW_virtual_byte(diff_8);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+ void
+BX_CPU_C::SUB_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+
+
+ /* op1 is a register, i->rm_addr is an index of a register */
+ op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ /* now write diff back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, diff_8);
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+ void
+BX_CPU_C::SUB_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+
+ op1_8 = AL;
+
+ op2_8 = i->Ib;
+
+ diff_8 = op1_8 - op2_8;
+
+ /* now write diff back to destination, which is a register */
+ AL = diff_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+
+
+ void
+BX_CPU_C::CMP_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+ void
+BX_CPU_C::CMP_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+
+ /* op1 is a register, i->rm_addr is an index of a register */
+ op1_8 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+
+ void
+BX_CPU_C::CMP_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+
+
+ op1_8 = AL;
+
+ op2_8 = i->Ib;
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+ void
+BX_CPU_C::XADD_EbGb(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit8u op2, op1, sum;
+
+ /* XADD dst(r/m8), src(r8)
+ * temp <-- src + dst | sum = op2 + op1
+ * src <-- dst | op2 = op1
+ * dst <-- tmp | op1 = sum
+ */
+
+ /* op2 is a register, i->rm_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ sum = op1 + op2;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ // and write destination into source
+ // Note: if both op1 & op2 are registers, the last one written
+ // should be the sum, as op1 & op2 may be the same register.
+ // For example: XADD AL, AL
+ BX_WRITE_8BIT_REG(i->nnn, op1);
+ BX_WRITE_8BIT_REG(i->rm, sum);
+ }
+ else {
+ write_RMW_virtual_byte(sum);
+ /* and write destination into source */
+ BX_WRITE_8BIT_REG(i->nnn, op1);
+ }
+
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_XADD8);
+#else
+ BX_PANIC(("XADD_EbGb: not supported on < 80486\n"));
+#endif
+}
+
+
+ void
+BX_CPU_C::ADD_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, sum;
+
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ sum = op1 + op2;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, sum);
+ }
+ else {
+ write_RMW_virtual_byte(sum);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_ADD8);
+}
+
+ void
+BX_CPU_C::ADC_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, sum;
+ Boolean temp_CF;
+
+ temp_CF = get_CF();
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ sum = op1 + op2 + temp_CF;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, sum);
+ }
+ else {
+ write_RMW_virtual_byte(sum);
+ }
+
+ SET_FLAGS_OSZAPC_8_CF(op1, op2, sum, BX_INSTR_ADC8,
+ temp_CF);
+}
+
+
+ void
+BX_CPU_C::SUB_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+
+
+ op2_8 = i->Ib;
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, diff_8);
+ }
+ else {
+ write_RMW_virtual_byte(diff_8);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SUB8);
+}
+
+ void
+BX_CPU_C::CMP_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2_8, op1_8, diff_8;
+
+ op2_8 = i->Ib;
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMP8);
+}
+
+
+ void
+BX_CPU_C::NEG_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, diff_8;
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = 0 - op1_8;
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, diff_8);
+ }
+ else {
+ write_RMW_virtual_byte(diff_8);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1_8, 0, diff_8, BX_INSTR_NEG8);
+}
+
+
+ void
+BX_CPU_C::INC_Eb(BxInstruction_t *i)
+{
+ Bit8u op1;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+
+ op1++;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, op1);
+ }
+ else {
+ write_RMW_virtual_byte(op1);
+ }
+
+ SET_FLAGS_OSZAP_8(0, 0, op1, BX_INSTR_INC8);
+}
+
+
+ void
+BX_CPU_C::DEC_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8;
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ op1_8--;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, op1_8);
+ }
+ else {
+ write_RMW_virtual_byte(op1_8);
+ }
+
+ SET_FLAGS_OSZAP_8(0, 0, op1_8, BX_INSTR_DEC8);
+}
+
+
+ void
+BX_CPU_C::CMPXCHG_EbGb(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+ Bit8u op2_8, op1_8, diff_8;
+
+
+ /* op1_8 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ diff_8 = AL - op1_8;
+
+ SET_FLAGS_OSZAPC_8(AL, op1_8, diff_8, BX_INSTR_CMP8);
+
+ if (diff_8 == 0) { // if accumulator == dest
+ // ZF = 1
+ set_ZF(1);
+ // dest <-- src
+ op2_8 = BX_READ_8BIT_REG(i->nnn);
+
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, op2_8);
+ }
+ else {
+ write_RMW_virtual_byte(op2_8);
+ }
+ }
+ else {
+ // ZF = 0
+ set_ZF(0);
+ // accumulator <-- dest
+ AL = op1_8;
+ }
+
+#else
+ BX_PANIC(("CMPXCHG_EbGb:\n"));
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::DAS(BxInstruction_t *)
+{
+ Bit8u tmpCF, tmpAL;
+
+ /* ??? */
+ /* the algorithm for DAS is fashioned after the pseudo code in the
+ * Pentium Processor Family Developer's Manual, volume 3. It seems
+ * to have changed from earlier processor's manuals. I'm not sure
+ * if this is a correction in the algorithm printed, or Intel has
+ * changed the handling of instruction. It might not even be
+ * correct yet...
+ */
+
+ tmpCF = 0;
+ tmpAL = AL;
+
+ /* DAS effect the following flags: A,C,S,Z,P */
+
+ if (((tmpAL & 0x0F) > 0x09) || get_AF()) {
+ set_AF(1);
+ tmpCF = (AL < 0x06) || get_CF();
+ AL = AL - 0x06;
+ /*tmpCF = (AL < 0) || CF;*/
+ }
+ if ( (tmpAL > 0x99) || get_CF() ) {
+ AL = AL - 0x60;
+ tmpCF = 1;
+ }
+
+ set_CF(tmpCF);
+ set_SF(AL >> 7);
+ set_ZF(AL==0);
+ set_PF_base(AL);
+}
+
+ void
+BX_CPU_C::AAA(BxInstruction_t *)
+{
+ Bit8u ALcarry;
+
+ ALcarry = AL > 0xf9;
+
+ /* AAA effects the following flags: A,C */
+ if ( ((AL & 0x0f) > 9) || get_AF() ) {
+ AL = (AL + 6) & 0x0f;
+ AH = AH + 1 + ALcarry;
+ set_AF(1);
+ set_CF(1);
+ }
+ else {
+ set_AF(0);
+ set_CF(0);
+ AL = AL & 0x0f;
+ }
+}
+
+ void
+BX_CPU_C::AAS(BxInstruction_t *)
+{
+ Bit8u ALborrow;
+
+ /* AAS affects the following flags: A,C */
+
+ ALborrow = AL < 6;
+
+ if ( ((AL & 0x0F) > 0x09) || get_AF() ) {
+ AL = (AL - 6) & 0x0f;
+ AH = AH - 1 - ALborrow;
+ set_AF(1);
+ set_CF(1);
+ }
+ else {
+ set_CF(0);
+ set_AF(0);
+ AL = AL & 0x0f;
+ }
+}
+
+ void
+BX_CPU_C::AAM(BxInstruction_t *i)
+{
+ Bit8u al, imm8;
+
+ imm8 = i->Ib;
+
+ al = AL;
+ AH = al / imm8;
+ AL = al % imm8;
+
+ /* AAM affects the following flags: S,Z,P */
+ set_SF((AH & 0x80) > 0);
+ set_ZF(AX==0);
+ set_PF_base(AL); /* ??? */
+}
+
+ void
+BX_CPU_C::AAD(BxInstruction_t *i)
+{
+ Bit8u imm8;
+
+ imm8 = i->Ib;
+
+ AL = AH * imm8 + AL;
+ AH = 0;
+
+ /* AAD effects the following flags: S,Z,P */
+ set_SF(AL >= 0x80);
+ set_ZF(AL == 0);
+ set_PF_base(AL);
+}
+
+ void
+BX_CPU_C::DAA(BxInstruction_t *)
+{
+ Bit8u al;
+
+ al = AL;
+
+ // DAA affects the following flags: S,Z,A,P,C
+ // ???
+
+ if (((al & 0x0F) > 0x09) || get_AF()) {
+ al = al + 0x06;
+ set_AF(1);
+ }
+ else
+ set_AF(0);
+
+ if ((al > 0x9F) || get_CF()) {
+ al = al + 0x60;
+ set_CF(1);
+ }
+
+ AL = al;
+
+ set_SF(al >> 7);
+ set_ZF(al==0);
+ set_PF_base(al);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+ void
+BX_CPU_C::SETO_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETO: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_OF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNO_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNO: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_OF()==0)
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETB_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETB: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_CF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNB_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNB: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_CF()==0)
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETZ_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETZ: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_ZF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNZ_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNZ: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_ZF()==0)
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETBE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETBE: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_CF() || get_ZF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNBE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNBE: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if ((get_CF()==0) && (get_ZF()==0))
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETS_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETS: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_SF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNS_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNL: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_SF()==0)
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETP_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETP: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_PF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNP_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNP: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_PF() == 0)
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETL_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETL: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_SF() != get_OF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNL_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNL: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_SF() == get_OF())
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETLE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETLE: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if (get_ZF() || (get_SF()!=get_OF()))
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::SETNLE_Eb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("SETNLE: not available on < 386\n"));
+#else
+ Bit8u result_8;
+
+
+ if ((get_ZF()==0) && (get_SF()==get_OF()))
+ result_8 = 1;
+ else
+ result_8 = 0;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &result_8);
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::BSF_GvEv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BSF_GvEv(): not supported on < 386\n"));
+#else
+
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32;
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ if (op2_32 == 0) {
+ set_ZF(1);
+ /* op1_32 undefined */
+ return;
+ }
+
+ op1_32 = 0;
+ while ( (op2_32 & 0x01) == 0 ) {
+ op1_32++;
+ op2_32 >>= 1;
+ }
+ set_ZF(0);
+
+ /* now write result back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, op1_32);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16;
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ if (op2_16 == 0) {
+ set_ZF(1);
+ /* op1_16 undefined */
+ return;
+ }
+
+ op1_16 = 0;
+ while ( (op2_16 & 0x01) == 0 ) {
+ op1_16++;
+ op2_16 >>= 1;
+ }
+ set_ZF(0);
+
+ /* now write result back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, op1_16);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BSR_GvEv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BSR_GvEv(): not supported on < 386\n"));
+#else
+
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32;
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ if (op2_32 == 0) {
+ set_ZF(1);
+ /* op1_32 undefined */
+ return;
+ }
+
+ op1_32 = 31;
+ while ( (op2_32 & 0x80000000) == 0 ) {
+ op1_32--;
+ op2_32 <<= 1;
+ }
+ set_ZF(0);
+
+ /* now write result back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, op1_32);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16;
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ if (op2_16 == 0) {
+ set_ZF(1);
+ /* op1_16 undefined */
+ return;
+ }
+
+ op1_16 = 15;
+ while ( (op2_16 & 0x8000) == 0 ) {
+ op1_16--;
+ op2_16 <<= 1;
+ }
+ set_ZF(0);
+
+ /* now write result back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, op1_16);
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::BSWAP_EAX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u eax, b0, b1, b2, b3;
+
+ eax = EAX;
+ b0 = eax & 0xff; eax >>= 8;
+ b1 = eax & 0xff; eax >>= 8;
+ b2 = eax & 0xff; eax >>= 8;
+ b3 = eax;
+
+ EAX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_EAX: not implemented CPU <= 3\n"));
+#endif
+}
+
+ void
+BX_CPU_C::BSWAP_ECX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u ecx, b0, b1, b2, b3;
+
+ ecx = ECX;
+ b0 = ecx & 0xff; ecx >>= 8;
+ b1 = ecx & 0xff; ecx >>= 8;
+ b2 = ecx & 0xff; ecx >>= 8;
+ b3 = ecx;
+
+ ECX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_ECX: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_EDX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u edx, b0, b1, b2, b3;
+
+ edx = EDX;
+ b0 = edx & 0xff; edx >>= 8;
+ b1 = edx & 0xff; edx >>= 8;
+ b2 = edx & 0xff; edx >>= 8;
+ b3 = edx;
+
+ EDX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_EDX: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_EBX(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u ebx, b0, b1, b2, b3;
+
+ ebx = EBX;
+ b0 = ebx & 0xff; ebx >>= 8;
+ b1 = ebx & 0xff; ebx >>= 8;
+ b2 = ebx & 0xff; ebx >>= 8;
+ b3 = ebx;
+
+ EBX = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_EBX: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_ESP(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u esp, b0, b1, b2, b3;
+
+ esp = ESP;
+ b0 = esp & 0xff; esp >>= 8;
+ b1 = esp & 0xff; esp >>= 8;
+ b2 = esp & 0xff; esp >>= 8;
+ b3 = esp;
+
+ ESP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_ESP: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_EBP(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u ebp, b0, b1, b2, b3;
+
+ ebp = EBP;
+ b0 = ebp & 0xff; ebp >>= 8;
+ b1 = ebp & 0xff; ebp >>= 8;
+ b2 = ebp & 0xff; ebp >>= 8;
+ b3 = ebp;
+
+ EBP = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_EBP: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_ESI(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u esi, b0, b1, b2, b3;
+
+ esi = ESI;
+ b0 = esi & 0xff; esi >>= 8;
+ b1 = esi & 0xff; esi >>= 8;
+ b2 = esi & 0xff; esi >>= 8;
+ b3 = esi;
+
+ ESI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_ESI: not implemented CPU <= 3\n"));
+#endif
+}
+ void
+BX_CPU_C::BSWAP_EDI(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
+
+ Bit32u edi, b0, b1, b2, b3;
+
+ edi = EDI;
+ b0 = edi & 0xff; edi >>= 8;
+ b1 = edi & 0xff; edi >>= 8;
+ b2 = edi & 0xff; edi >>= 8;
+ b3 = edi;
+
+ EDI = (b0<<24) | (b1<<16) | (b2<<8) | b3;
+#else
+ BX_PANIC(("BSWAP_EDI: not implemented CPU <= 3\n"));
+#endif
+}
+
+
+ void
+BX_CPU_C::BT_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BT_EvGv: not available on <386\n"));
+#else
+ Bit32u op1_addr;
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, index;
+ Bit32s displacement32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ op2_32 &= 0x1f;
+ set_CF((op1_32 >> op2_32) & 0x01);
+ return;
+ }
+
+ index = op2_32 & 0x1f;
+ displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+ op1_addr = i->rm_addr + 4 * displacement32;
+
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, op1_addr, &op1_32);
+
+ set_CF((op1_32 >> index) & 0x01);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16, index;
+ Bit32s displacement32;
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ op2_16 &= 0x0f;
+ set_CF((op1_16 >> op2_16) & 0x01);
+ return;
+ }
+
+ index = op2_16 & 0x0f;
+ displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+ op1_addr = i->rm_addr + 2 * displacement32;
+
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, op1_addr, &op1_16);
+
+ set_CF((op1_16 >> index) & 0x01);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTS_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTS_EvGv: not available on <386\n"));
+#else
+ Bit32u op1_addr;
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, bit_i, index;
+ Bit32s displacement32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ op2_32 &= 0x1f;
+ set_CF((op1_32 >> op2_32) & 0x01);
+ op1_32 |= (((Bit32u) 1) << op2_32);
+
+ /* now write diff back to destination */
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ return;
+ }
+
+ index = op2_32 & 0x1f;
+ displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+ op1_addr = i->rm_addr + 4 * displacement32;
+
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+
+ bit_i = (op1_32 >> index) & 0x01;
+ op1_32 |= (((Bit32u) 1) << index);
+
+ write_RMW_virtual_dword(op1_32);
+
+ set_CF(bit_i);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16, bit_i, index;
+ Bit32s displacement32;
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ op2_16 &= 0x0f;
+ set_CF((op1_16 >> op2_16) & 0x01);
+ op1_16 |= (((Bit16u) 1) << op2_16);
+
+ /* now write diff back to destination */
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ return;
+ }
+
+ index = op2_16 & 0x0f;
+ displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+ op1_addr = i->rm_addr + 2 * displacement32;
+
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+
+ bit_i = (op1_16 >> index) & 0x01;
+ op1_16 |= (((Bit16u) 1) << index);
+
+ write_RMW_virtual_word(op1_16);
+
+ set_CF(bit_i);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTR_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTR_EvGv: not available on <386\n"));
+#else
+ Bit32u op1_addr;
+
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, index, temp_cf;
+ Bit32s displacement32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ op2_32 &= 0x1f;
+ set_CF((op1_32 >> op2_32) & 0x01);
+ op1_32 &= ~(((Bit32u) 1) << op2_32);
+
+ /* now write diff back to destination */
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ return;
+ }
+
+ index = op2_32 & 0x1f;
+ displacement32 = ((Bit32s) (op2_32&0xffffffe0)) / 32;
+ op1_addr = i->rm_addr + 4 * displacement32;
+
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+
+ temp_cf = (op1_32 >> index) & 0x01;
+ op1_32 &= ~(((Bit32u) 1) << index);
+
+ /* now write back to destination */
+ write_RMW_virtual_dword(op1_32);
+
+ set_CF(temp_cf);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16, index, temp_cf;
+ Bit32s displacement32;
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ op2_16 &= 0x0f;
+ set_CF((op1_16 >> op2_16) & 0x01);
+ op1_16 &= ~(((Bit16u) 1) << op2_16);
+
+ /* now write diff back to destination */
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ return;
+ }
+
+ index = op2_16 & 0x0f;
+ displacement32 = ((Bit16s) (op2_16&0xfff0)) / 16;
+ op1_addr = i->rm_addr + 2 * displacement32;
+
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+
+ temp_cf = (op1_16 >> index) & 0x01;
+ op1_16 &= ~(((Bit16u) 1) << index);
+
+ /* now write back to destination */
+ write_RMW_virtual_word(op1_16);
+
+ set_CF(temp_cf);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTC_EvGv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTC_EvGv: not available on <386\n"));
+#else
+ Bit32u op1_addr;
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, index_32, temp_CF;
+ Bit32s displacement32;
+
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+ index_32 = op2_32 & 0x1f;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ op1_addr = 0; // keep compiler happy
+ }
+ else {
+ displacement32 = ((Bit32s) (op2_32 & 0xffffffe0)) / 32;
+ op1_addr = i->rm_addr + 4 * displacement32;
+ read_RMW_virtual_dword(i->seg, op1_addr, &op1_32);
+ }
+
+ temp_CF = (op1_32 >> index_32) & 0x01;
+ op1_32 &= ~(((Bit32u) 1) << index_32); /* clear out bit */
+ op1_32 |= (((Bit32u) !temp_CF) << index_32); /* set to complement */
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+ set_CF(temp_CF);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, op2_16, index_16, temp_CF;
+ Bit16s displacement16;
+
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+ index_16 = op2_16 & 0x0f;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ op1_addr = 0; // keep compiler happy
+ }
+ else {
+ displacement16 = ((Bit16s) (op2_16 & 0xfff0)) / 16;
+ op1_addr = i->rm_addr + 2 * displacement16;
+ read_RMW_virtual_word(i->seg, op1_addr, &op1_16);
+ }
+
+ temp_CF = (op1_16 >> index_16) & 0x01;
+ op1_16 &= ~(((Bit16u) 1) << index_16); /* clear out bit */
+ op1_16 |= (((Bit16u) !temp_CF) << index_16); /* set to complement */
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+ set_CF(temp_CF);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BT_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BT_EvIb: not available on <386\n"));
+#else
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32;
+ Bit8u op2_8;
+
+ op2_8 = i->Ib;
+ op2_8 %= 32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ set_CF((op1_32 >> op2_8) & 0x01);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16;
+ Bit8u op2_8;
+
+
+ op2_8 = i->Ib;
+ op2_8 %= 16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ set_CF((op1_16 >> op2_8) & 0x01);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTS_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTS_EvIb: not available on <386\n"));
+#else
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, temp_CF;
+ Bit8u op2_8;
+
+ op2_8 = i->Ib;
+ op2_8 %= 32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ temp_CF = (op1_32 >> op2_8) & 0x01;
+ op1_32 |= (((Bit32u) 1) << op2_8);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+ set_CF(temp_CF);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, temp_CF;
+ Bit8u op2_8;
+
+
+ op2_8 = i->Ib;
+ op2_8 %= 16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ temp_CF = (op1_16 >> op2_8) & 0x01;
+ op1_16 |= (((Bit16u) 1) << op2_8);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+ set_CF(temp_CF);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTC_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTC_EvIb: not available on <386\n"));
+#else
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, temp_CF;
+ Bit8u op2_8;
+
+ op2_8 = i->Ib;
+ op2_8 %= 32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ temp_CF = (op1_32 >> op2_8) & 0x01;
+
+ op1_32 &= ~(((Bit32u) 1) << op2_8); /* clear out bit */
+ op1_32 |= (((Bit32u) !temp_CF) << op2_8); /* set to complement */
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+ set_CF(temp_CF);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, temp_CF;
+ Bit8u op2_8;
+
+
+ op2_8 = i->Ib;
+ op2_8 %= 16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ temp_CF = (op1_16 >> op2_8) & 0x01;
+ op1_16 &= ~(((Bit16u) 1) << op2_8); /* clear out bit */
+ op1_16 |= (((Bit16u) !temp_CF) << op2_8); /* set to complement */
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+ set_CF(temp_CF);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::BTR_EvIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("BTR_EvIb: not available on <386\n"));
+#else
+
+ if (i->os_32) { /* 32 bit operand size mode */
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, temp_CF;
+ Bit8u op2_8;
+
+ op2_8 = i->Ib;
+ op2_8 %= 32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ temp_CF = (op1_32 >> op2_8) & 0x01;
+ op1_32 &= ~(((Bit32u) 1) << op2_8);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ write_RMW_virtual_dword(op1_32);
+ }
+ set_CF(temp_CF);
+ }
+ else { /* 16 bit operand size mode */
+ Bit16u op1_16, temp_CF;
+ Bit8u op2_8;
+
+
+ op2_8 = i->Ib;
+ op2_8 %= 16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ temp_CF = (op1_16 >> op2_8) & 0x01;
+ op1_16 &= ~(((Bit16u) 1) << op2_8);
+
+ /* now write diff back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+ set_CF(temp_CF);
+ }
+#endif
+}
--- /dev/null
+// cpu-sid.cc - override some important bx_cpu_c member functions. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+static Bit8u *sid_prefetch_data = NULL;
+
+void
+sid_cpu_c::cpu_loop(Bit32s max_instr_count)
+{
+ unsigned ret;
+ BxInstruction_t i;
+ unsigned maxisize;
+ Bit8u *fetch_ptr;
+ Boolean is_32;
+
+ static int num_loops = 0;
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR break_point = 0;
+#ifdef MAGIC_BREAKPOINT
+ BX_CPU_THIS_PTR magic_break = 0;
+#endif // MAGIC_BREAKPOINT
+ BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+#endif // BX_DEBUGGER
+
+ (void) setjmp( BX_CPU_THIS_PTR jmp_buf_env );
+
+ BX_CPU_THIS_PTR prev_eip = EIP; // commit new EIP
+ BX_CPU_THIS_PTR prev_esp = ESP; // commit new ESP
+
+#if X86_CPU_DEBUG
+ printf("At top of main loop, EIP = %p, ESP = %p\n", EIP, ESP);
+#endif
+
+main_cpu_loop:
+
+ // ???
+ BX_CPU_THIS_PTR EXT = 0;
+ BX_CPU_THIS_PTR errorno = 0;
+
+ // First check on events which occurred for previous instructions
+ // (traps) and ones which are asynchronous to the CPU
+ // (hardware interrupts).
+ if (BX_CPU_THIS_PTR async_event)
+ goto handle_async_event;
+
+async_events_processed:
+
+ // Now we can handle things which are synchronous to instruction
+ // execution.
+ if (BX_CPU_THIS_PTR eflags.rf) {
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ }
+#if BX_X86_DEBUGGER
+ else {
+ // only bother comparing if any breakpoints enabled
+ if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+ Bit32u iaddr =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base +
+ BX_CPU_THIS_PTR prev_eip;
+ Bit32u dr6_bits;
+ if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
+ BX_HWDebugInstruction)) ) {
+ // Add to the list of debug events thus far.
+ BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+ BX_CPU_THIS_PTR async_event = 1;
+ // If debug events are not inhibited on this boundary,
+ // fire off a debug fault. Otherwise handle it on the next
+ // boundary. (becomes a trap)
+ if ( !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+ // 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
+ // debug events on this boundary. Reset the mask so they
+ // will be processed on the next boundary.
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+#if BX_DEBUGGER
+ {
+ Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+ if ( dbg_is_begin_instr_bpoint(
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+ return;
+ }
+ }
+#endif // #if BX_DEBUGGER
+
+
+ is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+
+ if (BX_CPU_THIS_PTR bytesleft == 0) {
+ prefetch();
+ }
+ 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);
+
+#if X86_CPU_DEBUG
+ printf("FetchDecode returned: %d\n", ret);
+ printf("Current opcode: %p, with length: %d, EIP = %p\n", i.b1, i.ilen, this->eip);
+#endif
+
+ if (ret) {
+ if (i.ResolveModrm) {
+ // call method on sid_cpu_c object
+ BX_CPU_CALL_METHOD_FROM_SID(i.ResolveModrm, (&i));
+ }
+ BX_CPU_THIS_PTR fetch_ptr += i.ilen;
+ BX_CPU_THIS_PTR bytesleft -= i.ilen;
+fetch_decode_OK:
+
+ if (i.rep_used && (i.attr & BxRepeatable)) {
+repeat_loop:
+ if (i.attr & BxRepeatableZF) {
+ if (i.as_32) {
+ if (ECX != 0) {
+ BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&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 (ECX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ else {
+ if (CX != 0) {
+ BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&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 (CX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ }
+ else { // normal repeat, no concern for ZF
+ if (i.as_32) {
+ if (ECX != 0) {
+ BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+ ECX -= 1;
+ }
+ if (ECX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ else { // 16bit addrsize
+ if (CX != 0) {
+ BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&i));
+ CX -= 1;
+ }
+ if (CX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ }
+ // 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);
+#endif
+
+#if BX_DEBUGGER == 0
+ if (BX_CPU_THIS_PTR async_event) {
+ invalidate_prefetch_q();
+ goto debugger_check;
+ }
+ goto repeat_loop;
+#else /* if BX_DEBUGGER == 1 */
+ invalidate_prefetch_q();
+ goto debugger_check;
+#endif
+
+
+repeat_done:
+ BX_CPU_THIS_PTR eip += i.ilen;
+ }
+ else {
+ // non repeating instruction
+ BX_CPU_THIS_PTR eip += i.ilen;
+ BX_CPU_CALL_METHOD_FROM_SID(i.execute_sid, (&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(BX_CPU_THIS_PTR eip + BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.base);
+#endif
+
+debugger_check:
+
+ // The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+ // instructions and then return so that the other processors have a chance
+ // to run. Every time sid pulses the step pin, cpu_loop executes once
+ CHECK_MAX_INSTRUCTIONS(max_instr_count);
+
+#if BX_DEBUGGER
+ // BW vm mode switch support is in dbg_is_begin_instr_bpoint
+ // note instr generating exceptions never reach this point.
+
+ // (mch) Read/write, time break point support
+ if (BX_CPU_THIS_PTR break_point) {
+ switch (BX_CPU_THIS_PTR break_point) {
+ case BREAK_POINT_TIME:
+ BX_CPU_THIS_PTR info("[%lld] Caught time breakpoint\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_TIME_BREAK_POINT;
+ return;
+ case BREAK_POINT_READ:
+ BX_CPU_THIS_PTR info("[%lld] Caught read watch point\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_READ_WATCH_POINT;
+ return;
+ case BREAK_POINT_WRITE:
+ BX_CPU_THIS_PTR info("[%lld] Caught write watch point\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_WRITE_WATCH_POINT;
+ return;
+ default:
+ BX_PANIC(("Weird break point condition"));
+ }
+ }
+#ifdef MAGIC_BREAKPOINT
+ // (mch) Magic break point support
+ if (BX_CPU_THIS_PTR magic_break) {
+ if (bx_dbg.magic_break_enabled) {
+ BX_CPU_THIS_PTR info("Stopped on MAGIC BREAKPOINT\n");
+ 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_CPU_THIS_PTR info("Ignoring MAGIC BREAKPOINT\n");
+ }
+ }
+#endif
+ if (BX_CPU_THIS_PTR trace) {
+ BX_CPU_THIS_PTR stop_reason = STOP_TRACE;
+ return;
+ }
+#endif
+
+#if BX_DEBUGGER
+ {
+ Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+ if ( dbg_is_end_instr_bpoint(
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+ return;
+ }
+ }
+#endif // #if BX_DEBUGGER
+ goto main_cpu_loop;
+ }
+ else {
+ unsigned remain, j;
+ static Bit8u FetchBuffer[16];
+ Bit8u *temp_ptr;
+
+ // read all leftover bytes in current page
+ for (j=0; j<BX_CPU_THIS_PTR bytesleft; j++) {
+ FetchBuffer[j] = *fetch_ptr++;
+ }
+
+ // 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;
+ 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\n"));
+ }
+ temp_ptr = fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+ // read leftover bytes in next page
+ for (; j<16; j++) {
+ FetchBuffer[j] = *temp_ptr++;
+ }
+
+ ret = FetchDecode(FetchBuffer, &i, 16, is_32);
+
+#if X86_CPU_DEBUG
+ printf("Just returned from prefetch...\n");
+ printf("FetchDecode returned: %d\n", ret);
+ printf("Current opcode: %p, with length: %d, EIP = %p, prev_eip = %p\n", i.b1, i.ilen, this->eip, this->prev_eip);
+#endif
+
+ if (ret==0)
+ BX_PANIC(("fetchdecode: cross boundary: ret==0\n"));
+ if (i.ResolveModrm) {
+ BX_CPU_CALL_METHOD_FROM_SID(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;
+ goto fetch_decode_OK;
+ }
+
+
+
+ //
+ // This area is where we process special conditions and events.
+ //
+
+handle_async_event:
+
+ if (BX_CPU_THIS_PTR debug_trap & 0x80000000) {
+ // I made up the bitmask above to mean HALT state.
+#if BX_SMP_PROCESSORS==1
+#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
+ // arrived, then clear the HALT condition; otherwise just return from
+ // the CPU loop with stop_reason STOP_CPU_HALTED.
+ if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+ // interrupt ends the HALT condition
+ BX_CPU_THIS_PTR debug_trap = 0; // clear traps for after resume
+ BX_CPU_THIS_PTR inhibit_mask = 0; // clear inhibits for after resume
+ //bx_printf ("halt condition has been cleared in %s\n", name);
+ } else {
+ // HALT condition remains, return so other CPUs have a chance
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR stop_reason = STOP_CPU_HALTED;
+#endif
+ return;
+ }
+#endif
+ }
+
+
+ // Priority 1: Hardware Reset and Machine Checks
+ // RESET
+ // Machine Check
+ // (bochs doesn't support these)
+
+ // Priority 2: Trap on Task Switch
+ // T flag in TSS is set
+ 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
+ // STOPCLK
+ // SMI
+ // INIT
+ // (bochs doesn't support these)
+
+ // Priority 4: Traps on Previous Instruction
+ // 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) ) {
+ // 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
+ // Maskable Hardware Interrupts
+ if (BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_INTERRUPTS) {
+ // Processing external interrupts is inhibited on this
+ // boundary because of certain instructions like STI.
+ // 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_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ && BX_DBG_ASYNC_INTR) {
+ Bit8u vector;
+
+ // NOTE: similar code in ::take_irq()
+#if BX_SUPPORT_APIC
+ if (BX_CPU_THIS_PTR int_from_local_apic)
+ vector = BX_CPU_THIS_PTR local_apic.acknowledge_int ();
+ else
+ vector = BX_IAC(); // may set INTR with next interrupt
+#else
+#if 0 // FIXME: this will eventually be included
+ // if no local APIC, always acknowledge the PIC.
+ vector = BX_IAC(); // may set INTR with next interrupt
+#endif
+#endif
+ //if (bx_dbg.interrupts) BX_INFO(("decode: interrupt %u\n",
+ // (unsigned) vector));
+ 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);
+ }
+#if 0 // FIXME: this will eventually be included
+ 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
+ BX_RAISE_HLDA();
+ }
+#endif
+ // Priority 6: Faults from fetching next instruction
+ // Code breakpoint fault
+ // Code segment limit violation (priority 7 on 486/Pentium)
+ // Code page fault (priority 7 on 486/Pentium)
+ // (handled in main decode loop)
+
+ // Priority 7: Faults from decoding next instruction
+ // Instruction length > 15 bytes
+ // Illegal opcode
+ // Coprocessor not available
+ // (handled in main decode loop etc)
+
+ // Priority 8: Faults on executing an instruction
+ // Floating point execution
+ // Overflow
+ // Bound error
+ // Invalid TSS
+ // Segment not present
+ // Stack fault
+ // General protection
+ // Data page fault
+ // Alignment check
+ // (handled by rest of the code)
+
+
+ if (BX_CPU_THIS_PTR eflags.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
+ }
+#if 0 // FIXME: this will eventually be included
+ if ( !(BX_CPU_THIS_PTR INTR ||
+ BX_CPU_THIS_PTR debug_trap ||
+ BX_HRQ ||
+ BX_CPU_THIS_PTR eflags.tf) )
+ BX_CPU_THIS_PTR async_event = 0;
+ goto async_events_processed;
+#endif
+}
+
+// boundaries of consideration:
+//
+// * physical memory boundary: 1024k (1Megabyte) (increments of...)
+// * A20 boundary: 1024k (1Megabyte)
+// * page boundary: 4k
+// * ROM boundary: 2k (dont care since we are only reading)
+// * segment boundary: any
+
+
+
+ void
+sid_cpu_c::prefetch(void)
+{
+ // cs:eIP
+ // prefetch QSIZE byte quantity aligned on corresponding boundary
+ Bit32u new_linear_addr;
+ Bit32u new_phy_addr;
+ Bit32u temp_eip, temp_limit;
+
+ temp_eip = BX_CPU_THIS_PTR 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;
+ if (temp_eip > temp_limit) {
+ BX_PANIC(("prefetch: EIP > CS.limit\n"));
+ }
+
+#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);
+ }
+ else {
+#endif // BX_SUPPORT_PAGING
+ new_phy_addr = A20ADDR(new_linear_addr);
+#if BX_SUPPORT_PAGING
+ }
+#endif // BX_SUPPORT_PAGING
+
+ // 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) {
+ // }
+
+ BX_CPU_THIS_PTR bytesleft = 16;
+
+ if(!sid_prefetch_data)
+ sid_prefetch_data = new Bit8u[16];
+
+#if X86_CPU_DEBUG
+ printf("Prefetching 16 new bytes from %p...\n", new_phy_addr);
+#endif
+
+ BX_CPU_THIS_PTR mem->read_physical(this, new_phy_addr, 16, (void *)sid_prefetch_data);
+
+ BX_CPU_THIS_PTR fetch_ptr = sid_prefetch_data;
+}
+
+
+ // If control has transfered locally, it is possible the prefetch Q is
+ // still valid. This would happen for repeat instructions, and small
+ // branches.
+ void
+sid_cpu_c::revalidate_prefetch_q(void)
+{
+ Bit32u new_linear_addr, new_linear_page, new_linear_offset;
+ Bit32u new_phy_addr;
+
+ 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;
+
+ BX_CPU_THIS_PTR bytesleft = 16;
+
+ if(!sid_prefetch_data)
+ sid_prefetch_data = new Bit8u[16];
+
+#if X86_CPU_DEBUG
+ printf("Revalidating prefetch: Prefetching 16 new bytes from %p...\n", new_phy_addr);
+#endif
+
+ BX_CPU_THIS_PTR mem->read_physical(this, new_phy_addr, 16, (void *)sid_prefetch_data);
+
+ BX_CPU_THIS_PTR fetch_ptr = sid_prefetch_data;
+ }
+ else {
+ BX_CPU_THIS_PTR bytesleft = 0; // invalidate prefetch Q
+ }
+}
--- /dev/null
+// cpu-sid.h - declaration of the sid_cpu_c class. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#ifndef __CPU_SID_H__
+#define __CPU_SID_H__
+
+// The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+// instructions and then return so that the other processors have a chance to
+// run. This is used only when simulating multiple processors.
+//
+// If maximum instructions have been executed, return. A count less
+// than zero means run forever.
+#define CHECK_MAX_INSTRUCTIONS(count) \
+ if (count >= 0) { \
+ count--; if (count == 0) return; \
+ }
+
+#define NEED_CPU_REG_SHORTCUTS 1
+
+#include "cpu.h"
+
+class x86_cpu;
+
+class sid_cpu_c : public BX_CPU_C {
+ public:
+ x86_cpu *sid_cpu;
+
+ void init (sid_mem_c *addrspace);
+ void interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+ Bit16u error_code);
+ void set_INTR(Boolean value);
+ void cpu_loop(Bit32s max_instr_count);
+ void prefetch(void);
+ void revalidate_prefetch_q(void);
+
+ Bit32u dbg_get_eflags(void);
+ Bit32u dbg_get_reg(unsigned reg);
+ Boolean dbg_set_reg(unsigned reg, Bit32u val);
+ void JCC_Jd(BxInstruction_t *i);
+ void INT3(BxInstruction_t *i);
+ void INT_Ib(BxInstruction_t *i);
+ unsigned FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+ unsigned remain, Boolean is_32);
+};
+
+typedef void (sid_cpu_c::*SidExecutePtr_t)(BxInstruction_t *);
+
+# define BX_CPU_CALL_METHOD_FROM_SID(func, args) \
+ (this->*((SidExecutePtr_t) (func))) args
+
+extern sid_cpu_c bx_cpu;
+
+#endif // __CPU_SID_H__
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+//unsigned counter[2] = { 0, 0 };
+
+
+
+#if BX_SIM_ID == 0 // only need to define once
+// This array defines a look-up table for the even parity-ness
+// of an 8bit quantity, for optimal assignment of the parity bit
+// in the EFLAGS register
+const Boolean bx_parity_lookup[256] = {
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
+ };
+#endif
+
+
+#if BX_SMP_PROCESSORS==1
+#if BX_SUPPORT_SID
+sid_cpu_c bx_cpu;
+sid_mem_c bx_mem;
+#else
+// single processor simulation, so there's one of everything
+BX_CPU_C bx_cpu;
+BX_MEM_C bx_mem;
+#endif // BX_SUPPORT_SID
+#else
+// multiprocessor simulation, we need an array of cpus and memories
+BX_CPU_C *bx_cpu_array[BX_SMP_PROCESSORS];
+BX_MEM_C *bx_mem_array[BX_ADDRESS_SPACES];
+#endif
+
+
+
+// notes:
+//
+// check limit of CS?
+
+#ifdef REGISTER_IADDR
+extern void REGISTER_IADDR(Bit32u addr);
+#endif
+
+// The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+// instructions and then return so that the other processors have a chance to
+// run. This is used only when simulating multiple processors.
+//
+// If maximum instructions have been executed, return. A count less
+// than zero means run forever.
+#define CHECK_MAX_INSTRUCTIONS(count) \
+ if (count >= 0) { \
+ count--; if (count == 0) return; \
+ }
+
+#if BX_SMP_PROCESSORS==1
+# define BX_TICK1_IF_SINGLE_PROCESSOR() BX_TICK1()
+#else
+# define BX_TICK1_IF_SINGLE_PROCESSOR()
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION == 0
+ void
+BX_CPU_C::cpu_loop(Bit32s max_instr_count)
+{
+ unsigned ret;
+ BxInstruction_t i;
+ unsigned maxisize;
+ Bit8u *fetch_ptr;
+ Boolean is_32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR break_point = 0;
+#ifdef MAGIC_BREAKPOINT
+ BX_CPU_THIS_PTR magic_break = 0;
+#endif
+ BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+#endif
+
+ (void) setjmp( BX_CPU_THIS_PTR jmp_buf_env );
+
+ 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;
+
+ // First check on events which occurred for previous instructions
+ // (traps) and ones which are asynchronous to the CPU
+ // (hardware interrupts).
+ if (BX_CPU_THIS_PTR async_event)
+ goto handle_async_event;
+
+async_events_processed:
+
+ // Now we can handle things which are synchronous to instruction
+ // execution.
+ if (BX_CPU_THIS_PTR eflags.rf) {
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ }
+#if BX_X86_DEBUGGER
+ else {
+ // only bother comparing if any breakpoints enabled
+ if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+ Bit32u iaddr =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base +
+ BX_CPU_THIS_PTR prev_eip;
+ Bit32u dr6_bits;
+ if ( (dr6_bits = hwdebug_compare(iaddr, 1, BX_HWDebugInstruction,
+ BX_HWDebugInstruction)) ) {
+ // Add to the list of debug events thus far.
+ BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+ BX_CPU_THIS_PTR async_event = 1;
+ // If debug events are not inhibited on this boundary,
+ // fire off a debug fault. Otherwise handle it on the next
+ // boundary. (becomes a trap)
+ if ( !(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG) ) {
+ // 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
+ // debug events on this boundary. Reset the mask so they
+ // will be processed on the next boundary.
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+#if BX_DEBUGGER
+ {
+ Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+ if ( dbg_is_begin_instr_bpoint(
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+ return;
+ }
+ }
+#endif // #if BX_DEBUGGER
+
+
+ is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+
+ if (BX_CPU_THIS_PTR bytesleft == 0) {
+ prefetch();
+ }
+ 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);
+
+ if (ret) {
+ if (i.ResolveModrm) {
+ // call method on BX_CPU_C object
+ 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 (i.rep_used && (i.attr & BxRepeatable)) {
+repeat_loop:
+ if (i.attr & BxRepeatableZF) {
+ if (i.as_32) {
+ if (ECX != 0) {
+ 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 (ECX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ else {
+ if (CX != 0) {
+ 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 (CX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ }
+ else { // normal repeat, no concern for ZF
+ if (i.as_32) {
+ if (ECX != 0) {
+ BX_CPU_CALL_METHOD(i.execute, (&i));
+ ECX -= 1;
+ }
+ if (ECX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ else { // 16bit addrsize
+ if (CX != 0) {
+ BX_CPU_CALL_METHOD(i.execute, (&i));
+ CX -= 1;
+ }
+ if (CX == 0) goto repeat_done;
+ goto repeat_not_done;
+ }
+ }
+ // 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);
+#endif
+ BX_TICK1_IF_SINGLE_PROCESSOR();
+
+#if BX_DEBUGGER == 0
+ if (BX_CPU_THIS_PTR async_event) {
+ invalidate_prefetch_q();
+ goto debugger_check;
+ }
+ goto repeat_loop;
+#else /* if BX_DEBUGGER == 1 */
+ invalidate_prefetch_q();
+ goto debugger_check;
+#endif
+
+
+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));
+ }
+
+ 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);
+#endif
+ BX_TICK1_IF_SINGLE_PROCESSOR();
+
+debugger_check:
+
+#if (BX_SMP_PROCESSORS>1 && BX_DEBUGGER==0)
+ // The CHECK_MAX_INSTRUCTIONS macro allows cpu_loop to execute a few
+ // instructions and then return so that the other processors have a chance
+ // to run. This is used only when simulating multiple processors. If only
+ // one processor, don't waste any cycles on it! Also, it is not needed
+ // with the debugger because its guard mechanism provides the same
+ // functionality.
+ CHECK_MAX_INSTRUCTIONS(max_instr_count);
+#endif
+
+#if BX_DEBUGGER
+ // BW vm mode switch support is in dbg_is_begin_instr_bpoint
+ // note instr generating exceptions never reach this point.
+
+ // (mch) Read/write, time break point support
+ if (BX_CPU_THIS_PTR break_point) {
+ switch (BX_CPU_THIS_PTR break_point) {
+ case BREAK_POINT_TIME:
+ BX_CPU_THIS_PTR info("[%lld] Caught time breakpoint\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_TIME_BREAK_POINT;
+ return;
+ case BREAK_POINT_READ:
+ BX_CPU_THIS_PTR info("[%lld] Caught read watch point\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_READ_WATCH_POINT;
+ return;
+ case BREAK_POINT_WRITE:
+ BX_CPU_THIS_PTR info("[%lld] Caught write watch point\n", bx_pc_system.time_ticks());
+ BX_CPU_THIS_PTR stop_reason = STOP_WRITE_WATCH_POINT;
+ return;
+ default:
+ BX_PANIC(("Weird break point condition"));
+ }
+ }
+#ifdef MAGIC_BREAKPOINT
+ // (mch) Magic break point support
+ if (BX_CPU_THIS_PTR magic_break) {
+ if (bx_dbg.magic_break_enabled) {
+ BX_CPU_THIS_PTR info("Stopped on MAGIC BREAKPOINT\n");
+ 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_CPU_THIS_PTR info("Ignoring MAGIC BREAKPOINT\n");
+ }
+ }
+#endif
+ if (BX_CPU_THIS_PTR trace) {
+ BX_CPU_THIS_PTR stop_reason = STOP_TRACE;
+ return;
+ }
+#endif
+
+#if BX_DEBUGGER
+ {
+ Bit32u debug_eip = BX_CPU_THIS_PTR prev_eip;
+ if ( dbg_is_end_instr_bpoint(
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + debug_eip,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b) ) {
+ return;
+ }
+ }
+#endif // #if BX_DEBUGGER
+ goto main_cpu_loop;
+ }
+ else {
+ unsigned remain, j;
+static Bit8u FetchBuffer[16];
+ Bit8u *temp_ptr;
+
+ // read all leftover bytes in current page
+ for (j=0; j<BX_CPU_THIS_PTR bytesleft; j++) {
+ FetchBuffer[j] = *fetch_ptr++;
+ }
+
+ // 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;
+ 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\n"));
+ }
+ temp_ptr = fetch_ptr = BX_CPU_THIS_PTR fetch_ptr;
+
+ // read leftover bytes in next page
+ for (; j<16; j++) {
+ FetchBuffer[j] = *temp_ptr++;
+ }
+ ret = FetchDecode(FetchBuffer, &i, 16, is_32);
+ if (ret==0)
+ BX_PANIC(("fetchdecode: cross boundary: ret==0\n"));
+ 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;
+ goto fetch_decode_OK;
+ }
+
+
+
+ //
+ // This area is where we process special conditions and events.
+ //
+
+handle_async_event:
+
+ if (BX_CPU_THIS_PTR debug_trap & 0x80000000) {
+ // I made up the bitmask above to mean HALT state.
+#if BX_SMP_PROCESSORS==1
+ // for one processor, pass the time as quickly as possible until
+ // an interrupt wakes up the CPU.
+ while (1) {
+ if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+ break;
+ }
+ 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
+ // arrived, then clear the HALT condition; otherwise just return from
+ // the CPU loop with stop_reason STOP_CPU_HALTED.
+ if (BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_) {
+ // interrupt ends the HALT condition
+ BX_CPU_THIS_PTR debug_trap = 0; // clear traps for after resume
+ BX_CPU_THIS_PTR inhibit_mask = 0; // clear inhibits for after resume
+ //bx_printf ("halt condition has been cleared in %s\n", name);
+ } else {
+ // HALT condition remains, return so other CPUs have a chance
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR stop_reason = STOP_CPU_HALTED;
+#endif
+ return;
+ }
+#endif
+ }
+
+
+ // Priority 1: Hardware Reset and Machine Checks
+ // RESET
+ // Machine Check
+ // (bochs doesn't support these)
+
+ // Priority 2: Trap on Task Switch
+ // T flag in TSS is set
+ 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
+ // STOPCLK
+ // SMI
+ // INIT
+ // (bochs doesn't support these)
+
+ // Priority 4: Traps on Previous Instruction
+ // 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) ) {
+ // 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
+ // Maskable Hardware Interrupts
+ if (BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_INTERRUPTS) {
+ // Processing external interrupts is inhibited on this
+ // boundary because of certain instructions like STI.
+ // 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_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ && BX_DBG_ASYNC_INTR) {
+ Bit8u vector;
+
+ // NOTE: similar code in ::take_irq()
+#if BX_SUPPORT_APIC
+ if (BX_CPU_THIS_PTR int_from_local_apic)
+ vector = BX_CPU_THIS_PTR local_apic.acknowledge_int ();
+ else
+ vector = BX_IAC(); // may set INTR with next interrupt
+#else
+#if 0 // FIXME: look into this later
+ // if no local APIC, always acknowledge the PIC.
+ vector = BX_IAC(); // may set INTR with next interrupt
+#endif
+#endif
+ //if (bx_dbg.interrupts) BX_INFO(("decode: interrupt %u\n",
+ // (unsigned) vector));
+ 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);
+ }
+#if 0 // FIXME: look into this later
+ 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
+ BX_RAISE_HLDA();
+ }
+#endif
+ // Priority 6: Faults from fetching next instruction
+ // Code breakpoint fault
+ // Code segment limit violation (priority 7 on 486/Pentium)
+ // Code page fault (priority 7 on 486/Pentium)
+ // (handled in main decode loop)
+
+ // Priority 7: Faults from decoding next instruction
+ // Instruction length > 15 bytes
+ // Illegal opcode
+ // Coprocessor not available
+ // (handled in main decode loop etc)
+
+ // Priority 8: Faults on executing an instruction
+ // Floating point execution
+ // Overflow
+ // Bound error
+ // Invalid TSS
+ // Segment not present
+ // Stack fault
+ // General protection
+ // Data page fault
+ // Alignment check
+ // (handled by rest of the code)
+
+
+ if (BX_CPU_THIS_PTR eflags.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
+ }
+#if 0 // FIXME: look into this later
+ if ( !(BX_CPU_THIS_PTR INTR ||
+ BX_CPU_THIS_PTR debug_trap ||
+ BX_HRQ ||
+ BX_CPU_THIS_PTR eflags.tf) )
+ BX_CPU_THIS_PTR async_event = 0;
+#endif
+ goto async_events_processed;
+}
+#endif // #if BX_DYNAMIC_TRANSLATION == 0
+
+
+
+
+// boundaries of consideration:
+//
+// * physical memory boundary: 1024k (1Megabyte) (increments of...)
+// * A20 boundary: 1024k (1Megabyte)
+// * page boundary: 4k
+// * ROM boundary: 2k (dont care since we are only reading)
+// * segment boundary: any
+
+
+
+ void
+BX_CPU_C::prefetch(void)
+{
+ // cs:eIP
+ // prefetch QSIZE byte quantity aligned on corresponding boundary
+ Bit32u new_linear_addr;
+ Bit32u new_phy_addr;
+ Bit32u temp_eip, temp_limit;
+
+ temp_eip = BX_CPU_THIS_PTR 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;
+ if (temp_eip > temp_limit) {
+ BX_PANIC(("prefetch: EIP > CS.limit\n"));
+ }
+
+#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);
+ }
+ else {
+#endif // BX_SUPPORT_PAGING
+ new_phy_addr = A20ADDR(new_linear_addr);
+#if BX_SUPPORT_PAGING
+ }
+#endif // BX_SUPPORT_PAGING
+
+ 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_PANIC(("prefetch: running in bogus memory\n"));
+ }
+
+ // 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) {
+ // }
+
+ 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];
+}
+
+
+ // 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)
+{
+ Bit32u new_linear_addr, new_linear_page, new_linear_offset;
+ Bit32u new_phy_addr;
+
+ 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;
+ 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 = 0; // invalidate prefetch Q
+ }
+}
+
+ void
+BX_CPU_C::invalidate_prefetch_q(void)
+{
+ BX_CPU_THIS_PTR bytesleft = 0;
+}
+
+
+
+
+#if BX_DEBUGGER
+extern unsigned int dbg_show_mask;
+
+ Boolean
+BX_CPU_C::dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+ Bit32u is_32)
+{
+ BX_CPU_THIS_PTR guard_found.cs = cs;
+ BX_CPU_THIS_PTR guard_found.eip = eip;
+ BX_CPU_THIS_PTR guard_found.laddr = laddr;
+ BX_CPU_THIS_PTR guard_found.is_32bit_code = is_32;
+
+ // BW mode switch breakpoint
+ // instruction which generate exceptions never reach the end of the
+ // loop due to a long jump. Thats why we check at start of instr.
+ // Downside is that we show the instruction about to be executed
+ // (not the one generating the mode switch).
+ if (BX_CPU_THIS_PTR mode_break &&
+ (BX_CPU_THIS_PTR debug_vm != BX_CPU_THIS_PTR eflags.vm)) {
+ BX_CPU_THIS_PTR info("Caught vm mode switch breakpoint\n");
+ BX_CPU_THIS_PTR debug_vm = BX_CPU_THIS_PTR eflags.vm;
+ BX_CPU_THIS_PTR stop_reason = STOP_MODE_BREAK_POINT;
+ return 1;
+ }
+
+ if( (BX_CPU_THIS_PTR show_flag) & (dbg_show_mask)) {
+ int rv;
+ if((rv = bx_dbg_symbolic_output()))
+ return rv;
+ }
+
+ // see if debugger is looking for iaddr breakpoint of any type
+ if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_ALL) {
+#if BX_DBG_SUPPORT_VIR_BPOINT
+ if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_VIR) {
+ if (BX_CPU_THIS_PTR guard_found.icount!=0) {
+ for (unsigned i=0; i<bx_guard.iaddr.num_virtual; i++) {
+ if ( (bx_guard.iaddr.vir[i].cs == cs) &&
+ (bx_guard.iaddr.vir[i].eip == eip) ) {
+ BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_VIR;
+ BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+ return(1); // on a breakpoint
+ }
+ }
+ }
+ }
+#endif
+#if BX_DBG_SUPPORT_LIN_BPOINT
+ if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_LIN) {
+ if (BX_CPU_THIS_PTR guard_found.icount!=0) {
+ for (unsigned i=0; i<bx_guard.iaddr.num_linear; i++) {
+ if ( bx_guard.iaddr.lin[i].addr == BX_CPU_THIS_PTR guard_found.laddr ) {
+ BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_LIN;
+ BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+ return(1); // on a breakpoint
+ }
+ }
+ }
+ }
+#endif
+#if BX_DBG_SUPPORT_PHY_BPOINT
+ if (bx_guard.guard_for & BX_DBG_GUARD_IADDR_PHY) {
+ Bit32u phy;
+ Boolean valid;
+ dbg_xlate_linear2phy(BX_CPU_THIS_PTR guard_found.laddr,
+ &phy, &valid);
+ if ( (BX_CPU_THIS_PTR guard_found.icount!=0) && valid ) {
+ for (unsigned i=0; i<bx_guard.iaddr.num_physical; i++) {
+ if ( bx_guard.iaddr.phy[i].addr == phy ) {
+ BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_IADDR_PHY;
+ BX_CPU_THIS_PTR guard_found.iaddr_index = i;
+ return(1); // on a breakpoint
+ }
+ }
+ }
+ }
+#endif
+ }
+ return(0); // not on a breakpoint
+}
+
+
+ Boolean
+BX_CPU_C::dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+ Bit32u is_32)
+{
+ BX_CPU_THIS_PTR guard_found.icount++;
+
+ // see if debugger requesting icount guard
+ if (bx_guard.guard_for & BX_DBG_GUARD_ICOUNT) {
+ if (BX_CPU_THIS_PTR guard_found.icount >= bx_guard.icount) {
+ BX_CPU_THIS_PTR guard_found.cs = cs;
+ BX_CPU_THIS_PTR guard_found.eip = eip;
+ BX_CPU_THIS_PTR guard_found.laddr = laddr;
+ BX_CPU_THIS_PTR guard_found.is_32bit_code = is_32;
+ BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_ICOUNT;
+ return(1);
+ }
+ }
+
+ // convenient point to see if user typed Ctrl-C
+ if (bx_guard.interrupt_requested &&
+ (bx_guard.guard_for & BX_DBG_GUARD_CTRL_C)) {
+ BX_CPU_THIS_PTR guard_found.guard_found = BX_DBG_GUARD_CTRL_C;
+ return(1);
+ }
+
+#if (BX_NUM_SIMULATORS >= 2)
+ // if async event pending, acknowlege them
+ if (bx_guard.async_changes_pending.which) {
+ if (bx_guard.async_changes_pending.which & BX_DBG_ASYNC_PENDING_A20)
+ bx_dbg_async_pin_ack(BX_DBG_ASYNC_PENDING_A20,
+ bx_guard.async_changes_pending.a20);
+ if (bx_guard.async_changes_pending.which) {
+ BX_PANIC(("decode: async pending unrecognized.\n"));
+ }
+ }
+#endif
+ return(0); // no breakpoint
+}
+
+
+ void
+BX_CPU_C::dbg_take_irq(void)
+{
+ unsigned vector;
+
+ // NOTE: similar code in ::cpu_loop()
+
+ if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+ if ( setjmp(BX_CPU_THIS_PTR jmp_buf_env) == 0 ) {
+ // normal return from setjmp setup
+ vector = BX_IAC(); // may set INTR with next interrupt
+ BX_CPU_THIS_PTR errorno = 0;
+ BX_CPU_THIS_PTR EXT = 1; // external event
+ BX_CPU_THIS_PTR async_event = 1; // set in case INTR is triggered
+ interrupt(vector, 0, 0, 0);
+ }
+ }
+}
+
+ void
+BX_CPU_C::dbg_force_interrupt(unsigned vector)
+{
+ // Used to force slave simulator to take an interrupt, without
+ // regard to IF
+
+ if ( setjmp(BX_CPU_THIS_PTR jmp_buf_env) == 0 ) {
+ // normal return from setjmp setup
+ BX_CPU_THIS_PTR errorno = 0;
+ BX_CPU_THIS_PTR EXT = 1; // external event
+ BX_CPU_THIS_PTR async_event = 1; // probably don't need this
+ interrupt(vector, 0, 0, 0);
+ }
+}
+
+ void
+BX_CPU_C::dbg_take_dma(void)
+{
+ // NOTE: similar code in ::cpu_loop()
+ if ( BX_HRQ ) {
+ BX_CPU_THIS_PTR async_event = 1; // set in case INTR is triggered
+ BX_RAISE_HLDA();
+ }
+}
+#endif // #if BX_DEBUGGER
+
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#ifndef BX_CPU_H
+# define BX_CPU_H 1
+
+#include <setjmp.h>
+
+#include "cpu/lazy_flags.h"
+
+
+#define BX_SREG_ES 0
+#define BX_SREG_CS 1
+#define BX_SREG_SS 2
+#define BX_SREG_DS 3
+#define BX_SREG_FS 4
+#define BX_SREG_GS 5
+
+// segment register encoding
+#define BX_SEG_REG_ES 0
+#define BX_SEG_REG_CS 1
+#define BX_SEG_REG_SS 2
+#define BX_SEG_REG_DS 3
+#define BX_SEG_REG_FS 4
+#define BX_SEG_REG_GS 5
+#define BX_SEG_REG_NULL 8
+#define BX_NULL_SEG_REG(seg) ((seg) & BX_SEG_REG_NULL)
+
+
+#ifdef BX_LITTLE_ENDIAN
+#define BX_REG8L_OFFSET 0
+#define BX_REG8H_OFFSET 1
+#define BX_REG16_OFFSET 0
+#else // BX_BIG_ENDIAN
+#define BX_REG8L_OFFSET 3
+#define BX_REG8H_OFFSET 2
+#define BX_REG16_OFFSET 2
+#endif // ifdef BX_LITTLE_ENDIAN
+
+#define BX_8BIT_REG_AL 0
+#define BX_8BIT_REG_CL 1
+#define BX_8BIT_REG_DL 2
+#define BX_8BIT_REG_BL 3
+#define BX_8BIT_REG_AH 4
+#define BX_8BIT_REG_CH 5
+#define BX_8BIT_REG_DH 6
+#define BX_8BIT_REG_BH 7
+
+#define BX_16BIT_REG_AX 0
+#define BX_16BIT_REG_CX 1
+#define BX_16BIT_REG_DX 2
+#define BX_16BIT_REG_BX 3
+#define BX_16BIT_REG_SP 4
+#define BX_16BIT_REG_BP 5
+#define BX_16BIT_REG_SI 6
+#define BX_16BIT_REG_DI 7
+
+#define BX_32BIT_REG_EAX 0
+#define BX_32BIT_REG_ECX 1
+#define BX_32BIT_REG_EDX 2
+#define BX_32BIT_REG_EBX 3
+#define BX_32BIT_REG_ESP 4
+#define BX_32BIT_REG_EBP 5
+#define BX_32BIT_REG_ESI 6
+#define BX_32BIT_REG_EDI 7
+
+
+#if defined(NEED_CPU_REG_SHORTCUTS)
+
+/* WARNING:
+ Only BX_CPU_C member functions can use these shortcuts safely!
+ Functions that use the shortcuts outside of BX_CPU_C might work
+ when BX_USE_CPU_SMF=1 but will fail when BX_USE_CPU_SMF=0
+ (for example in SMP mode).
+*/
+
+// access to 8 bit general registers
+#define AL (BX_CPU_THIS_PTR gen_reg[0].word.byte.rl)
+#define CL (BX_CPU_THIS_PTR gen_reg[1].word.byte.rl)
+#define DL (BX_CPU_THIS_PTR gen_reg[2].word.byte.rl)
+#define BL (BX_CPU_THIS_PTR gen_reg[3].word.byte.rl)
+#define AH (BX_CPU_THIS_PTR gen_reg[0].word.byte.rh)
+#define CH (BX_CPU_THIS_PTR gen_reg[1].word.byte.rh)
+#define DH (BX_CPU_THIS_PTR gen_reg[2].word.byte.rh)
+#define BH (BX_CPU_THIS_PTR gen_reg[3].word.byte.rh)
+
+
+// access to 16 bit general registers
+#define AX (BX_CPU_THIS_PTR gen_reg[0].word.rx)
+#define CX (BX_CPU_THIS_PTR gen_reg[1].word.rx)
+#define DX (BX_CPU_THIS_PTR gen_reg[2].word.rx)
+#define BX (BX_CPU_THIS_PTR gen_reg[3].word.rx)
+#define SP (BX_CPU_THIS_PTR gen_reg[4].word.rx)
+#define BP (BX_CPU_THIS_PTR gen_reg[5].word.rx)
+#define SI (BX_CPU_THIS_PTR gen_reg[6].word.rx)
+#define DI (BX_CPU_THIS_PTR gen_reg[7].word.rx)
+
+// access to 16 bit instruction pointer
+#define IP (* (Bit16u *) (((Bit8u *) &BX_CPU_THIS_PTR eip) + BX_REG16_OFFSET))
+
+
+// accesss to 32 bit general registers
+#define EAX BX_CPU_THIS_PTR gen_reg[0].erx
+#define ECX BX_CPU_THIS_PTR gen_reg[1].erx
+#define EDX BX_CPU_THIS_PTR gen_reg[2].erx
+#define EBX BX_CPU_THIS_PTR gen_reg[3].erx
+#define ESP BX_CPU_THIS_PTR gen_reg[4].erx
+#define EBP BX_CPU_THIS_PTR gen_reg[5].erx
+#define ESI BX_CPU_THIS_PTR gen_reg[6].erx
+#define EDI BX_CPU_THIS_PTR gen_reg[7].erx
+
+// access to 32 bit instruction pointer
+#define EIP BX_CPU_THIS_PTR eip
+
+
+#define BX_READ_8BIT_REG(index) (((index) < 4) ? \
+ (BX_CPU_THIS_PTR gen_reg[index].word.byte.rl) : \
+ (BX_CPU_THIS_PTR gen_reg[(index)-4].word.byte.rh))
+#define BX_READ_16BIT_REG(index) (BX_CPU_THIS_PTR gen_reg[index].word.rx)
+#define BX_READ_32BIT_REG(index) (BX_CPU_THIS_PTR gen_reg[index].erx)
+
+#define BX_READ_16BIT_BASE_REG(var, index) {\
+ var = *BX_CPU_THIS_PTR _16bit_base_reg[index];\
+ }
+
+#define BX_READ_16BIT_INDEX_REG(var, index) {\
+ var = *BX_CPU_THIS_PTR _16bit_index_reg[index];\
+ }
+
+#define BX_WRITE_8BIT_REG(index, val) {\
+ if ((index) < 4) \
+ BX_CPU_THIS_PTR gen_reg[index].word.byte.rl = val; \
+ else \
+ BX_CPU_THIS_PTR gen_reg[(index)-4].word.byte.rh = val; \
+ }
+#define BX_WRITE_16BIT_REG(index, val) {\
+ BX_CPU_THIS_PTR gen_reg[index].word.rx = val; \
+ }
+#define BX_WRITE_32BIT_REG(index, val) {\
+ BX_CPU_THIS_PTR gen_reg[index].erx = val; \
+ }
+
+
+
+
+#define TF BX_CPU_THIS_PTR eflags.tf
+#define IF BX_CPU_THIS_PTR eflags.if_
+#define DF BX_CPU_THIS_PTR eflags.df
+
+#define IOPL BX_CPU_THIS_PTR eflags.iopl
+#ifndef CPL
+#define CPL (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl)
+#endif
+
+
+#endif // defined(NEED_CPU_REG_SHORTCUTS)
+
+#define BX_DE_EXCEPTION 0 // Divide Error (fault)
+#define BX_DB_EXCEPTION 1 // Debug (fault/trap)
+#define BX_BP_EXCEPTION 3 // Breakpoint (trap)
+#define BX_OF_EXCEPTION 4 // Overflow (trap)
+#define BX_BR_EXCEPTION 5 // BOUND (fault)
+#define BX_UD_EXCEPTION 6
+#define BX_NM_EXCEPTION 7
+#define BX_DF_EXCEPTION 8
+#define BX_TS_EXCEPTION 10
+#define BX_NP_EXCEPTION 11
+#define BX_SS_EXCEPTION 12
+#define BX_GP_EXCEPTION 13
+#define BX_PF_EXCEPTION 14
+#define BX_MF_EXCEPTION 16
+#define BX_AC_EXCEPTION 17
+
+
+
+
+
+typedef struct {
+ /* 31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16
+ * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
+ * 0| 0| 0| 0| 0| 0| 0| 0| 0| 0|ID|VP|VF|AC|VM|RF
+ *
+ * 15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0
+ * ==|==|=====|==|==|==|==|==|==|==|==|==|==|==|==
+ * 0|NT| IOPL|OF|DF|IF|TF|SF|ZF| 0|AF| 0|PF| 1|CF
+ */
+
+ // In order to get access to these fields from the Dynamic Translation
+ // code, using only 8bit offsets, I needed to move these fields
+ // together.
+ Bit32u cf;
+ Bit32u af;
+ Bit32u zf;
+ Bit32u sf;
+ Bit32u of;
+
+ Boolean bit1;
+ Bit8u pf_byte; /* PF derived from last result byte when needed */
+ Boolean bit3;
+ Boolean bit5;
+ Boolean tf;
+ Boolean if_;
+ Boolean df;
+#if BX_CPU_LEVEL >= 2
+ Bit8u iopl;
+ Boolean nt;
+#endif
+ Boolean bit15;
+#if BX_CPU_LEVEL >= 3
+ Boolean rf;
+ Boolean vm;
+#endif
+#if BX_CPU_LEVEL >= 4
+ Boolean ac; // alignment check
+ // Boolean vif; // Virtual Interrupt Flag
+ // Boolean vip; // Virtual Interrupt Pending
+ Boolean id; // late model 486 and beyond had CPUID
+#endif
+ } bx_flags_reg_t;
+
+
+#if BX_CPU_LEVEL >= 2
+typedef struct {
+ Bit32u val32; // 32bit value of register
+
+ // bitfields broken out for efficient access
+#if BX_CPU_LEVEL >= 3
+ Boolean pg; // paging
+#endif
+
+// CR0 notes:
+// Each x86 level has its own quirks regarding how it handles
+// reserved bits. I used DOS DEBUG.EXE in real mode on the
+// following processors, tried to clear bits 1..30, then tried
+// to set bits 1..30, to see how these bits are handled.
+// I found the following:
+//
+// Processor try to clear bits 1..30 try to set bits 1..30
+// 386 7FFFFFF0 7FFFFFFE
+// 486DX2 00000010 6005003E
+// Pentium 00000010 7FFFFFFE
+// Pentium-II 00000010 6005003E
+//
+// My assumptions:
+// All processors: bit 4 is hardwired to 1 (not true on all clones)
+// 386: bits 5..30 of CR0 are also hardwired to 1
+// Pentium: reserved bits retain value set using mov cr0, reg32
+// 486DX2/Pentium-II: reserved bits are hardwired to 0
+
+#if BX_CPU_LEVEL >= 4
+ Boolean cd; // cache disable
+ Boolean nw; // no write-through
+ Boolean am; // alignment mask
+ Boolean wp; // write-protect
+ Boolean ne; // numerics exception
+#endif
+
+ Boolean ts; // task switched
+ Boolean em; // emulate math coprocessor
+ Boolean mp; // monitor coprocessor
+ Boolean pe; // protected mode enable
+ } bx_cr0_t;
+#endif
+
+
+typedef struct { /* bx_selector_t */
+ Bit16u value; /* the 16bit value of the selector */
+#if BX_CPU_LEVEL >= 2
+ /* the following fields are extracted from the value field in protected
+ mode only. They're used for sake of efficiency */
+ Bit16u index; /* 13bit index extracted from value in protected mode */
+ Bit8u ti; /* table indicator bit extracted from value */
+ Bit8u rpl; /* RPL extracted from value */
+#endif
+ } bx_selector_t;
+
+
+
+typedef struct {
+ Boolean valid; /* 0 = invalid, 1 = valid */
+ Boolean p; /* present */
+ Bit8u dpl; /* descriptor privilege level 0..3 */
+ Boolean segment; /* 0 = system/gate, 1 = data/code segment */
+ Bit8u type; /* For system & gate descriptors, only
+ * 0 = invalid descriptor (reserved)
+ * 1 = 286 available Task State Segment (TSS)
+ * 2 = LDT descriptor
+ * 3 = 286 busy Task State Segment (TSS)
+ * 4 = 286 call gate
+ * 5 = task gate
+ * 6 = 286 interrupt gate
+ * 7 = 286 trap gate
+ * 8 = (reserved)
+ * 9 = 386 available TSS
+ * 10 = (reserved)
+ * 11 = 386 busy TSS
+ * 12 = 386 call gate
+ * 13 = (reserved)
+ * 14 = 386 interrupt gate
+ * 15 = 386 trap gate */
+ union {
+ struct {
+ Boolean executable; /* 1=code, 0=data or stack segment */
+ Boolean c_ed; /* for code: 1=conforming,
+ for data/stack: 1=expand down */
+ Boolean r_w; /* for code: readable?, for data/stack: writeable? */
+ Boolean a; /* accessed? */
+ Bit32u base; /* base address: 286=24bits, 386=32bits */
+ Bit32u limit; /* limit: 286=16bits, 386=20bits */
+ Bit32u limit_scaled; /* for efficiency, this contrived field is set to
+ * limit for byte granular, and
+ * (limit << 12) | 0xfff for page granular seg's
+ */
+#if BX_CPU_LEVEL >= 3
+ Boolean g; /* granularity: 0=byte, 1=4K (page) */
+ Boolean d_b; /* default size: 0=16bit, 1=32bit */
+ Boolean avl; /* available for use by system */
+#endif
+ } segment;
+ struct {
+ Bit8u word_count; /* 5bits (0..31) #words to copy from caller's stack
+ * to called procedure's stack. (call gates only)*/
+ Bit16u dest_selector;
+ Bit16u dest_offset;
+ } gate286;
+ struct { // type 5: Task Gate Descriptor
+ Bit16u tss_selector; // TSS segment selector
+ } taskgate;
+#if BX_CPU_LEVEL >= 3
+ struct {
+ Bit8u dword_count; /* 5bits (0..31) #dwords to copy from caller's stack
+ * to called procedure's stack. (call gates only)*/
+ Bit16u dest_selector;
+ Bit32u dest_offset;
+ } gate386;
+#endif
+ struct {
+ Bit32u base; /* 24 bit 286 TSS base */
+ Bit16u limit; /* 16 bit 286 TSS limit */
+ } tss286;
+#if BX_CPU_LEVEL >= 3
+ struct {
+ Bit32u base; /* 32 bit 386 TSS base */
+ Bit32u limit; /* 20 bit 386 TSS limit */
+ Bit32u limit_scaled; // Same notes as for 'segment' field
+ Boolean g; /* granularity: 0=byte, 1=4K (page) */
+ Boolean avl; /* available for use by system */
+ } tss386;
+#endif
+ struct {
+ Bit32u base; /* 286=24 386+ =32 bit LDT base */
+ Bit16u limit; /* 286+ =16 bit LDT limit */
+ } ldt;
+ } u;
+
+ } bx_descriptor_t;
+
+typedef struct {
+ bx_selector_t selector;
+ bx_descriptor_t cache;
+ } bx_segment_reg_t;
+
+typedef void * (*BxVoidFPtr_t)(void);
+class BX_CPU_C;
+#if BX_SUPPORT_SID
+class sid_cpu_c;
+#endif
+
+typedef struct BxInstruction_tag {
+ // prefix stuff here...
+ unsigned attr; // attribute from fetchdecode
+ unsigned b1; // opcode1 byte
+ unsigned rep_used;
+ unsigned modrm; // mod-nnn-r/m byte
+ unsigned mod;
+ unsigned nnn;
+ unsigned rm;
+ Bit16u displ16u; // for 16-bit modrm forms
+ Bit32u displ32u; // for 32-bit modrm forms
+ unsigned seg;
+ unsigned sib; // scale-index-base (2nd modrm byte)
+ unsigned scale;
+ unsigned index;
+ unsigned base;
+ Bit32u addr_displacement; // address displacement
+ Bit32u rm_addr;
+ Bit32u Id;
+ Bit16u Iw;
+ Bit8u Ib;
+ Bit8u Ib2; // for ENTER_IwIb
+ Bit16u Iw2; // for JMP_Ap
+ unsigned ilen; // instruction length
+ unsigned os_32, as_32; // OperandSize/AddressSize is 32bit
+ unsigned flags_in, flags_out; // flags needed, flags modified
+
+#if BX_USE_CPU_SMF
+ void (*ResolveModrm)(BxInstruction_tag *);
+ void (*execute)(BxInstruction_tag *);
+#else
+ void (BX_CPU_C::*ResolveModrm)(BxInstruction_tag *);
+ void (BX_CPU_C::*execute)(BxInstruction_tag *);
+#if BX_SUPPORT_SID
+ void (sid_cpu_c::*execute_sid)(BxInstruction_tag *);
+#endif
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+ BxVoidFPtr_t DTResolveModrm;
+#endif
+#if BX_DYNAMIC_TRANSLATION
+ unsigned DTAttr;
+ Bit8u * (*DTFPtr)(Bit8u *, BxInstruction_tag *);
+ unsigned DTMemRegsUsed;
+#endif
+ } BxInstruction_t;
+
+#if BX_USE_CPU_SMF
+typedef void (*BxExecutePtr_t)(BxInstruction_t *);
+#else
+typedef void (BX_CPU_C::*BxExecutePtr_t)(BxInstruction_t *);
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION
+typedef Bit8u * (*BxDTASResolveModrm_t)(Bit8u *, BxInstruction_t *,
+ unsigned, unsigned);
+#endif
+
+
+#if BX_DYNAMIC_TRANSLATION
+// Arrays of function pointers which handle a specific
+// mod-rm address format
+extern BxDTASResolveModrm_t BxDTResolve32Mod0[];
+extern BxDTASResolveModrm_t BxDTResolve32Mod1or2[];
+extern BxDTASResolveModrm_t BxDTResolve32Mod0Base[];
+extern BxDTASResolveModrm_t BxDTResolve32Mod1or2Base[];
+extern BxDTASResolveModrm_t BxDTResolve16Mod1or2[];
+extern BxDTASResolveModrm_t BxDTResolve16Mod0[];
+#endif
+
+
+#if BX_CPU_LEVEL < 2
+ /* no GDTR or IDTR register in an 8086 */
+#else
+typedef struct {
+ Bit32u base; /* base address: 24bits=286,32bits=386 */
+ Bit16u limit; /* limit, 16bits */
+ } bx_global_segment_reg_t;
+#endif
+
+
+
+
+#if BX_USE_TLB
+ typedef struct {
+ Bit32u lpf; // linear page frame
+ Bit32u ppf; // physical page frame
+ Bit32u pte_addr; // Page Table Address for updating A & D bits
+ Bit32u combined_access;
+ } bx_TLB_entry;
+#endif // #if BX_USE_TLB
+
+
+
+#ifdef BX_BIG_ENDIAN
+typedef struct {
+ union {
+ Bit32u erx;
+ struct {
+ Bit16u word_filler;
+ union {
+ Bit16u rx;
+ struct {
+ Bit8u rh;
+ Bit8u rl;
+ } byte;
+ };
+ } word;
+ };
+ } bx_gen_reg_t;
+#else
+typedef struct {
+ union {
+ Bit32u erx;
+ struct {
+ union {
+ Bit16u rx;
+ struct {
+ Bit8u rl;
+ Bit8u rh;
+ } byte;
+ };
+ Bit16u word_filler;
+ } word;
+ };
+ } bx_gen_reg_t;
+#endif
+
+
+typedef enum {
+ APIC_TYPE_NONE,
+ APIC_TYPE_IOAPIC,
+ APIC_TYPE_LOCAL_APIC
+} bx_apic_type_t;
+
+#if BX_SUPPORT_APIC
+class bx_generic_apic_c : public logfunctions {
+protected:
+ Bit32u base_addr;
+ Bit8u id;
+#define APIC_UNKNOWN_ID 0xff
+#define APIC_VERSION_ID 0x00170011 // same version as 82093 IOAPIC
+public:
+ bx_generic_apic_c ();
+ virtual ~bx_generic_apic_c ();
+ virtual void init ();
+ virtual void hwreset () { }
+ Bit32u get_base (void) { return base_addr; }
+ void set_base (Bit32u newbase);
+ void set_id (Bit8u newid);
+ Bit8u get_id () { return id; }
+ virtual char *get_name();
+ Boolean is_selected (Bit32u addr, Bit32u len);
+ void read (Bit32u addr, void *data, unsigned len);
+ virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
+ virtual void write(Bit32u address, Bit32u *value, unsigned len);
+ virtual void startup_msg (Bit32u vector);
+ // on local APIC, trigger means deliver to the CPU.
+ // on I/O APIC, trigger means direct to another APIC according to table.
+ virtual void trigger_irq (unsigned num, unsigned from);
+ virtual void untrigger_irq (unsigned num, unsigned from);
+ virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode);
+ Boolean deliver (Bit8u destination, Bit8u dest_mode, Bit8u delivery_mode, Bit8u vector, Bit8u polarity, Bit8u trig_mode);
+ virtual Boolean match_logical_addr (Bit8u address);
+ virtual bx_apic_type_t get_type ();
+};
+
+class bx_local_apic_c : public bx_generic_apic_c {
+#define BX_LOCAL_APIC_MAX_INTS 256
+ // TMR=trigger mode register. Cleared for edge-triggered interrupts
+ // and set for level-triggered interrupts. If set, local APIC must send
+ // EOI message to all other APICs. EOI's are not implemented.
+ Bit8u tmr[BX_LOCAL_APIC_MAX_INTS];
+ // IRR=interrupt request register. When an interrupt is triggered by
+ // the I/O APIC or another processor, it sets a bit in irr. The bit is
+ // cleared when the interrupt is acknowledged by the processor.
+ Bit8u irr[BX_LOCAL_APIC_MAX_INTS];
+ // ISR=in-service register. When an IRR bit is cleared, the corresponding
+ // bit in ISR is set. The ISR bit is cleared when
+ Bit8u isr[BX_LOCAL_APIC_MAX_INTS];
+ Bit32u arb_id, arb_priority, task_priority, log_dest, dest_format, spurious_vec;
+ Bit32u lvt[6];
+#define APIC_LVT_TIMER 0
+#define APIC_LVT_THERMAL 1
+#define APIC_LVT_PERFORM 2
+#define APIC_LVT_LINT0 3
+#define APIC_LVT_LINT1 4
+#define APIC_LVT_ERROR 5
+ Bit32u timer_initial, timer_current, timer_divconf;
+ Boolean timer_active; // internal state, not accessible from bus
+ Bit32u timer_divide_counter, timer_divide_factor;
+ Bit32u apic_base_msr;
+ Bit32u icr_high, icr_low;
+ Bit32u err_status;
+#define APIC_ERR_ILLEGAL_ADDR 0x80
+#define APIC_ERR_RX_ILLEGAL_VEC 0x40
+#define APIC_ERR_TX_ILLEGAL_VEC 0x20
+#define APIC_ERR_RX_ACCEPT_ERR 0x08
+#define APIC_ERR_TX_ACCEPT_ERR 0x04
+#define APIC_ERR_RX_CHECKSUM 0x02
+#define APIC_ERR_TX_CHECKSUM 0x01
+public:
+ bx_local_apic_c(BX_CPU_C *mycpu);
+ virtual ~bx_local_apic_c(void);
+ BX_CPU_C *cpu;
+ virtual void hwreset ();
+ virtual void init ();
+ BX_CPU_C *get_cpu (Bit8u id);
+ void set_id (Bit8u newid); // redefine to set cpu->name
+ virtual char *get_name();
+ virtual void write (Bit32u addr, Bit32u *data, unsigned len);
+ virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
+ virtual void startup_msg (Bit32u vector);
+ // on local APIC, trigger means raise the CPU's INTR line. For now
+ // I also have to raise pc_system.INTR but that should be replaced
+ // with the cpu-specific INTR signals.
+ virtual void trigger_irq (unsigned num, unsigned from);
+ virtual void untrigger_irq (unsigned num, unsigned from);
+ Bit8u acknowledge_int (); // only the local CPU should call this
+ int highest_priority_int (Bit8u *array);
+ void service_local_apic ();
+ void print_status ();
+ virtual Boolean match_logical_addr (Bit8u address);
+ virtual Boolean is_local_apic () { return true; }
+ virtual bx_apic_type_t get_type () { return APIC_TYPE_LOCAL_APIC; }
+ virtual Bit32u get_delivery_bitmask (Bit8u dest, Bit8u dest_mode);
+ Bit8u get_ppr ();
+ Bit8u get_apr ();
+ void periodic (Bit32u usec_delta);
+ void set_divide_configuration (Bit32u value);
+ };
+
+#define APIC_MAX_ID 16
+extern bx_generic_apic_c *apic_index[APIC_MAX_ID];
+#endif // if BX_SUPPORT_APIC
+
+
+#if BX_USE_CPU_SMF == 0
+// normal member functions. This can ONLY be used within BX_CPU_C classes.
+// Anyone on the outside should use the BX_CPU macro (defined in bochs.h)
+// instead.
+# define BX_CPU_THIS_PTR this->
+# define BX_SMF
+# define BX_CPU_C_PREFIX BX_CPU_C::
+// with normal member functions, calling a member fn pointer looks like
+// object->*(fnptr)(arg, ...);
+// Since this is different from when SMF=1, encapsulate it in a macro.
+# define BX_CPU_CALL_METHOD(func, args) \
+ (this->*((BxExecutePtr_t) (func))) args
+#else
+// static member functions. With SMF, there is only one CPU by definition.
+# define BX_CPU_THIS_PTR BX_CPU(0)->
+# define BX_SMF static
+# define BX_CPU_C_PREFIX
+# define BX_CPU_CALL_METHOD(func, args) \
+ ((BxExecutePtr_t) (func)) args
+#endif
+
+typedef void (*BxDTShim_t)(void);
+
+#if BX_SUPPORT_SID
+class sid_mem_c;
+#else
+class BX_MEM_C;
+#endif
+
+class BX_CPU_C : public logfunctions {
+
+public: // for now...
+
+ char name[64];
+
+ // General register set
+ // eax: accumulator
+ // ebx: base
+ // ecx: count
+ // edx: data
+ // ebp: base pointer
+ // esi: source index
+ // edi: destination index
+ // esp: stack pointer
+ bx_gen_reg_t gen_reg[8];
+
+ Bit32u eip; // instruction pointer
+#if BX_CPU_LEVEL > 0
+ // so that we can back up when handling faults, exceptions, etc.
+ // we need to store the value of the instruction pointer, before
+ // each fetch/execute cycle.
+ Bit32u prev_eip;
+#endif
+ // A few pointer to functions for use by the dynamic translation
+ // code. Keep them close to the gen_reg declaration, so I can
+ // use an 8bit offset to access them.
+
+#if BX_DYNAMIC_TRANSLATION
+ BxDTShim_t DTWrite8vShim;
+ BxDTShim_t DTWrite16vShim;
+ BxDTShim_t DTWrite32vShim;
+ BxDTShim_t DTRead8vShim;
+ BxDTShim_t DTRead16vShim;
+ BxDTShim_t DTRead32vShim;
+ BxDTShim_t DTReadRMW8vShim;
+ BxDTShim_t DTReadRMW16vShim;
+ BxDTShim_t DTReadRMW32vShim;
+ BxDTShim_t DTWriteRMW8vShim;
+ BxDTShim_t DTWriteRMW16vShim;
+ BxDTShim_t DTWriteRMW32vShim;
+ BxDTShim_t DTSetFlagsOSZAPCPtr;
+ BxDTShim_t DTIndBrHandler;
+ BxDTShim_t DTDirBrHandler;
+#endif
+
+ // status and control flags register set
+ Bit32u lf_flags_status;
+ Boolean lf_pf;
+ bx_flags_reg_t eflags;
+
+ bx_lf_flags_entry oszapc;
+ bx_lf_flags_entry oszap;
+
+ Bit32u prev_esp;
+
+#define BX_INHIBIT_INTERRUPTS 0x01
+#define BX_INHIBIT_DEBUG 0x02
+ // What events to inhibit at any given time. Certain instructions
+ // inhibit interrupts, some debug exceptions and single-step traps.
+ unsigned inhibit_mask;
+
+ /* user segment register set */
+ bx_segment_reg_t sregs[6];
+
+ /* system segment registers */
+#if BX_CPU_LEVEL >= 2
+ bx_global_segment_reg_t gdtr; /* global descriptor table register */
+ bx_global_segment_reg_t idtr; /* interrupt descriptor table register */
+#endif
+ bx_segment_reg_t ldtr; /* interrupt descriptor table register */
+ bx_segment_reg_t tr; /* task register */
+
+
+ /* debug registers 0-7 (unimplemented) */
+#if BX_CPU_LEVEL >= 3
+ Bit32u dr0;
+ Bit32u dr1;
+ Bit32u dr2;
+ Bit32u dr3;
+ Bit32u dr6;
+ Bit32u dr7;
+#endif
+
+ /* TR3 - TR7 (Test Register 3-7), unimplemented */
+
+ /* Control registers */
+#if BX_CPU_LEVEL >= 2
+ bx_cr0_t cr0;
+ Bit32u cr1;
+ Bit32u cr2;
+ Bit32u cr3;
+#endif
+#if BX_CPU_LEVEL >= 4
+ Bit32u cr4;
+#endif
+
+#if BX_SUPPORT_SID
+ sid_mem_c *mem;
+#else
+ // pointer to the address space that this processor uses.
+ BX_MEM_C *mem;
+#endif
+
+ Boolean EXT; /* 1 if processing external interrupt or exception
+ * or if not related to current instruction,
+ * 0 if current CS:IP caused exception */
+ unsigned errorno; /* signal exception during instruction emulation */
+
+ Bit32u debug_trap; // holds DR6 value to be set as well
+ volatile Boolean async_event;
+ volatile Boolean INTR;
+
+ // for accessing registers by index number
+ Bit16u *_16bit_base_reg[8];
+ Bit16u *_16bit_index_reg[8];
+ Bit32u empty_register;
+
+ // for decoding instructions; accessing seg reg's by index
+ unsigned sreg_mod00_rm16[8];
+ unsigned sreg_mod01_rm16[8];
+ unsigned sreg_mod10_rm16[8];
+ unsigned sreg_mod01_rm32[8];
+ unsigned sreg_mod10_rm32[8];
+ unsigned sreg_mod0_base32[8];
+ unsigned sreg_mod1or2_base32[8];
+
+ // for exceptions
+ jmp_buf jmp_buf_env;
+ Bit8u curr_exception[2];
+
+ static const Boolean is_exception_OK[3][3];
+
+ bx_segment_reg_t save_cs;
+ bx_segment_reg_t save_ss;
+ 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;
+
+#if BX_DEBUGGER
+ Bit8u break_point;
+#ifdef MAGIC_BREAKPOINT
+ Bit8u magic_break;
+#endif
+ Bit8u stop_reason;
+ Bit8u trace;
+ Bit8u mode_break; /* BW */
+ Boolean debug_vm; /* BW contains current mode*/
+ Bit8u show_eip; /* BW record eip at special instr f.ex eip */
+ Bit8u show_flag; /* BW shows instr class executed */
+ bx_guard_found_t guard_found;
+#endif
+
+ // for paging
+#if BX_USE_TLB
+ struct {
+ bx_TLB_entry entry[BX_TLB_SIZE];
+ } TLB;
+#endif
+
+ struct {
+ Bit32u paddress1; // physical address after translation of 1st len1 bytes of data
+ Bit32u paddress2; // physical address after translation of 2nd len2 bytes of data
+ Bit32u len1; // number of bytes in page 1
+ Bit32u len2; // number of bytes in page 2
+ unsigned pages; // number of pages access spans (1 or 2)
+ } address_xlation;
+
+ // for lazy flags processing
+ BX_SMF Boolean get_OF(void);
+ BX_SMF Boolean get_SF(void);
+ BX_SMF Boolean get_ZF(void);
+ BX_SMF Boolean get_AF(void);
+ BX_SMF Boolean get_PF(void);
+ BX_SMF Boolean get_CF(void);
+
+ // constructors & destructors...
+ BX_CPU_C();
+ ~BX_CPU_C(void);
+#if BX_SUPPORT_SID
+ void init (sid_mem_c *addrspace);
+#else
+ void init (BX_MEM_C *addrspace);
+#endif
+
+ // prototypes for CPU instructions...
+ BX_SMF void ADD_EbGb(BxInstruction_t *);
+ BX_SMF void ADD_EdGd(BxInstruction_t *);
+ BX_SMF void ADD_GbEb(BxInstruction_t *);
+ BX_SMF void ADD_GdEd(BxInstruction_t *);
+ BX_SMF void ADD_ALIb(BxInstruction_t *);
+ BX_SMF void ADD_EAXId(BxInstruction_t *);
+ BX_SMF void OR_EbGb(BxInstruction_t *);
+ BX_SMF void OR_EdGd(BxInstruction_t *);
+ BX_SMF void OR_EwGw(BxInstruction_t *);
+ BX_SMF void OR_GbEb(BxInstruction_t *);
+ BX_SMF void OR_GdEd(BxInstruction_t *);
+ BX_SMF void OR_GwEw(BxInstruction_t *);
+ BX_SMF void OR_ALIb(BxInstruction_t *);
+ BX_SMF void OR_EAXId(BxInstruction_t *);
+ BX_SMF void OR_AXIw(BxInstruction_t *);
+
+ BX_SMF void PUSH_CS(BxInstruction_t *);
+ BX_SMF void PUSH_DS(BxInstruction_t *);
+ BX_SMF void POP_DS(BxInstruction_t *);
+ BX_SMF void PUSH_ES(BxInstruction_t *);
+ BX_SMF void POP_ES(BxInstruction_t *);
+ BX_SMF void PUSH_FS(BxInstruction_t *);
+ BX_SMF void POP_FS(BxInstruction_t *);
+ BX_SMF void PUSH_GS(BxInstruction_t *);
+ BX_SMF void POP_GS(BxInstruction_t *);
+ BX_SMF void PUSH_SS(BxInstruction_t *);
+ BX_SMF void POP_SS(BxInstruction_t *);
+
+ BX_SMF void ADC_EbGb(BxInstruction_t *);
+ BX_SMF void ADC_EdGd(BxInstruction_t *);
+ BX_SMF void ADC_GbEb(BxInstruction_t *);
+ BX_SMF void ADC_GdEd(BxInstruction_t *);
+ BX_SMF void ADC_ALIb(BxInstruction_t *);
+ BX_SMF void ADC_EAXId(BxInstruction_t *);
+ BX_SMF void SBB_EbGb(BxInstruction_t *);
+ BX_SMF void SBB_EdGd(BxInstruction_t *);
+ BX_SMF void SBB_GbEb(BxInstruction_t *);
+ BX_SMF void SBB_GdEd(BxInstruction_t *);
+ BX_SMF void SBB_ALIb(BxInstruction_t *);
+ BX_SMF void SBB_EAXId(BxInstruction_t *);
+
+ BX_SMF void AND_EbGb(BxInstruction_t *);
+ BX_SMF void AND_EdGd(BxInstruction_t *);
+ BX_SMF void AND_EwGw(BxInstruction_t *);
+ BX_SMF void AND_GbEb(BxInstruction_t *);
+ BX_SMF void AND_GdEd(BxInstruction_t *);
+ BX_SMF void AND_GwEw(BxInstruction_t *);
+ BX_SMF void AND_ALIb(BxInstruction_t *);
+ BX_SMF void AND_EAXId(BxInstruction_t *);
+ BX_SMF void AND_AXIw(BxInstruction_t *);
+ BX_SMF void DAA(BxInstruction_t *);
+ BX_SMF void SUB_EbGb(BxInstruction_t *);
+ BX_SMF void SUB_EdGd(BxInstruction_t *);
+ BX_SMF void SUB_GbEb(BxInstruction_t *);
+ BX_SMF void SUB_GdEd(BxInstruction_t *);
+ BX_SMF void SUB_ALIb(BxInstruction_t *);
+ BX_SMF void SUB_EAXId(BxInstruction_t *);
+ BX_SMF void DAS(BxInstruction_t *);
+
+ BX_SMF void XOR_EbGb(BxInstruction_t *);
+ BX_SMF void XOR_EdGd(BxInstruction_t *);
+ BX_SMF void XOR_EwGw(BxInstruction_t *);
+ BX_SMF void XOR_GbEb(BxInstruction_t *);
+ BX_SMF void XOR_GdEd(BxInstruction_t *);
+ BX_SMF void XOR_GwEw(BxInstruction_t *);
+ BX_SMF void XOR_ALIb(BxInstruction_t *);
+ BX_SMF void XOR_EAXId(BxInstruction_t *);
+ BX_SMF void XOR_AXIw(BxInstruction_t *);
+ BX_SMF void AAA(BxInstruction_t *);
+ BX_SMF void CMP_EbGb(BxInstruction_t *);
+ BX_SMF void CMP_EdGd(BxInstruction_t *);
+ BX_SMF void CMP_GbEb(BxInstruction_t *);
+ BX_SMF void CMP_GdEd(BxInstruction_t *);
+ BX_SMF void CMP_ALIb(BxInstruction_t *);
+ BX_SMF void CMP_EAXId(BxInstruction_t *);
+ BX_SMF void AAS(BxInstruction_t *);
+
+ BX_SMF void PUSHAD32(BxInstruction_t *);
+ BX_SMF void PUSHAD16(BxInstruction_t *);
+ BX_SMF void POPAD32(BxInstruction_t *);
+ BX_SMF void POPAD16(BxInstruction_t *);
+ BX_SMF void BOUND_GvMa(BxInstruction_t *);
+ BX_SMF void ARPL_EwGw(BxInstruction_t *);
+ BX_SMF void PUSH_Id(BxInstruction_t *);
+ BX_SMF void PUSH_Iw(BxInstruction_t *);
+ BX_SMF void IMUL_GdEdId(BxInstruction_t *);
+ BX_SMF void INSB_YbDX(BxInstruction_t *);
+ BX_SMF void INSW_YvDX(BxInstruction_t *);
+ BX_SMF void OUTSB_DXXb(BxInstruction_t *);
+ BX_SMF void OUTSW_DXXv(BxInstruction_t *);
+
+ BX_SMF void TEST_EbGb(BxInstruction_t *);
+ BX_SMF void TEST_EdGd(BxInstruction_t *);
+ BX_SMF void TEST_EwGw(BxInstruction_t *);
+ BX_SMF void XCHG_EbGb(BxInstruction_t *);
+ BX_SMF void XCHG_EdGd(BxInstruction_t *);
+ BX_SMF void XCHG_EwGw(BxInstruction_t *);
+ BX_SMF void MOV_EbGb(BxInstruction_t *);
+ BX_SMF void MOV_EdGd(BxInstruction_t *);
+ BX_SMF void MOV_EwGw(BxInstruction_t *);
+ BX_SMF void MOV_GbEb(BxInstruction_t *);
+ BX_SMF void MOV_GdEd(BxInstruction_t *);
+ BX_SMF void MOV_GwEw(BxInstruction_t *);
+ BX_SMF void MOV_EwSw(BxInstruction_t *);
+ BX_SMF void LEA_GdM(BxInstruction_t *);
+ BX_SMF void LEA_GwM(BxInstruction_t *);
+ BX_SMF void MOV_SwEw(BxInstruction_t *);
+ BX_SMF void POP_Ev(BxInstruction_t *);
+
+ BX_SMF void CBW(BxInstruction_t *);
+ BX_SMF void CWD(BxInstruction_t *);
+ BX_SMF void CALL32_Ap(BxInstruction_t *);
+ BX_SMF void CALL16_Ap(BxInstruction_t *);
+ BX_SMF void FWAIT(BxInstruction_t *);
+ BX_SMF void PUSHF_Fv(BxInstruction_t *);
+ BX_SMF void POPF_Fv(BxInstruction_t *);
+ BX_SMF void SAHF(BxInstruction_t *);
+ BX_SMF void LAHF(BxInstruction_t *);
+
+ BX_SMF void MOV_ALOb(BxInstruction_t *);
+ BX_SMF void MOV_EAXOd(BxInstruction_t *);
+ BX_SMF void MOV_AXOw(BxInstruction_t *);
+ BX_SMF void MOV_ObAL(BxInstruction_t *);
+ BX_SMF void MOV_OdEAX(BxInstruction_t *);
+ BX_SMF void MOV_OwAX(BxInstruction_t *);
+ BX_SMF void MOVSB_XbYb(BxInstruction_t *);
+ BX_SMF void MOVSW_XvYv(BxInstruction_t *);
+ BX_SMF void CMPSB_XbYb(BxInstruction_t *);
+ BX_SMF void CMPSW_XvYv(BxInstruction_t *);
+ BX_SMF void TEST_ALIb(BxInstruction_t *);
+ BX_SMF void TEST_EAXId(BxInstruction_t *);
+ BX_SMF void TEST_AXIw(BxInstruction_t *);
+ BX_SMF void STOSB_YbAL(BxInstruction_t *);
+ BX_SMF void STOSW_YveAX(BxInstruction_t *);
+ BX_SMF void LODSB_ALXb(BxInstruction_t *);
+ BX_SMF void LODSW_eAXXv(BxInstruction_t *);
+ BX_SMF void SCASB_ALXb(BxInstruction_t *);
+ BX_SMF void SCASW_eAXXv(BxInstruction_t *);
+
+ BX_SMF void RETnear32(BxInstruction_t *);
+ BX_SMF void RETnear16(BxInstruction_t *);
+ BX_SMF void LES_GvMp(BxInstruction_t *);
+ BX_SMF void LDS_GvMp(BxInstruction_t *);
+ BX_SMF void MOV_EbIb(BxInstruction_t *);
+ BX_SMF void MOV_EdId(BxInstruction_t *);
+ BX_SMF void MOV_EwIw(BxInstruction_t *);
+ BX_SMF void ENTER_IwIb(BxInstruction_t *);
+ BX_SMF void LEAVE(BxInstruction_t *);
+ BX_SMF void RETfar32(BxInstruction_t *);
+ BX_SMF void RETfar16(BxInstruction_t *);
+
+ BX_SMF void INT1(BxInstruction_t *);
+ BX_SMF void INT3(BxInstruction_t *);
+ BX_SMF void INT_Ib(BxInstruction_t *);
+ BX_SMF void INTO(BxInstruction_t *);
+ BX_SMF void IRET32(BxInstruction_t *);
+ BX_SMF void IRET16(BxInstruction_t *);
+
+ BX_SMF void AAM(BxInstruction_t *);
+ BX_SMF void AAD(BxInstruction_t *);
+ BX_SMF void SALC(BxInstruction_t *);
+ BX_SMF void XLAT(BxInstruction_t *);
+
+ BX_SMF void LOOPNE_Jb(BxInstruction_t *);
+ BX_SMF void LOOPE_Jb(BxInstruction_t *);
+ BX_SMF void LOOP_Jb(BxInstruction_t *);
+ BX_SMF void JCXZ_Jb(BxInstruction_t *);
+ BX_SMF void IN_ALIb(BxInstruction_t *);
+ BX_SMF void IN_eAXIb(BxInstruction_t *);
+ BX_SMF void OUT_IbAL(BxInstruction_t *);
+ BX_SMF void OUT_IbeAX(BxInstruction_t *);
+ BX_SMF void CALL_Aw(BxInstruction_t *);
+ BX_SMF void CALL_Ad(BxInstruction_t *);
+ BX_SMF void JMP_Jd(BxInstruction_t *);
+ BX_SMF void JMP_Jw(BxInstruction_t *);
+ BX_SMF void JMP_Ap(BxInstruction_t *);
+ BX_SMF void IN_ALDX(BxInstruction_t *);
+ BX_SMF void IN_eAXDX(BxInstruction_t *);
+ BX_SMF void OUT_DXAL(BxInstruction_t *);
+ BX_SMF void OUT_DXeAX(BxInstruction_t *);
+
+ BX_SMF void HLT(BxInstruction_t *);
+ BX_SMF void CMC(BxInstruction_t *);
+ BX_SMF void CLC(BxInstruction_t *);
+ BX_SMF void STC(BxInstruction_t *);
+ BX_SMF void CLI(BxInstruction_t *);
+ BX_SMF void STI(BxInstruction_t *);
+ BX_SMF void CLD(BxInstruction_t *);
+ BX_SMF void STD(BxInstruction_t *);
+
+
+ BX_SMF void LAR_GvEw(BxInstruction_t *);
+ BX_SMF void LSL_GvEw(BxInstruction_t *);
+ BX_SMF void CLTS(BxInstruction_t *);
+ BX_SMF void INVD(BxInstruction_t *);
+ BX_SMF void WBINVD(BxInstruction_t *);
+
+ BX_SMF void MOV_CdRd(BxInstruction_t *);
+ BX_SMF void MOV_DdRd(BxInstruction_t *);
+ BX_SMF void MOV_RdCd(BxInstruction_t *);
+ BX_SMF void MOV_RdDd(BxInstruction_t *);
+ BX_SMF void MOV_TdRd(BxInstruction_t *);
+ BX_SMF void MOV_RdTd(BxInstruction_t *);
+
+ BX_SMF void JCC_Jd(BxInstruction_t *);
+ BX_SMF void JCC_Jw(BxInstruction_t *);
+
+ BX_SMF void SETO_Eb(BxInstruction_t *);
+ BX_SMF void SETNO_Eb(BxInstruction_t *);
+ BX_SMF void SETB_Eb(BxInstruction_t *);
+ BX_SMF void SETNB_Eb(BxInstruction_t *);
+ BX_SMF void SETZ_Eb(BxInstruction_t *);
+ BX_SMF void SETNZ_Eb(BxInstruction_t *);
+ BX_SMF void SETBE_Eb(BxInstruction_t *);
+ BX_SMF void SETNBE_Eb(BxInstruction_t *);
+ BX_SMF void SETS_Eb(BxInstruction_t *);
+ BX_SMF void SETNS_Eb(BxInstruction_t *);
+ BX_SMF void SETP_Eb(BxInstruction_t *);
+ BX_SMF void SETNP_Eb(BxInstruction_t *);
+ BX_SMF void SETL_Eb(BxInstruction_t *);
+ BX_SMF void SETNL_Eb(BxInstruction_t *);
+ BX_SMF void SETLE_Eb(BxInstruction_t *);
+ BX_SMF void SETNLE_Eb(BxInstruction_t *);
+
+ BX_SMF void CPUID(BxInstruction_t *);
+ BX_SMF void BT_EvGv(BxInstruction_t *);
+ BX_SMF void SHLD_EdGd(BxInstruction_t *);
+ BX_SMF void SHLD_EwGw(BxInstruction_t *);
+
+
+ BX_SMF void BTS_EvGv(BxInstruction_t *);
+
+ BX_SMF void SHRD_EwGw(BxInstruction_t *);
+ BX_SMF void SHRD_EdGd(BxInstruction_t *);
+
+ BX_SMF void IMUL_GdEd(BxInstruction_t *);
+
+ BX_SMF void LSS_GvMp(BxInstruction_t *);
+ BX_SMF void BTR_EvGv(BxInstruction_t *);
+ BX_SMF void LFS_GvMp(BxInstruction_t *);
+ BX_SMF void LGS_GvMp(BxInstruction_t *);
+ BX_SMF void MOVZX_GdEb(BxInstruction_t *);
+ BX_SMF void MOVZX_GwEb(BxInstruction_t *);
+ BX_SMF void MOVZX_GdEw(BxInstruction_t *);
+ BX_SMF void MOVZX_GwEw(BxInstruction_t *);
+ BX_SMF void BTC_EvGv(BxInstruction_t *);
+ BX_SMF void BSF_GvEv(BxInstruction_t *);
+ BX_SMF void BSR_GvEv(BxInstruction_t *);
+ BX_SMF void MOVSX_GdEb(BxInstruction_t *);
+ BX_SMF void MOVSX_GwEb(BxInstruction_t *);
+ BX_SMF void MOVSX_GdEw(BxInstruction_t *);
+ BX_SMF void MOVSX_GwEw(BxInstruction_t *);
+
+ BX_SMF void BSWAP_EAX(BxInstruction_t *);
+ BX_SMF void BSWAP_ECX(BxInstruction_t *);
+ BX_SMF void BSWAP_EDX(BxInstruction_t *);
+ BX_SMF void BSWAP_EBX(BxInstruction_t *);
+ BX_SMF void BSWAP_ESP(BxInstruction_t *);
+ BX_SMF void BSWAP_EBP(BxInstruction_t *);
+ BX_SMF void BSWAP_ESI(BxInstruction_t *);
+ BX_SMF void BSWAP_EDI(BxInstruction_t *);
+
+ BX_SMF void ADD_EbIb(BxInstruction_t *);
+ BX_SMF void ADC_EbIb(BxInstruction_t *);
+ BX_SMF void SBB_EbIb(BxInstruction_t *);
+ BX_SMF void SUB_EbIb(BxInstruction_t *);
+ BX_SMF void CMP_EbIb(BxInstruction_t *);
+
+ BX_SMF void XOR_EbIb(BxInstruction_t *);
+ BX_SMF void OR_EbIb(BxInstruction_t *);
+ BX_SMF void AND_EbIb(BxInstruction_t *);
+
+ BX_SMF void ADD_EdId(BxInstruction_t *);
+ BX_SMF void OR_EdId(BxInstruction_t *);
+ BX_SMF void OR_EwIw(BxInstruction_t *);
+ BX_SMF void ADC_EdId(BxInstruction_t *);
+ BX_SMF void SBB_EdId(BxInstruction_t *);
+ BX_SMF void AND_EdId(BxInstruction_t *);
+ BX_SMF void AND_EwIw(BxInstruction_t *);
+ BX_SMF void SUB_EdId(BxInstruction_t *);
+ BX_SMF void XOR_EdId(BxInstruction_t *);
+ BX_SMF void XOR_EwIw(BxInstruction_t *);
+ BX_SMF void CMP_EdId(BxInstruction_t *);
+
+ BX_SMF void ROL_Eb(BxInstruction_t *);
+ BX_SMF void ROR_Eb(BxInstruction_t *);
+ BX_SMF void RCL_Eb(BxInstruction_t *);
+ BX_SMF void RCR_Eb(BxInstruction_t *);
+ BX_SMF void SHL_Eb(BxInstruction_t *);
+ BX_SMF void SHR_Eb(BxInstruction_t *);
+ BX_SMF void SAR_Eb(BxInstruction_t *);
+
+ BX_SMF void ROL_Ed(BxInstruction_t *);
+ BX_SMF void ROL_Ew(BxInstruction_t *);
+ BX_SMF void ROR_Ed(BxInstruction_t *);
+ BX_SMF void ROR_Ew(BxInstruction_t *);
+ BX_SMF void RCL_Ed(BxInstruction_t *);
+ BX_SMF void RCL_Ew(BxInstruction_t *);
+ BX_SMF void RCR_Ed(BxInstruction_t *);
+ BX_SMF void RCR_Ew(BxInstruction_t *);
+ BX_SMF void SHL_Ed(BxInstruction_t *);
+ BX_SMF void SHL_Ew(BxInstruction_t *);
+ BX_SMF void SHR_Ed(BxInstruction_t *);
+ BX_SMF void SHR_Ew(BxInstruction_t *);
+ BX_SMF void SAR_Ed(BxInstruction_t *);
+ BX_SMF void SAR_Ew(BxInstruction_t *);
+
+ BX_SMF void TEST_EbIb(BxInstruction_t *);
+ BX_SMF void NOT_Eb(BxInstruction_t *);
+ BX_SMF void NEG_Eb(BxInstruction_t *);
+ BX_SMF void MUL_ALEb(BxInstruction_t *);
+ BX_SMF void IMUL_ALEb(BxInstruction_t *);
+ BX_SMF void DIV_ALEb(BxInstruction_t *);
+ BX_SMF void IDIV_ALEb(BxInstruction_t *);
+
+ BX_SMF void TEST_EdId(BxInstruction_t *);
+ BX_SMF void TEST_EwIw(BxInstruction_t *);
+ BX_SMF void NOT_Ed(BxInstruction_t *);
+ BX_SMF void NOT_Ew(BxInstruction_t *);
+ BX_SMF void NEG_Ed(BxInstruction_t *);
+ BX_SMF void MUL_EAXEd(BxInstruction_t *);
+ BX_SMF void IMUL_EAXEd(BxInstruction_t *);
+ BX_SMF void DIV_EAXEd(BxInstruction_t *);
+ BX_SMF void IDIV_EAXEd(BxInstruction_t *);
+
+ BX_SMF void INC_Eb(BxInstruction_t *);
+ BX_SMF void DEC_Eb(BxInstruction_t *);
+
+ BX_SMF void INC_Ed(BxInstruction_t *);
+ BX_SMF void DEC_Ed(BxInstruction_t *);
+ BX_SMF void CALL_Ed(BxInstruction_t *);
+ BX_SMF void CALL_Ew(BxInstruction_t *);
+ BX_SMF void CALL32_Ep(BxInstruction_t *);
+ BX_SMF void CALL16_Ep(BxInstruction_t *);
+ BX_SMF void JMP_Ed(BxInstruction_t *);
+ BX_SMF void JMP_Ew(BxInstruction_t *);
+ BX_SMF void JMP32_Ep(BxInstruction_t *);
+ BX_SMF void JMP16_Ep(BxInstruction_t *);
+ BX_SMF void PUSH_Ed(BxInstruction_t *);
+ BX_SMF void PUSH_Ew(BxInstruction_t *);
+
+ BX_SMF void SLDT_Ew(BxInstruction_t *);
+ BX_SMF void STR_Ew(BxInstruction_t *);
+ BX_SMF void LLDT_Ew(BxInstruction_t *);
+ BX_SMF void LTR_Ew(BxInstruction_t *);
+ BX_SMF void VERR_Ew(BxInstruction_t *);
+ BX_SMF void VERW_Ew(BxInstruction_t *);
+
+ BX_SMF void SGDT_Ms(BxInstruction_t *);
+ BX_SMF void SIDT_Ms(BxInstruction_t *);
+ BX_SMF void LGDT_Ms(BxInstruction_t *);
+ BX_SMF void LIDT_Ms(BxInstruction_t *);
+ BX_SMF void SMSW_Ew(BxInstruction_t *);
+ BX_SMF void LMSW_Ew(BxInstruction_t *);
+
+
+ BX_SMF void BT_EvIb(BxInstruction_t *);
+ BX_SMF void BTS_EvIb(BxInstruction_t *);
+ BX_SMF void BTR_EvIb(BxInstruction_t *);
+ BX_SMF void BTC_EvIb(BxInstruction_t *);
+
+ BX_SMF void ESC0(BxInstruction_t *);
+ BX_SMF void ESC1(BxInstruction_t *);
+ BX_SMF void ESC2(BxInstruction_t *);
+ BX_SMF void ESC3(BxInstruction_t *);
+ BX_SMF void ESC4(BxInstruction_t *);
+ BX_SMF void ESC5(BxInstruction_t *);
+ BX_SMF void ESC6(BxInstruction_t *);
+ BX_SMF void ESC7(BxInstruction_t *);
+
+ BX_SMF void fpu_execute(BxInstruction_t *i);
+ BX_SMF void fpu_init(void);
+
+ BX_SMF void CMPXCHG_XBTS(BxInstruction_t *);
+ BX_SMF void CMPXCHG_IBTS(BxInstruction_t *);
+ BX_SMF void CMPXCHG_EbGb(BxInstruction_t *);
+ BX_SMF void CMPXCHG_EdGd(BxInstruction_t *);
+ BX_SMF void CMPXCHG8B(BxInstruction_t *);
+ BX_SMF void XADD_EbGb(BxInstruction_t *);
+ BX_SMF void XADD_EdGd(BxInstruction_t *);
+ BX_SMF void RETnear32_Iw(BxInstruction_t *);
+ BX_SMF void RETnear16_Iw(BxInstruction_t *);
+ BX_SMF void RETfar32_Iw(BxInstruction_t *);
+ BX_SMF void RETfar16_Iw(BxInstruction_t *);
+
+ BX_SMF void LOADALL(BxInstruction_t *);
+ BX_SMF void CMOV_GdEd(BxInstruction_t *);
+ BX_SMF void CMOV_GwEw(BxInstruction_t *);
+
+ BX_SMF void ADD_EwGw(BxInstruction_t *);
+ BX_SMF void ADD_GwEw(BxInstruction_t *);
+ BX_SMF void ADD_AXIw(BxInstruction_t *);
+ BX_SMF void ADC_EwGw(BxInstruction_t *);
+ BX_SMF void ADC_GwEw(BxInstruction_t *);
+ BX_SMF void ADC_AXIw(BxInstruction_t *);
+ BX_SMF void SBB_EwGw(BxInstruction_t *);
+ BX_SMF void SBB_GwEw(BxInstruction_t *);
+ BX_SMF void SBB_AXIw(BxInstruction_t *);
+ BX_SMF void SBB_EwIw(BxInstruction_t *);
+ BX_SMF void SUB_EwGw(BxInstruction_t *);
+ BX_SMF void SUB_GwEw(BxInstruction_t *);
+ BX_SMF void SUB_AXIw(BxInstruction_t *);
+ BX_SMF void CMP_EwGw(BxInstruction_t *);
+ BX_SMF void CMP_GwEw(BxInstruction_t *);
+ BX_SMF void CMP_AXIw(BxInstruction_t *);
+ BX_SMF void CWDE(BxInstruction_t *);
+ BX_SMF void CDQ(BxInstruction_t *);
+ BX_SMF void XADD_EwGw(BxInstruction_t *);
+ BX_SMF void ADD_EwIw(BxInstruction_t *);
+ BX_SMF void ADC_EwIw(BxInstruction_t *);
+ BX_SMF void SUB_EwIw(BxInstruction_t *);
+ BX_SMF void CMP_EwIw(BxInstruction_t *);
+ BX_SMF void NEG_Ew(BxInstruction_t *);
+ BX_SMF void INC_Ew(BxInstruction_t *);
+ BX_SMF void DEC_Ew(BxInstruction_t *);
+ BX_SMF void CMPXCHG_EwGw(BxInstruction_t *);
+ BX_SMF void MUL_AXEw(BxInstruction_t *);
+ BX_SMF void IMUL_AXEw(BxInstruction_t *);
+ BX_SMF void DIV_AXEw(BxInstruction_t *);
+ BX_SMF void IDIV_AXEw(BxInstruction_t *);
+ BX_SMF void IMUL_GwEwIw(BxInstruction_t *);
+ BX_SMF void IMUL_GwEw(BxInstruction_t *);
+ BX_SMF void NOP(BxInstruction_t *);
+ BX_SMF void MOV_RLIb(BxInstruction_t *);
+ BX_SMF void MOV_RHIb(BxInstruction_t *);
+ BX_SMF void MOV_RXIw(BxInstruction_t *);
+ BX_SMF void MOV_ERXId(BxInstruction_t *);
+ BX_SMF void INC_RX(BxInstruction_t *);
+ BX_SMF void DEC_RX(BxInstruction_t *);
+ BX_SMF void INC_ERX(BxInstruction_t *);
+ BX_SMF void DEC_ERX(BxInstruction_t *);
+ BX_SMF void PUSH_RX(BxInstruction_t *);
+ BX_SMF void POP_RX(BxInstruction_t *);
+ BX_SMF void PUSH_ERX(BxInstruction_t *);
+ BX_SMF void POP_ERX(BxInstruction_t *);
+ BX_SMF void POP_Ew(BxInstruction_t *);
+ BX_SMF void POP_Ed(BxInstruction_t *);
+ BX_SMF void XCHG_RXAX(BxInstruction_t *);
+ BX_SMF void XCHG_ERXEAX(BxInstruction_t *);
+
+ // mch added
+ BX_SMF void INVLPG(BxInstruction_t *);
+ BX_SMF void wait_for_interrupt();
+ BX_SMF void RSM(BxInstruction_t *);
+
+ BX_SMF void WRMSR(BxInstruction_t *);
+ BX_SMF void RDTSC(BxInstruction_t *);
+ BX_SMF void RDMSR(BxInstruction_t *);
+ BX_SMF void SetCR0(Bit32u val_32);
+ BX_SMF void dynamic_translate(void);
+ BX_SMF void dynamic_init(void);
+ BX_SMF unsigned FetchDecode(Bit8u *, BxInstruction_t *, unsigned, Boolean);
+ BX_SMF void UndefinedOpcode(BxInstruction_t *);
+ BX_SMF void BxError(BxInstruction_t *i);
+ BX_SMF void BxResolveError(BxInstruction_t *i);
+
+ BX_SMF void Resolve16Mod0Rm0(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm1(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm2(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm3(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm4(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm5(BxInstruction_t *);
+ BX_SMF void Resolve16Mod0Rm7(BxInstruction_t *);
+
+ BX_SMF void Resolve16Mod1or2Rm0(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm1(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm2(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm3(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm4(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm5(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm6(BxInstruction_t *);
+ BX_SMF void Resolve16Mod1or2Rm7(BxInstruction_t *);
+
+ BX_SMF void Resolve32Mod0Rm0(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Rm1(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Rm2(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Rm3(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Rm6(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Rm7(BxInstruction_t *);
+
+ BX_SMF void Resolve32Mod1or2Rm0(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm1(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm2(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm3(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm5(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm6(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Rm7(BxInstruction_t *);
+
+ BX_SMF void Resolve32Mod0Base0(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base1(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base2(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base3(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base4(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base5(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base6(BxInstruction_t *);
+ BX_SMF void Resolve32Mod0Base7(BxInstruction_t *);
+
+ BX_SMF void Resolve32Mod1or2Base0(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base1(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base2(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base3(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base4(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base5(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base6(BxInstruction_t *);
+ BX_SMF void Resolve32Mod1or2Base7(BxInstruction_t *);
+
+
+ BX_SMF void REP(void (*)(void));
+ BX_SMF void REP_ZF(void (*)(void), unsigned rep_prefix);
+#if BX_DEBUGGER
+ BX_SMF void dbg_take_irq(void);
+ BX_SMF void dbg_force_interrupt(unsigned vector);
+ BX_SMF void dbg_take_dma(void);
+ BX_SMF Boolean dbg_get_cpu(bx_dbg_cpu_t *cpu);
+ BX_SMF Boolean dbg_set_cpu(bx_dbg_cpu_t *cpu);
+ BX_SMF Boolean dbg_set_reg(unsigned reg, Bit32u val);
+ BX_SMF Bit32u dbg_get_reg(unsigned reg);
+ BX_SMF Boolean dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no);
+ BX_SMF unsigned dbg_query_pending(void);
+ BX_SMF Bit32u dbg_get_descriptor_l(bx_descriptor_t *);
+ BX_SMF Bit32u dbg_get_descriptor_h(bx_descriptor_t *);
+ BX_SMF Bit32u dbg_get_eflags(void);
+ BX_SMF Boolean dbg_is_begin_instr_bpoint(Bit32u cs, Bit32u eip, Bit32u laddr,
+ Bit32u is_32);
+ BX_SMF Boolean dbg_is_end_instr_bpoint(Bit32u cs, Bit32u eip,
+ Bit32u laddr, Bit32u is_32);
+#endif
+#if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION
+ BX_SMF void dbg_xlate_linear2phy(Bit32u linear, Bit32u *phy, Boolean *valid);
+#endif
+ BX_SMF void atexit(void);
+
+ // now for some ancillary functions...
+ BX_SMF void cpu_loop(Bit32s max_instr_count);
+ BX_SMF void decode_exgx16(unsigned need_fetch);
+ BX_SMF void decode_exgx32(unsigned need_fetch);
+
+ BX_SMF void prefetch(void);
+ BX_SMF void revalidate_prefetch_q(void);
+ BX_SMF void invalidate_prefetch_q(void);
+
+ BX_SMF void write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
+ BX_SMF void read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length);
+ BX_SMF void write_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+ BX_SMF void write_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+ BX_SMF void write_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+ BX_SMF void read_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+ BX_SMF void read_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+ BX_SMF void read_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+
+ BX_SMF void read_RMW_virtual_byte(unsigned seg, Bit32u offset, Bit8u *data);
+ BX_SMF void read_RMW_virtual_word(unsigned seg, Bit32u offset, Bit16u *data);
+ BX_SMF void read_RMW_virtual_dword(unsigned seg, Bit32u offset, Bit32u *data);
+ BX_SMF void write_RMW_virtual_byte(Bit8u val8);
+ BX_SMF void write_RMW_virtual_word(Bit16u val16);
+ BX_SMF void write_RMW_virtual_dword(Bit32u val32);
+
+ BX_SMF void access_linear(Bit32u address, unsigned length, unsigned pl,
+ unsigned rw, void *data);
+#if BX_SUPPORT_PAGING
+ BX_SMF Bit32u itranslate_linear(Bit32u laddress, unsigned pl);
+ BX_SMF Bit32u dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw);
+#endif // BX_SUPPORT_PAGING
+ BX_SMF void TLB_flush(void);
+ BX_SMF void TLB_clear(void);
+ BX_SMF void TLB_init(void);
+ BX_SMF void set_INTR(Boolean value);
+ BX_SMF char *strseg(bx_segment_reg_t *seg);
+ BX_SMF void interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+ Bit16u error_code);
+#if BX_CPU_LEVEL >= 2
+ BX_SMF void exception(unsigned vector, Bit16u error_code, Boolean is_INT);
+#endif
+ BX_SMF int int_number(bx_segment_reg_t *seg);
+ BX_SMF void shutdown_cpu(void);
+ BX_SMF void enable_paging(void);
+ BX_SMF void disable_paging(void);
+ BX_SMF void CR3_change(Bit32u value32);
+ BX_SMF void reset(unsigned source);
+
+ BX_SMF void jump_protected(BxInstruction_t *, Bit16u cs, Bit32u disp32);
+ BX_SMF void call_protected(BxInstruction_t *, Bit16u cs, Bit32u disp32);
+ BX_SMF void return_protected(BxInstruction_t *, Bit16u pop_bytes);
+ BX_SMF void iret_protected(BxInstruction_t *);
+ BX_SMF void validate_seg_regs(void);
+ BX_SMF void stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
+ Bit32u flags32);
+ BX_SMF void stack_return_from_v86(BxInstruction_t *);
+ BX_SMF void init_v8086_mode(void);
+ BX_SMF void v8086_message(void);
+ BX_SMF void task_switch(bx_selector_t *selector,
+ bx_descriptor_t *descriptor,
+ unsigned source,
+ Bit32u dword1, Bit32u dword2);
+ BX_SMF void get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp);
+ BX_SMF void write_flags(Bit16u flags, Boolean change_IOPL, Boolean change_IF);
+ BX_SMF void write_eflags(Bit32u eflags, Boolean change_IOPL, Boolean change_IF,
+ Boolean change_VM, Boolean change_RF);
+ BX_SMF Bit16u read_flags(void);
+ BX_SMF Bit32u read_eflags(void);
+
+ BX_SMF Bit8u inp8(Bit16u addr);
+ BX_SMF void outp8(Bit16u addr, Bit8u value);
+ BX_SMF Bit16u inp16(Bit16u addr);
+ BX_SMF void outp16(Bit16u addr, Bit16u value);
+ BX_SMF Bit32u inp32(Bit16u addr);
+ BX_SMF void outp32(Bit16u addr, Bit32u value);
+ BX_SMF Boolean allow_io(Bit16u addr, unsigned len);
+ BX_SMF void enter_protected_mode(void);
+ BX_SMF void enter_real_mode(void);
+ BX_SMF void parse_selector(Bit16u raw_selector, bx_selector_t *selector);
+ BX_SMF void parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp);
+ BX_SMF void load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor);
+ BX_SMF void load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl);
+ BX_SMF void load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl);
+ BX_SMF void fetch_raw_descriptor(bx_selector_t *selector,
+ Bit32u *dword1, Bit32u *dword2, Bit8u exception);
+ BX_SMF void load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value);
+ BX_SMF Boolean fetch_raw_descriptor2(bx_selector_t *selector,
+ Bit32u *dword1, Bit32u *dword2);
+ BX_SMF void push_16(Bit16u value16);
+ BX_SMF void push_32(Bit32u value32);
+ BX_SMF void pop_16(Bit16u *value16_ptr);
+ BX_SMF void pop_32(Bit32u *value32_ptr);
+ BX_SMF Boolean can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes);
+ BX_SMF Boolean can_pop(Bit32u bytes);
+ BX_SMF void sanity_checks(void);
+
+ BX_SMF void debug(Bit32u offset);
+
+#if BX_X86_DEBUGGER
+ // x86 hardware debug support
+ BX_SMF Bit32u hwdebug_compare(Bit32u laddr, unsigned size,
+ unsigned opa, unsigned opb);
+#endif
+
+ BX_SMF BX_CPP_INLINE void set_CF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_AF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_ZF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_SF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_OF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_PF(Boolean val);
+ BX_SMF BX_CPP_INLINE void set_PF_base(Bit8u val);
+
+
+ BX_SMF BX_CPP_INLINE void set_AX(Bit16u ax);
+ BX_SMF BX_CPP_INLINE void set_BX(Bit16u bx);
+ BX_SMF BX_CPP_INLINE void set_CX(Bit16u cx);
+ BX_SMF BX_CPP_INLINE void set_DX(Bit16u dx);
+ BX_SMF BX_CPP_INLINE void set_AL(Bit8u al);
+ BX_SMF BX_CPP_INLINE void set_AH(Bit8u ah);
+ BX_SMF BX_CPP_INLINE void set_BL(Bit8u bl);
+ BX_SMF BX_CPP_INLINE void set_BH(Bit8u bh);
+ BX_SMF BX_CPP_INLINE void set_CL(Bit8u cl);
+ BX_SMF BX_CPP_INLINE void set_CH(Bit8u ch);
+ BX_SMF BX_CPP_INLINE void set_DL(Bit8u dl);
+ BX_SMF BX_CPP_INLINE void set_DH(Bit8u dh);
+
+ BX_SMF BX_CPP_INLINE Bit8u get_AL(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_AH(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_BL(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_BH(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_CL(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_CH(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_DL(void);
+ BX_SMF BX_CPP_INLINE Bit8u get_DH(void);
+
+ BX_SMF BX_CPP_INLINE Bit16u get_AX(void);
+ BX_SMF BX_CPP_INLINE Bit16u get_BX(void);
+ BX_SMF BX_CPP_INLINE Bit16u get_CX(void);
+ BX_SMF BX_CPP_INLINE Bit16u get_DX(void);
+
+#if BX_CPU_LEVEL >= 2
+ BX_SMF BX_CPP_INLINE Boolean real_mode(void);
+#endif
+#if BX_CPU_LEVEL >= 3
+ BX_SMF BX_CPP_INLINE Boolean protected_mode(void);
+ BX_SMF BX_CPP_INLINE Boolean v8086_mode(void);
+#endif
+#if BX_SUPPORT_APIC
+ bx_local_apic_c local_apic;
+ Boolean int_from_local_apic;
+#endif
+ };
+
+
+#if BX_X86_DEBUGGER
+#define BX_HWDebugInstruction 0x00
+#define BX_HWDebugMemW 0x01
+#define BX_HWDebugIO 0x02
+#define BX_HWDebugMemRW 0x03
+#endif
+
+#if BX_SUPPORT_SID
+#else
+#if BX_SMP_PROCESSORS==1
+// single processor simulation, so there's one of everything
+extern BX_CPU_C bx_cpu;
+#else
+// multiprocessor simulation, we need an array of cpus and memories
+extern BX_CPU_C *bx_cpu_array[BX_SMP_PROCESSORS];
+#endif
+#endif // BX_SUPPORT_SID
+
+#if defined(NEED_CPU_REG_SHORTCUTS)
+
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AX(Bit16u ax) { AX = ax; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BX(Bit16u bx) { BX = bx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CX(Bit16u cx) { CX = cx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DX(Bit16u dx) { DX = dx; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AL(Bit8u al) { AL = al; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_AH(Bit8u ah) { AH = ah; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BL(Bit8u bl) { BL = bl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_BH(Bit8u bh) { BH = bh; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CL(Bit8u cl) { CL = cl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_CH(Bit8u ch) { CH = ch; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DL(Bit8u dl) { DL = dl; };
+BX_SMF BX_CPP_INLINE void BX_CPU_C_PREFIX set_DH(Bit8u dh) { DH = dh; };
+
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_AL(void) { return(AL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_AH(void) { return(AH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_BL(void) { return(BL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_BH(void) { return(BH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_CL(void) { return(CL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_CH(void) { return(CH); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_DL(void) { return(DL); };
+BX_SMF BX_CPP_INLINE Bit8u BX_CPU_C_PREFIX get_DH(void) { return(DH); };
+
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_AX(void) { return(AX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_BX(void) { return(BX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_CX(void) { return(CX); };
+BX_SMF BX_CPP_INLINE Bit16u BX_CPU_C_PREFIX get_DX(void) { return(DX); };
+
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+ BX_CPP_INLINE Boolean BX_CPU_C::real_mode(void) { return( !BX_CPU_THIS_PTR cr0.pe ); };
+#endif
+
+#if BX_CPU_LEVEL == 2
+ BX_CPP_INLINE Boolean BX_CPU_C::protected_mode(void) { return( BX_CPU_THIS_PTR cr0.pe ); };
+#endif
+
+
+#if BX_CPU_LEVEL >= 3
+# if BX_SUPPORT_V8086_MODE
+ BX_CPP_INLINE Boolean
+BX_CPU_C::v8086_mode(void) {
+ return(BX_CPU_THIS_PTR eflags.vm);
+ }
+
+ BX_CPP_INLINE Boolean
+BX_CPU_C::protected_mode(void) {
+ return(BX_CPU_THIS_PTR cr0.pe && !BX_CPU_THIS_PTR eflags.vm);
+ }
+# else
+ BX_CPP_INLINE Boolean
+BX_CPU_C::v8086_mode(void) {
+ return(0);
+ }
+
+ BX_CPP_INLINE Boolean
+BX_CPU_C::protected_mode(void) {
+ return(BX_CPU_THIS_PTR cr0.pe);
+ }
+# endif
+#endif
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_CF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0xfffff0;
+ BX_CPU_THIS_PTR eflags.cf = val;
+ }
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_AF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+ BX_CPU_THIS_PTR eflags.af = val;
+ }
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_ZF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+ BX_CPU_THIS_PTR eflags.zf = val;
+ }
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_SF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+ BX_CPU_THIS_PTR eflags.sf = val;
+ }
+
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_OF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+ BX_CPU_THIS_PTR eflags.of = val;
+ }
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_PF(Boolean val) {
+ BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+ BX_CPU_THIS_PTR lf_pf = val;
+ }
+
+ BX_CPP_INLINE void
+BX_CPU_C::set_PF_base(Bit8u val) {
+ BX_CPU_THIS_PTR eflags.pf_byte = val;
+ BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0xffff0f) | BX_LF_MASK_P;
+ }
+
+
+#define SET_FLAGS_OSZAPC_8(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszapc.op1_8 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_8 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_8 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+#define SET_FLAGS_OSZAPC_8_CF(op1, op2, result, ins, last_CF) { \
+ BX_CPU_THIS_PTR oszapc.op1_8 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_8 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_8 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+#define SET_FLAGS_OSZAPC_16(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszapc.op1_16 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_16 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_16 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+#define SET_FLAGS_OSZAPC_16_CF(op1, op2, result, ins, last_CF) { \
+ BX_CPU_THIS_PTR oszapc.op1_16 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_16 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_16 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+#define SET_FLAGS_OSZAPC_32(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszapc.op1_32 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_32 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_32 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+#define SET_FLAGS_OSZAPC_32_CF(op1, op2, result, ins, last_CF) { \
+ BX_CPU_THIS_PTR oszapc.op1_32 = op1; \
+ BX_CPU_THIS_PTR oszapc.op2_32 = op2; \
+ BX_CPU_THIS_PTR oszapc.result_32 = result; \
+ BX_CPU_THIS_PTR oszapc.instr = ins; \
+ BX_CPU_THIS_PTR oszapc.prev_CF = last_CF; \
+ BX_CPU_THIS_PTR lf_flags_status = BX_LF_MASK_OSZAPC; \
+ }
+
+
+#define SET_FLAGS_OSZAP_8(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszap.op1_8 = op1; \
+ BX_CPU_THIS_PTR oszap.op2_8 = op2; \
+ BX_CPU_THIS_PTR oszap.result_8 = result; \
+ BX_CPU_THIS_PTR oszap.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+ }
+
+#define SET_FLAGS_OSZAP_16(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszap.op1_16 = op1; \
+ BX_CPU_THIS_PTR oszap.op2_16 = op2; \
+ BX_CPU_THIS_PTR oszap.result_16 = result; \
+ BX_CPU_THIS_PTR oszap.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+ }
+
+#define SET_FLAGS_OSZAP_32(op1, op2, result, ins) { \
+ BX_CPU_THIS_PTR oszap.op1_32 = op1; \
+ BX_CPU_THIS_PTR oszap.op2_32 = op2; \
+ BX_CPU_THIS_PTR oszap.result_32 = result; \
+ BX_CPU_THIS_PTR oszap.instr = ins; \
+ BX_CPU_THIS_PTR lf_flags_status = (BX_CPU_THIS_PTR lf_flags_status & 0x00000f) | BX_LF_MASK_OSZAP; \
+ }
+
+#define SET_FLAGS_OxxxxC(new_of, new_cf) { \
+ BX_CPU_THIS_PTR eflags.of = (Boolean) new_of; \
+ BX_CPU_THIS_PTR eflags.cf = (Boolean) new_cf; \
+ BX_CPU_THIS_PTR lf_flags_status &= 0x0ffff0; \
+ /* ??? could also mark other bits undefined here */ \
+ }
+
+
+
+
+
+
+extern const Boolean bx_parity_lookup[256];
+
+#define BX_REPE_PREFIX 10
+#define BX_REPNE_PREFIX 11
+
+
+
+#define BX_TASK_FROM_JUMP 10
+#define BX_TASK_FROM_CALL_OR_INT 11
+#define BX_TASK_FROM_IRET 12
+
+
+//
+// For decoding...
+//
+
+// If the Immediate bit is set, the lowest 3 bits of the attribute
+// specify which kinds of immediate data a required by instruction.
+
+#define BxImmediate 0x000f // bits 3..0: any immediate
+#define BxImmediate_Ib 0x0001 // 8 bits regardless
+#define BxImmediate_Ib_SE 0x0002 // sign extend to OS size
+#define BxImmediate_Iv 0x0003 // 16 or 32 depending on OS size
+#define BxImmediate_Iw 0x0004 // 16 bits regardless
+#define BxImmediate_IvIw 0x0005 // call_Ap
+#define BxImmediate_IwIb 0x0006 // enter_IwIb
+#define BxImmediate_O 0x0007 // mov_ALOb, mov_ObAL, mov_eAXOv, mov_OveAX
+#define BxImmediate_BrOff8 0x0008 // Relative branch offset byte
+#define BxImmediate_BrOff16 0x0009 // Relative branch offset word
+#define BxImmediate_BrOff32 BxImmediate_Iv
+
+#define BxPrefix 0x0010 // bit 4
+#define BxAnother 0x0020 // bit 5
+#define BxRepeatable 0x0040 // bit 6
+#define BxRepeatableZF 0x0080 // bit 7
+#define BxGroupN 0x0100 // bits 8
+#define BxGroup1 BxGroupN
+#define BxGroup2 BxGroupN
+#define BxGroup3 BxGroupN
+#define BxGroup4 BxGroupN
+#define BxGroup5 BxGroupN
+#define BxGroup6 BxGroupN
+#define BxGroup7 BxGroupN
+#define BxGroup8 BxGroupN
+#define BxGroup9 BxGroupN
+#define BxGroupa BxGroupN
+
+#if BX_DEBUGGER
+typedef enum _show_flags {
+ Flag_call = 0x1,
+ Flag_ret = 0x2,
+ Flag_int = 0x4,
+ Flag_iret = 0x8,
+ Flag_intsig = 0x10
+} show_flags_t;
+#endif
+
+#endif // #ifndef BX_CPU_H
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+ void
+BX_CPU_C::RETnear16_Iw(BxInstruction_t *i)
+{
+ Bit16u imm16;
+ Bit32u temp_ESP;
+ Bit16u return_IP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+
+ if (protected_mode()) {
+ if ( !can_pop(2) ) {
+ BX_PANIC(("retnear_iw: can't pop IP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, CPL==3, BX_READ, &return_IP);
+
+ if ( return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("retnear_iw: IP > limit\n"));
+ }
+
+ if ( !can_pop(2 + imm16) ) {
+ BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+ /* #GP(0) -or #SS(0) ??? */
+ }
+
+ BX_CPU_THIS_PTR eip = return_IP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 2 + imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += 2 + imm16;
+ }
+ else {
+ pop_16(&return_IP);
+ BX_CPU_THIS_PTR eip = return_IP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += imm16;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETnear16(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit16u return_IP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ if (protected_mode()) {
+ if ( !can_pop(2) ) {
+ BX_PANIC(("retnear: can't pop IP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, CPL==3, BX_READ, &return_IP);
+
+ if ( return_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("retnear: IP > limit\n"));
+ }
+
+ BX_CPU_THIS_PTR eip = return_IP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 2;
+ else
+ SP += 2;
+ }
+ else {
+ pop_16(&return_IP);
+ BX_CPU_THIS_PTR eip = return_IP;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETfar16_Iw(BxInstruction_t *i)
+{
+ Bit16s imm16;
+ Bit16u ip, cs_raw;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR return_protected(i, imm16);
+ goto done;
+ }
+#endif
+
+
+ pop_16(&ip);
+ pop_16(&cs_raw);
+ BX_CPU_THIS_PTR eip = (Bit32u) ip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += imm16;
+ else
+ SP += imm16;
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::RETfar16(BxInstruction_t *i)
+{
+ Bit16u ip, cs_raw;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR return_protected(i, 0);
+ goto done;
+ }
+#endif
+
+ pop_16(&ip);
+ pop_16(&cs_raw);
+ BX_CPU_THIS_PTR eip = (Bit32u) ip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+
+ void
+BX_CPU_C::CALL_Aw(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+ if ( protected_mode() &&
+ (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+ BX_PANIC(("call_av: new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+#endif
+
+ /* push 16 bit EA of next instruction */
+ push_16(IP);
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL16_Ap(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit16u disp16;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ disp16 = i->Iw;
+ cs_raw = i->Iw2;
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, disp16);
+ goto done;
+ }
+#endif
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_16((Bit16u) BX_CPU_THIS_PTR eip);
+ BX_CPU_THIS_PTR eip = (Bit32u) disp16;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::CALL_Ew(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit16u op1_16;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (op1_16 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("call_ev: IP out of CS limits!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 2) ) {
+ BX_PANIC(("call_ev: can't push IP\n"));
+ }
+ }
+#endif
+
+ push_16(IP);
+
+ BX_CPU_THIS_PTR eip = op1_16;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL16_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit16u op1_16;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ BX_PANIC(("CALL_Ep: op1 is a register"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ read_virtual_word(i->seg, i->rm_addr+2, &cs_raw);
+ invalidate_prefetch_q();
+
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16);
+ goto done;
+ }
+
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_16(IP);
+
+ BX_CPU_THIS_PTR eip = op1_16;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+ void
+BX_CPU_C::JMP_Jw(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+
+
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ new_EIP &= 0x0000ffff;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+ void
+BX_CPU_C::JCC_Jw(BxInstruction_t *i)
+{
+ Boolean condition = 0;
+
+ switch (i->b1 & 0x0f) {
+ case 0x00: /* JO */ condition = get_OF(); break;
+ case 0x01: /* JNO */ condition = !get_OF(); break;
+ case 0x02: /* JB */ condition = get_CF(); break;
+ case 0x03: /* JNB */ condition = !get_CF(); break;
+ case 0x04: /* JZ */ condition = get_ZF(); break;
+ case 0x05: /* JNZ */ condition = !get_ZF(); break;
+ case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+ case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+ case 0x08: /* JS */ condition = get_SF(); break;
+ case 0x09: /* JNS */ condition = !get_SF(); break;
+ case 0x0A: /* JP */ condition = get_PF(); break;
+ case 0x0B: /* JNP */ condition = !get_PF(); break;
+ case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+ case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+ case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+ break;
+ case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+ !get_ZF();
+ break;
+ }
+
+ if (condition) {
+ Bit32u new_EIP;
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+ EIP = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+}
+
+
+
+ void
+BX_CPU_C::JMP_Ew(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+ Bit16u op1_16;
+
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ invalidate_prefetch_q();
+ new_EIP = op1_16;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+ /* Far indirect jump */
+
+ void
+BX_CPU_C::JMP16_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit16u op1_16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* far indirect must specify a memory address */
+ BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ read_virtual_word(i->seg, i->rm_addr+2, &cs_raw);
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_16);
+ goto done;
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = op1_16;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::IRET16(BxInstruction_t *i)
+{
+ Bit16u ip, cs_raw, flags;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_iret;
+ BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (v8086_mode()) {
+ // IOPL check in stack_return_from_v86()
+ stack_return_from_v86(i);
+ goto done;
+ }
+
+#if BX_CPU_LEVEL >= 2
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ iret_protected(i);
+ goto done;
+ }
+#endif
+
+
+ pop_16(&ip);
+ pop_16(&cs_raw);
+ pop_16(&flags);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+ BX_CPU_THIS_PTR eip = (Bit32u) ip;
+ write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if 0
+ void
+BX_CPU_C::RETnear32_Iw(BxInstruction_t *i)
+{
+ Bit16u imm16;
+ Bit32u temp_ESP;
+ Bit32u return_EIP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+
+ if (protected_mode()) {
+ if ( !can_pop(4) ) {
+ BX_PANIC(("retnear_iw: can't pop EIP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &return_EIP);
+
+ if (protected_mode() &&
+ (return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+ BX_DEBUG(("retnear_iw: EIP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ /* Pentium book says imm16 is number of words ??? */
+ if ( !can_pop(4 + imm16) ) {
+ BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+ /* #GP(0) -or #SS(0) ??? */
+ }
+
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 4 + imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += 4 + imm16;
+ }
+ else {
+ pop_32(&return_EIP);
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += imm16;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETnear32(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit32u return_EIP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ if (protected_mode()) {
+ if ( !can_pop(4) ) {
+ BX_PANIC(("retnear: can't pop EIP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &return_EIP);
+
+ if ( return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("retnear: EIP > limit\n"));
+ //exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 4;
+ else
+ SP += 4;
+ }
+ else {
+ pop_32(&return_EIP);
+ BX_CPU_THIS_PTR eip = return_EIP;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETfar32_Iw(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw;
+ Bit16s imm16;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+ /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR return_protected(i, imm16);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw);
+ BX_CPU_THIS_PTR eip = eip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += imm16;
+ else
+ SP += imm16;
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::RETfar32(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR return_protected(i, 0);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw); /* 32bit pop, MSW discarded */
+ BX_CPU_THIS_PTR eip = eip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+
+ void
+BX_CPU_C::CALL_Ad(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+ Bit32s disp32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ disp32 = i->Id;
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + disp32;
+
+ if ( protected_mode() ) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("call_av: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ /* push 32 bit EA of next instruction */
+ push_32(BX_CPU_THIS_PTR eip);
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL32_Ap(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u disp32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ disp32 = i->Id;
+ cs_raw = i->Iw2;
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32);
+ goto done;
+ }
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(BX_CPU_THIS_PTR eip);
+ BX_CPU_THIS_PTR eip = disp32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::CALL_Ed(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit32u op1_32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ if (op1_32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_DEBUG(("call_ev: EIP out of CS limits! at %s:%d\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+ BX_PANIC(("call_ev: can't push EIP\n"));
+ }
+ }
+
+ push_32(BX_CPU_THIS_PTR eip);
+
+ BX_CPU_THIS_PTR eip = op1_32;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL32_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u op1_32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ BX_PANIC(("CALL_Ep: op1 is a register\n"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+ invalidate_prefetch_q();
+
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
+ goto done;
+ }
+
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(BX_CPU_THIS_PTR eip);
+
+ BX_CPU_THIS_PTR eip = op1_32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+ void
+BX_CPU_C::JMP_Jd(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + (Bit32s) i->Id;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+#endif
+
+ void
+sid_cpu_c::JCC_Jd(BxInstruction_t *i)
+{
+ Boolean condition = 0;
+
+ switch (i->b1 & 0x0f) {
+ case 0x00: /* JO */ condition = get_OF(); break;
+ case 0x01: /* JNO */ condition = !get_OF(); break;
+ case 0x02: /* JB */ condition = get_CF(); break;
+ case 0x03: /* JNB */ condition = !get_CF(); break;
+ case 0x04: /* JZ */ condition = get_ZF(); break;
+ case 0x05: /* JNZ */ condition = !get_ZF(); break;
+ case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+ case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+ case 0x08: /* JS */ condition = get_SF(); break;
+ case 0x09: /* JNS */ condition = !get_SF(); break;
+ case 0x0A: /* JP */ condition = get_PF(); break;
+ case 0x0B: /* JNP */ condition = !get_PF(); break;
+ case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+ case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+ case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+ break;
+ case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+ !get_ZF();
+ break;
+ }
+
+ if (condition) {
+ Bit32u new_EIP;
+
+ new_EIP = EIP + (Bit32s) i->Id;
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+ EIP = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+}
+#if 0
+ void
+BX_CPU_C::JMP_Ap(BxInstruction_t *i)
+{
+ Bit32u disp32;
+ Bit16u cs_raw;
+
+ invalidate_prefetch_q();
+
+ if (i->os_32) {
+ disp32 = i->Id;
+ }
+ else {
+ disp32 = i->Iw;
+ }
+ cs_raw = i->Iw2;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
+ goto done;
+ }
+#endif
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+ BX_CPU_THIS_PTR eip = disp32;
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+
+
+ void
+BX_CPU_C::JMP_Ed(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ invalidate_prefetch_q();
+ new_EIP = op1_32;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+ /* Far indirect jump */
+
+ void
+BX_CPU_C::JMP32_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* far indirect must specify a memory address */
+ BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+ invalidate_prefetch_q();
+
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
+ goto done;
+ }
+
+ BX_CPU_THIS_PTR eip = op1_32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::IRET32(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw, eflags;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_iret;
+ BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (v8086_mode()) {
+ // IOPL check in stack_return_from_v86()
+ stack_return_from_v86(i);
+ goto done;
+ }
+
+#if BX_CPU_LEVEL >= 2
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ iret_protected(i);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw);
+ pop_32(&eflags);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+ BX_CPU_THIS_PTR eip = eip;
+ write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 1);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+ void
+BX_CPU_C::RETnear32_Iw(BxInstruction_t *i)
+{
+ Bit16u imm16;
+ Bit32u temp_ESP;
+ Bit32u return_EIP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+
+ if (protected_mode()) {
+ if ( !can_pop(4) ) {
+ BX_PANIC(("retnear_iw: can't pop EIP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &return_EIP);
+
+ if (protected_mode() &&
+ (return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) ) {
+ BX_DEBUG(("retnear_iw: EIP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ /* Pentium book says imm16 is number of words ??? */
+ if ( !can_pop(4 + imm16) ) {
+ BX_PANIC(("retnear_iw: can't release bytes from stack\n"));
+ /* #GP(0) -or #SS(0) ??? */
+ }
+
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 4 + imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += 4 + imm16;
+ }
+ else {
+ pop_32(&return_EIP);
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += imm16; /* ??? should it be 2*imm16 ? */
+ else
+ SP += imm16;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETnear32(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit32u return_EIP;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ if (protected_mode()) {
+ if ( !can_pop(4) ) {
+ BX_PANIC(("retnear: can't pop EIP\n"));
+ /* ??? #SS(0) -or #GP(0) */
+ }
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &return_EIP);
+
+ if ( return_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("retnear: EIP > limit\n"));
+ //exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) /* 32bit stack */
+ ESP += 4;
+ else
+ SP += 4;
+ }
+ else {
+ pop_32(&return_EIP);
+ BX_CPU_THIS_PTR eip = return_EIP;
+ }
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::RETfar32_Iw(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw;
+ Bit16s imm16;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+ /* ??? is imm16, number of bytes/words depending on operandsize ? */
+
+ imm16 = i->Iw;
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR return_protected(i, imm16);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw);
+ BX_CPU_THIS_PTR eip = eip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += imm16;
+ else
+ SP += imm16;
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::RETfar32(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_ret;
+#endif
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 2
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR return_protected(i, 0);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw); /* 32bit pop, MSW discarded */
+ BX_CPU_THIS_PTR eip = eip;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_RET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+
+ void
+BX_CPU_C::CALL_Ad(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+ Bit32s disp32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ disp32 = i->Id;
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + disp32;
+
+ if ( protected_mode() ) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("call_av: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ /* push 32 bit EA of next instruction */
+ push_32(BX_CPU_THIS_PTR eip);
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL32_Ap(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u disp32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ disp32 = i->Id;
+ cs_raw = i->Iw2;
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, disp32);
+ goto done;
+ }
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(BX_CPU_THIS_PTR eip);
+ BX_CPU_THIS_PTR eip = disp32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::CALL_Ed(BxInstruction_t *i)
+{
+ Bit32u temp_ESP;
+ Bit32u op1_32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ if (op1_32 > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_DEBUG(("call_ev: EIP out of CS limits! at %s:%d\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+ BX_PANIC(("call_ev: can't push EIP\n"));
+ }
+ }
+
+ push_32(BX_CPU_THIS_PTR eip);
+
+ BX_CPU_THIS_PTR eip = op1_32;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::CALL32_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u op1_32;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_call;
+#endif
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ BX_PANIC(("CALL_Ep: op1 is a register\n"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+ invalidate_prefetch_q();
+
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32);
+ goto done;
+ }
+
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(BX_CPU_THIS_PTR eip);
+
+ BX_CPU_THIS_PTR eip = op1_32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_CALL,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+ void
+BX_CPU_C::JMP_Jd(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+
+ invalidate_prefetch_q();
+
+ new_EIP = EIP + (Bit32s) i->Id;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jmp_jv: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+ void
+BX_CPU_C::JCC_Jd(BxInstruction_t *i)
+{
+ Boolean condition = 0;
+
+ switch (i->b1 & 0x0f) {
+ case 0x00: /* JO */ condition = get_OF(); break;
+ case 0x01: /* JNO */ condition = !get_OF(); break;
+ case 0x02: /* JB */ condition = get_CF(); break;
+ case 0x03: /* JNB */ condition = !get_CF(); break;
+ case 0x04: /* JZ */ condition = get_ZF(); break;
+ case 0x05: /* JNZ */ condition = !get_ZF(); break;
+ case 0x06: /* JBE */ condition = get_CF() || get_ZF(); break;
+ case 0x07: /* JNBE */ condition = !get_CF() && !get_ZF(); break;
+ case 0x08: /* JS */ condition = get_SF(); break;
+ case 0x09: /* JNS */ condition = !get_SF(); break;
+ case 0x0A: /* JP */ condition = get_PF(); break;
+ case 0x0B: /* JNP */ condition = !get_PF(); break;
+ case 0x0C: /* JL */ condition = get_SF() != get_OF(); break;
+ case 0x0D: /* JNL */ condition = get_SF() == get_OF(); break;
+ case 0x0E: /* JLE */ condition = get_ZF() || (get_SF() != get_OF());
+ break;
+ case 0x0F: /* JNLE */ condition = (get_SF() == get_OF()) &&
+ !get_ZF();
+ break;
+ }
+
+ if (condition) {
+ Bit32u new_EIP;
+
+ new_EIP = EIP + (Bit32s) i->Id;
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jo_routine: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+ EIP = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+}
+
+ void
+BX_CPU_C::JMP_Ap(BxInstruction_t *i)
+{
+ Bit32u disp32;
+ Bit16u cs_raw;
+
+ invalidate_prefetch_q();
+
+ if (i->os_32) {
+ disp32 = i->Id;
+ }
+ else {
+ disp32 = i->Iw;
+ }
+ cs_raw = i->Iw2;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32);
+ goto done;
+ }
+#endif
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+ BX_CPU_THIS_PTR eip = disp32;
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+
+
+
+ void
+BX_CPU_C::JMP_Ed(BxInstruction_t *i)
+{
+ Bit32u new_EIP;
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ invalidate_prefetch_q();
+ new_EIP = op1_32;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("jmp_ev: IP out of CS limits!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+
+ BX_CPU_THIS_PTR eip = new_EIP;
+
+ BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_EIP);
+}
+
+ /* Far indirect jump */
+
+ void
+BX_CPU_C::JMP32_Ep(BxInstruction_t *i)
+{
+ Bit16u cs_raw;
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* far indirect must specify a memory address */
+ BX_PANIC(("JMP_Ep(): op1 is a register\n"));
+ }
+
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ read_virtual_word(i->seg, i->rm_addr+4, &cs_raw);
+ invalidate_prefetch_q();
+
+ if ( protected_mode() ) {
+ BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32);
+ goto done;
+ }
+
+ BX_CPU_THIS_PTR eip = op1_32;
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
+
+ void
+BX_CPU_C::IRET32(BxInstruction_t *i)
+{
+ Bit32u eip, ecs_raw, eflags;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_iret;
+ BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR eip;
+#endif
+
+ invalidate_prefetch_q();
+
+ if (v8086_mode()) {
+ // IOPL check in stack_return_from_v86()
+ stack_return_from_v86(i);
+ goto done;
+ }
+
+#if BX_CPU_LEVEL >= 2
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ iret_protected(i);
+ goto done;
+ }
+#endif
+
+
+ pop_32(&eip);
+ pop_32(&ecs_raw);
+ pop_32(&eflags);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+ BX_CPU_THIS_PTR eip = eip;
+ write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 1);
+
+done:
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ return;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::JCXZ_Jb(BxInstruction_t *i)
+{
+ Bit32u temp_ECX;
+
+ if (i->as_32)
+ temp_ECX = ECX;
+ else
+ temp_ECX = CX;
+
+ if ( temp_ECX == 0 ) {
+ Bit32u new_EIP;
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ if (i->os_32==0)
+ new_EIP &= 0x0000ffff;
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("jcxz_jb: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+#endif
+ EIP = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+}
+
+
+
+ void
+BX_CPU_C::LOOPNE_Jb(BxInstruction_t *i)
+{
+ Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32)
+ count = ECX;
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ count = CX;
+
+ count--;
+ if ( (count!=0) && (get_ZF()==0) ) {
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ if (i->os_32==0)
+ new_EIP &= 0x0000ffff;
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("loopne_jb: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+
+ if (i->as_32)
+ ECX--;
+ else
+ CX--;
+}
+
+ void
+BX_CPU_C::LOOPE_Jb(BxInstruction_t *i)
+{
+ Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32)
+ count = ECX;
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ count = CX;
+
+ count--;
+ if ( (count!=0) && get_ZF()) {
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ if (i->os_32==0)
+ new_EIP &= 0x0000ffff;
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("loope_jb: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+
+ if (i->as_32)
+ ECX--;
+ else
+ CX--;
+}
+
+ void
+BX_CPU_C::LOOP_Jb(BxInstruction_t *i)
+{
+ Bit32u count, new_EIP;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32)
+ count = ECX;
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ count = CX;
+
+ count--;
+ if (count != 0) {
+
+ new_EIP = EIP + (Bit32s) i->Id;
+ if (i->os_32==0)
+ new_EIP &= 0x0000ffff;
+ if (protected_mode()) {
+ if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("loop_jb: offset outside of CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+ BX_CPU_THIS_PTR eip = new_EIP;
+ BX_INSTR_CNEAR_BRANCH_TAKEN(new_EIP);
+ revalidate_prefetch_q();
+ }
+#if BX_INSTRUMENTATION
+ else {
+ BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
+ }
+#endif
+
+ if (i->as_32)
+ ECX--;
+ else
+ CX--;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::jump_protected(BxInstruction_t *i, Bit16u cs_raw, Bit32u disp32)
+{
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit32u dword1, dword2;
+
+
+
+ /* destination selector is not null else #GP(0) */
+ if ((cs_raw & 0xfffc) == 0) {
+ BX_PANIC(("jump_protected: cs == 0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ parse_selector(cs_raw, &selector);
+
+ /* destination selector index is whithin its descriptor table
+ limits else #GP(selector) */
+ fetch_raw_descriptor(&selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ /* examine AR byte of destination selector for legal values: */
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ if ( descriptor.segment ) {
+ if ( descriptor.u.segment.executable==0 ) {
+ BX_INFO(("jump_protected: S=1: descriptor not executable\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+ // CASE: JUMP CONFORMING CODE SEGMENT:
+ if ( descriptor.u.segment.c_ed ) {
+ // descripor DPL must be <= CPL else #GP(selector)
+ if (descriptor.dpl > CPL) {
+ BX_INFO(("jump_protected: dpl > CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ /* segment must be PRESENT else #NP(selector) */
+ if (descriptor.p == 0) {
+ BX_INFO(("jump_protected: p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ /* instruction pointer must be in code segment limit else #GP(0) */
+ if (disp32 > descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("jump_protected: IP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* Load CS:IP from destination pointer */
+ /* Load CS-cache with new segment descriptor */
+ /* CPL does not change for conforming code segment */
+ load_cs(&selector, &descriptor, CPL);
+ BX_CPU_THIS_PTR eip = disp32;
+ return;
+ }
+
+ // CASE: jump nonconforming code segment:
+ else {
+ /* RPL of destination selector must be <= CPL else #GP(selector) */
+ if (selector.rpl > CPL) {
+ BX_PANIC(("jump_protected: rpl > CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor DPL must = CPL else #GP(selector)
+ if (descriptor.dpl != CPL) {
+ BX_INFO(("jump_protected: dpl != CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ /* segment must be PRESENT else #NP(selector) */
+ if (descriptor.p == 0) {
+ BX_INFO(("jump_protected: p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ /* IP must be in code segment limit else #GP(0) */
+ if (disp32 > descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("jump_protected: IP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* load CS:IP from destination pointer */
+ /* load CS-cache with new segment descriptor */
+ /* set RPL field of CS register to CPL */
+ load_cs(&selector, &descriptor, CPL);
+ BX_CPU_THIS_PTR eip = disp32;
+ return;
+ }
+ BX_PANIC(("jump_protected: segment=1\n"));
+ }
+
+ else {
+ Bit16u raw_tss_selector;
+ bx_selector_t tss_selector, gate_cs_selector;
+ bx_descriptor_t tss_descriptor, gate_cs_descriptor;
+ Bit16u gate_cs_raw;
+ Bit32u temp_eIP;
+
+
+ switch ( descriptor.type ) {
+ case 1: // 286 available TSS
+ case 9: // 386 available TSS
+ //if ( descriptor.type==1 )
+ // BX_INFO(("jump to 286 TSS\n"));
+ //else
+ // BX_INFO(("jump to 386 TSS\n"));
+
+ // TSS DPL must be >= CPL, else #GP(TSS selector)
+ if (descriptor.dpl < CPL) {
+ BX_PANIC(("jump_protected: TSS.dpl < CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // TSS DPL must be >= TSS selector RPL, else #GP(TSS selector)
+ if (descriptor.dpl < selector.rpl) {
+ BX_PANIC(("jump_protected: TSS.dpl < selector.rpl\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor AR byte must specify available TSS,
+ // else #GP(TSS selector) */
+ // this is taken care of by the 'default' case of switch statement */
+
+ // Task State Seg must be present, else #NP(TSS selector)
+ // checked in task_switch()
+
+ // SWITCH_TASKS _without_ nesting to TSS
+ task_switch(&selector, &descriptor,
+ BX_TASK_FROM_JUMP, dword1, dword2);
+
+ // IP must be in code seg limit, else #GP(0)
+ if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_INFO(("jump_protected: TSS.p == 0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ return;
+ break;
+
+ case 3: // Busy 286 TSS
+ BX_PANIC(("jump_protected: JUMP to busy 286 TSS unsupported.\n"));
+ return;
+ break;
+
+ case 4: // 286 call gate
+ //BX_INFO(("jump_protected: JUMP TO 286 CALL GATE:\n"));
+
+ // descriptor DPL must be >= CPL else #GP(gate selector)
+ if (descriptor.dpl < CPL) {
+ BX_INFO(("jump_protected: gate.dpl < CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor DPL must be >= gate selector RPL else #GP(gate selector)
+ if (descriptor.dpl < selector.rpl) {
+ BX_INFO(("jump_protected: gate.dpl < selector.rpl\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // gate must be present else #NP(gate selector)
+ if (descriptor.p==0) {
+ BX_PANIC(("jump_protected: task gate.p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // examine selector to code segment given in call gate descriptor
+ // selector must not be null, else #GP(0)
+ gate_cs_raw = descriptor.u.gate286.dest_selector;
+ if ( (gate_cs_raw & 0xfffc) == 0 ) {
+ BX_PANIC(("jump_protected: CS selector null\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+ parse_selector(gate_cs_raw, &gate_cs_selector);
+
+ // selector must be within its descriptor table limits else #GP(CS selector)
+ fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &gate_cs_descriptor);
+ // descriptor AR byte must indicate code segment else #GP(CS selector)
+ if ( (gate_cs_descriptor.valid==0) ||
+ (gate_cs_descriptor.segment==0) ||
+ (gate_cs_descriptor.u.segment.executable==0) ) {
+ BX_INFO(("jump_protected: AR byte: not code segment.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+
+ // if non-conforming, code segment descriptor DPL must = CPL else #GP(CS selector)
+ if (gate_cs_descriptor.u.segment.c_ed==0) {
+ if (gate_cs_descriptor.dpl != CPL) {
+ BX_INFO(("jump_protected: non-conform: code seg des DPL != CPL.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+ }
+ // if conforming, then code segment descriptor DPL must <= CPL else #GP(CS selector)
+ else {
+ if (gate_cs_descriptor.dpl > CPL) {
+ BX_INFO(("jump_protected: conform: code seg des DPL > CPL.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+ }
+
+ // code segment must be present else #NP(CS selector)
+ if (gate_cs_descriptor.p==0) {
+ BX_INFO(("jump_protected: code seg not present.\n"));
+ exception(BX_NP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+
+ // IP must be in code segment limit else #GP(0)
+ if ( descriptor.u.gate286.dest_offset >
+ gate_cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("jump_protected: IP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+
+ // load CS:IP from call gate
+ // load CS cache with new code segment
+ // set rpl of CS to CPL
+ load_cs(&gate_cs_selector, &gate_cs_descriptor, CPL);
+ EIP = descriptor.u.gate286.dest_offset;
+ return;
+ break;
+
+
+ case 5: // task gate
+//BX_INFO(("jump_pro: task gate\n"));
+
+ // gate descriptor DPL must be >= CPL else #GP(gate selector)
+ if (descriptor.dpl < CPL) {
+ BX_PANIC(("jump_protected: gate.dpl < CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // gate descriptor DPL must be >= gate selector RPL
+ // else #GP(gate selector)
+ if (descriptor.dpl < selector.rpl) {
+ BX_PANIC(("jump_protected: gate.dpl < selector.rpl\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // task gate must be present else #NP(gate selector)
+ if (descriptor.p==0) {
+ BX_PANIC(("jump_protected: task gate.p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // examine selector to TSS, given in Task Gate descriptor
+ // must specify global in the local/global bit else #GP(TSS selector)
+
+ raw_tss_selector = descriptor.u.taskgate.tss_selector;
+ parse_selector(raw_tss_selector, &tss_selector);
+ if (tss_selector.ti) {
+ BX_PANIC(("jump_protected: tss_selector.ti=1\n"));
+ exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ return;
+ }
+
+ // index must be within GDT limits else #GP(TSS selector)
+ fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ // descriptor AR byte must specify available TSS
+ // else #GP(TSS selector)
+ parse_descriptor(dword1, dword2, &tss_descriptor);
+ if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+ BX_INFO(("jump_protected: TSS selector points to bad TSS\n"));
+ exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+ if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+ BX_INFO(("jump_protected: TSS selector points to bad TSS\n"));
+ exception(BX_GP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+
+
+ // task state segment must be present, else #NP(tss selector)
+ if (tss_descriptor.p==0) {
+ BX_PANIC(("jump_protected: task descriptor.p == 0\n"));
+ exception(BX_NP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+
+ // SWITCH_TASKS _without_ nesting to TSS
+ task_switch(&tss_selector, &tss_descriptor,
+ BX_TASK_FROM_JUMP, dword1, dword2);
+
+ // eIP must be within code segment limit, else #GP(0)
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+ temp_eIP = EIP;
+ else
+ temp_eIP = IP;
+ if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("jump_protected: eIP > cs.limit\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+
+ break;
+
+ case 11: // Busy 386 TSS
+ BX_PANIC(("jump_protected: JUMP to busy 386 TSS unsupported.\n"));
+ return;
+ break;
+
+ case 12: // 386 call gate
+ //BX_INFO(("jump_protected: JUMP TO 386 CALL GATE:\n"));
+
+ // descriptor DPL must be >= CPL else #GP(gate selector)
+ if (descriptor.dpl < CPL) {
+ BX_PANIC(("jump_protected: gate.dpl < CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor DPL must be >= gate selector RPL else #GP(gate selector)
+ if (descriptor.dpl < selector.rpl) {
+ BX_PANIC(("jump_protected: gate.dpl < selector.rpl\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // gate must be present else #NP(gate selector)
+ if (descriptor.p==0) {
+ BX_PANIC(("jump_protected: task gate.p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // examine selector to code segment given in call gate descriptor
+ // selector must not be null, else #GP(0)
+ gate_cs_raw = descriptor.u.gate386.dest_selector;
+ if ( (gate_cs_raw & 0xfffc) == 0 ) {
+ BX_PANIC(("jump_protected: CS selector null\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+ parse_selector(gate_cs_raw, &gate_cs_selector);
+
+ // selector must be within its descriptor table limits else #GP(CS selector)
+ fetch_raw_descriptor(&gate_cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &gate_cs_descriptor);
+ // descriptor AR byte must indicate code segment else #GP(CS selector)
+ if ( (gate_cs_descriptor.valid==0) ||
+ (gate_cs_descriptor.segment==0) ||
+ (gate_cs_descriptor.u.segment.executable==0) ) {
+ BX_PANIC(("jump_protected: AR byte: not code segment.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+
+ // if non-conforming, code segment descriptor DPL must = CPL else #GP(CS selector)
+ if (gate_cs_descriptor.u.segment.c_ed==0) {
+ if (gate_cs_descriptor.dpl != CPL) {
+ BX_PANIC(("jump_protected: non-conform: code seg des DPL != CPL.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+ }
+ // if conforming, then code segment descriptor DPL must <= CPL else #GP(CS selector)
+ else {
+ if (gate_cs_descriptor.dpl > CPL) {
+ BX_PANIC(("jump_protected: conform: code seg des DPL > CPL.\n"));
+ exception(BX_GP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+ }
+
+ // code segment must be present else #NP(CS selector)
+ if (gate_cs_descriptor.p==0) {
+ BX_PANIC(("jump_protected: code seg not present.\n"));
+ exception(BX_NP_EXCEPTION, gate_cs_raw & 0xfffc, 0);
+ }
+
+ // IP must be in code segment limit else #GP(0)
+ if ( descriptor.u.gate386.dest_offset >
+ gate_cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("jump_protected: IP > limit\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+
+ // load CS:IP from call gate
+ // load CS cache with new code segment
+ // set rpl of CS to CPL
+ load_cs(&gate_cs_selector, &gate_cs_descriptor, CPL);
+ EIP = descriptor.u.gate386.dest_offset;
+ return;
+ break;
+
+ default:
+ BX_INFO(("jump_protected: gate type %u unsupported\n",
+ (unsigned) descriptor.type));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ break;
+ }
+ }
+ return;
+}
+#endif /* if BX_CPU_LEVEL >= 2 */
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::call_protected(BxInstruction_t *i, Bit16u cs_raw, Bit32u disp32)
+{
+ bx_selector_t cs_selector;
+ Bit32u dword1, dword2;
+ bx_descriptor_t cs_descriptor;
+
+ /* Opsize in effect for CALL is specified by the D bit for the
+ * segment containing dest & by any opsize prefix.
+ * For gate descriptor, deterermined by type of call gate:
+ * 4=16bit, 12=32bit
+ * count field: 16bit specifies #words, 32bit specifies #dwords
+ */
+
+ /* new cs selector must not be null, else #GP(0) */
+ if ( (cs_raw & 0xfffc) == 0 ) {
+ BX_PANIC(("call_protected: CS selector null\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ parse_selector(cs_raw, &cs_selector);
+
+ // check new CS selector index within its descriptor limits,
+ // else #GP(new CS selector)
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ // examine AR byte of selected descriptor for various legal values
+ if (cs_descriptor.valid==0) {
+ BX_PANIC(("call_protected: invalid CS descriptor\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ }
+
+ if (cs_descriptor.segment) { // normal segment
+ Bit32u temp_ESP;
+
+ if (cs_descriptor.u.segment.executable==0) {
+ BX_PANIC(("call_protected: non executable segment\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ if (cs_descriptor.u.segment.c_ed) { // conforming code segment
+ // DPL must be <= CPL, else #GP(code seg selector)
+ if (cs_descriptor.dpl > CPL) {
+ BX_PANIC(("call_protected: cs.dpl > CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+ }
+ else { // non-conforming code segment
+ // RPL must be <= CPL, else #GP(code seg selector)
+ // DPL must be = CPL, else #GP(code seg selector)
+ if ( (cs_selector.rpl > CPL) ||
+ (cs_descriptor.dpl != CPL) ) {
+ BX_PANIC(("call_protected: cs.rpl > CPL\n"));
+ exception(BX_GP_EXCEPTION, cs_raw & 0xfffc, 0);
+ }
+ }
+
+ // segment must be present, else #NP(code seg selector)
+ if (cs_descriptor.p == 0) {
+ BX_INFO(("call_protected: cs.p = 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ }
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ // stack must be big enough for return addr, else #SS(0)
+ if (i->os_32) {
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 8) ) {
+ BX_PANIC(("call_protected: stack doesn't have room for ret addr\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+
+ // IP must be in code seg limit, else #GP(0)
+ if (disp32 > cs_descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("call_protected: IP not in code seg limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ // push return address onto stack (CS padded to 32bits)
+ push_32((Bit32u) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(EIP);
+ }
+ else { // 16bit opsize
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+ BX_PANIC(("call_protected: stack doesn't have room for ret addr\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+
+ // IP must be in code seg limit, else #GP(0)
+ if (disp32 > cs_descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("call_protected: IP not in code seg limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_16(IP);
+ }
+
+ // load code segment descriptor into CS cache
+ // load CS with new code segment selector
+ // set RPL of CS to CPL
+ // load eIP with new offset
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ BX_CPU_THIS_PTR eip = disp32;
+ if (cs_descriptor.u.segment.d_b==0)
+ BX_CPU_THIS_PTR eip &= 0x0000ffff;
+ return;
+ }
+ else { // gate & special segment
+ bx_descriptor_t gate_descriptor;
+ bx_selector_t gate_selector;
+ Bit32u new_EIP;
+ Bit16u dest_selector;
+ Bit16u raw_tss_selector;
+ bx_selector_t tss_selector;
+ bx_descriptor_t tss_descriptor;
+ Bit32u temp_eIP;
+
+ /* 1 level of indirection via gate, switch gate & cs */
+ gate_descriptor = cs_descriptor;
+ gate_selector = cs_selector;
+
+ switch (gate_descriptor.type) {
+ case 1: // available 16bit TSS
+ case 9: // available 32bit TSS
+ //if (gate_descriptor.type==1)
+ // BX_INFO(("call_protected: 16bit available TSS\n"));
+ //else
+ // BX_INFO(("call_protected: 32bit available TSS\n"));
+
+ // TSS DPL must be >= CPL, else #TS(TSS selector)
+ if (gate_descriptor.dpl < CPL) {
+ BX_PANIC(("call_protected: TSS.dpl < CPL\n"));
+ exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // TSS DPL must be >= TSS selector RPL, else #TS(TSS selector)
+ if (gate_descriptor.dpl < gate_selector.rpl) {
+ BX_PANIC(("call_protected: TSS.dpl < selector.rpl\n"));
+ exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor AR byte must specify available TSS,
+ // else #TS(TSS selector) */
+ // this is taken care of by the 'default' case of switch statement */
+
+ // Task State Seg must be present, else #NP(TSS selector)
+ // checked in task_switch()
+
+ // SWITCH_TASKS _without_ nesting to TSS
+ task_switch(&gate_selector, &gate_descriptor,
+ BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+ // IP must be in code seg limit, else #TS(0)
+ if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_INFO(("call_protected: TSS.p == 0\n"));
+ exception(BX_TS_EXCEPTION, 0, 0);
+ return;
+ }
+ return;
+ break;
+
+ case 5: // TASK GATE
+ //BX_INFO(("call_protected: task gate\n"));
+ // gate descriptor DPL must be >= CPL else #TS(gate selector)
+ if (gate_descriptor.dpl < CPL) {
+ BX_PANIC(("call_protected: gate.dpl < CPL\n"));
+ exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // gate descriptor DPL must be >= gate selector RPL
+ // else #TS(gate selector)
+ if (gate_descriptor.dpl < gate_selector.rpl) {
+ BX_PANIC(("call_protected: gate.dpl < selector.rpl\n"));
+ exception(BX_TS_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // task gate must be present else #NP(gate selector)
+ if (gate_descriptor.p==0) {
+ BX_PANIC(("call_protected: task gate.p == 0\n"));
+ exception(BX_NP_EXCEPTION, cs_raw & 0xfffc, 0);
+ return;
+ }
+
+ // examine selector to TSS, given in Task Gate descriptor
+ // must specify global in the local/global bit else #TS(TSS selector)
+
+ raw_tss_selector = gate_descriptor.u.taskgate.tss_selector;
+ parse_selector(raw_tss_selector, &tss_selector);
+ if (tss_selector.ti) {
+ BX_PANIC(("call_protected: tss_selector.ti=1\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ return;
+ }
+
+ // index must be within GDT limits else #TS(TSS selector)
+ fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+ BX_TS_EXCEPTION);
+
+ // descriptor AR byte must specify available TSS
+ // else #TS(TSS selector)
+ parse_descriptor(dword1, dword2, &tss_descriptor);
+ if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+ BX_PANIC(("call_protected: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+ if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+ BX_PANIC(("call_protected: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+
+
+ // task state segment must be present, else #NP(tss selector)
+ if (tss_descriptor.p==0) {
+ BX_PANIC(("call_protected: task descriptor.p == 0\n"));
+ exception(BX_NP_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ }
+
+ // SWITCH_TASKS without nesting to TSS
+ task_switch(&tss_selector, &tss_descriptor,
+ BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+ // eIP must be within code segment limit, else #TS(0)
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+ temp_eIP = EIP;
+ else
+ temp_eIP = IP;
+ if (temp_eIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("call_protected: eIP > cs.limit\n"));
+ exception(BX_TS_EXCEPTION, 0x0000, 0);
+ }
+
+ return;
+ break;
+
+ case 4: // 16bit CALL GATE
+ case 12: // 32bit CALL GATE
+//if (gate_descriptor.type==4)
+// BX_INFO(("CALL: 16bit call gate\n"));
+//else
+// BX_INFO(("CALL: 32bit call gate\n"));
+
+ // call gate DPL must be >= CPL, else #GP(call gate selector)
+ // call gate DPL must be >= RPL, else #GP(call gate selector)
+ if ( (gate_descriptor.dpl < CPL) ||
+ (gate_descriptor.dpl < gate_selector.rpl) ) {
+ BX_PANIC(("call_protected: DPL < CPL or RPL\n"));
+ exception(BX_GP_EXCEPTION, gate_selector.value & 0xfffc, 0);
+ }
+
+ // call gate must be present, else #NP(call gate selector)
+ if (gate_descriptor.p==0) {
+ BX_PANIC(("call_protected: not present\n"));
+ exception(BX_NP_EXCEPTION, gate_selector.value & 0xfffc, 0);
+ }
+
+ // examine code segment selector in call gate descriptor
+
+ if (gate_descriptor.type==4) {
+ dest_selector = gate_descriptor.u.gate286.dest_selector;
+ new_EIP = gate_descriptor.u.gate286.dest_offset;
+ }
+ else {
+ dest_selector = gate_descriptor.u.gate386.dest_selector;
+ new_EIP = gate_descriptor.u.gate386.dest_offset;
+ }
+
+ // selector must not be null else #GP(0)
+ if ( (dest_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("call_protected: selector in gate null\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ parse_selector(dest_selector, &cs_selector);
+
+ // selector must be within its descriptor table limits,
+ // else #GP(code segment selector)
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ // AR byte of selected descriptor must indicate code segment,
+ // else #GP(code segment selector)
+ // DPL of selected descriptor must be <= CPL,
+ // else #GP(code segment selector)
+ if (cs_descriptor.valid==0 ||
+ cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0 ||
+ cs_descriptor.dpl > CPL) {
+ BX_PANIC(("call_protected: selected desciptor not code\n"));
+ exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+ }
+
+ // CALL GATE TO MORE PRIVILEGE
+ // if non-conforming code segment and DPL < CPL then
+ // ??? use gate_descriptor.dpl or cs_descriptor.dpl ???
+ if ( (cs_descriptor.u.segment.c_ed==0) &&
+ (cs_descriptor.dpl < CPL) ) {
+
+ Bit16u SS_for_cpl_x;
+ Bit32u ESP_for_cpl_x;
+ bx_selector_t ss_selector;
+ bx_descriptor_t ss_descriptor;
+ unsigned room_needed;
+ Bit8u param_count;
+ Bit16u return_SS, return_CS;
+ Bit32u return_ESP, return_EIP;
+ Bit32u return_ss_base;
+ unsigned i;
+ Bit16u parameter_word[32];
+ Bit32u parameter_dword[32];
+ Bit32u temp_ESP;
+
+//BX_INFO(("CALL: Call Gate: to more priviliged level\n"));
+
+ // get new SS selector for new privilege level from TSS
+ get_SS_ESP_from_TSS(cs_descriptor.dpl,
+ &SS_for_cpl_x, &ESP_for_cpl_x);
+
+/* ??? use dpl or rpl ??? */
+
+ // check selector & descriptor for new SS:
+ // selector must not be null, else #TS(0)
+ if ( (SS_for_cpl_x & 0xfffc) == 0 ) {
+ BX_PANIC(("call_protected: new SS null\n"));
+ exception(BX_TS_EXCEPTION, 0, 0);
+ return;
+ }
+
+ // selector index must be within its descriptor table limits,
+ // else #TS(SS selector)
+ parse_selector(SS_for_cpl_x, &ss_selector);
+ fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+ BX_TS_EXCEPTION);
+
+ parse_descriptor(dword1, dword2, &ss_descriptor);
+
+ // selector's RPL must equal DPL of code segment,
+ // else #TS(SS selector)
+ if (ss_selector.rpl != cs_descriptor.dpl) {
+ BX_PANIC(("call_protected: SS selector.rpl != CS descr.dpl\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ return;
+ }
+
+ // stack segment DPL must equal DPL of code segment,
+ // else #TS(SS selector)
+ if (ss_descriptor.dpl != cs_descriptor.dpl) {
+ BX_PANIC(("call_protected: SS descr.rpl != CS descr.dpl\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ return;
+ }
+
+ // descriptor must indicate writable data segment,
+ // else #TS(SS selector)
+ if (ss_descriptor.valid==0 ||
+ ss_descriptor.segment==0 ||
+ ss_descriptor.u.segment.executable ||
+ ss_descriptor.u.segment.r_w==0) {
+ BX_INFO(("call_protected: ss descriptor not writable data seg\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ return;
+ }
+
+ // segment must be present, else #SS(SS selector)
+ if (ss_descriptor.p==0) {
+ BX_PANIC(("call_protected: ss descriptor not present.\n"));
+ exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ return;
+ }
+
+ if ( cs_descriptor.u.segment.d_b )
+ // new stack must have room for parameters plus 16 bytes
+ room_needed = 16;
+ else
+ // new stack must have room for parameters plus 8 bytes
+ room_needed = 8;
+
+ if (gate_descriptor.type==4) {
+ // get word count from call gate, mask to 5 bits
+ param_count = gate_descriptor.u.gate286.word_count & 0x1f;
+ room_needed += param_count*2;
+ }
+ else {
+ // get word count from call gate, mask to 5 bits
+ param_count = gate_descriptor.u.gate386.dword_count & 0x1f;
+ room_needed += param_count*4;
+ }
+
+ // new stack must have room for parameters plus return info
+ // else #SS(SS selector)
+
+ if ( !can_push(&ss_descriptor, ESP_for_cpl_x, room_needed) ) {
+ BX_INFO(("call_protected: stack doesn't have room\n"));
+ exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ return;
+ }
+
+ // new eIP must be in code segment limit else #GP(0)
+ if ( new_EIP > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("call_protected: IP not within CS limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+
+ // save return SS:eSP to be pushed on new stack
+ return_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ return_ESP = ESP;
+ else
+ return_ESP = SP;
+ return_ss_base = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base;
+
+ // save return CS:eIP to be pushed on new stack
+ return_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ if ( cs_descriptor.u.segment.d_b )
+ return_EIP = EIP;
+ else
+ return_EIP = IP;
+
+
+ if (gate_descriptor.type==4) {
+ for (i=0; i<param_count; i++) {
+ access_linear(return_ss_base + return_ESP + i*2,
+ 2, 0, BX_READ, ¶meter_word[i]);
+ }
+ }
+ else {
+ for (i=0; i<param_count; i++) {
+ access_linear(return_ss_base + return_ESP + i*4,
+ 4, 0, BX_READ, ¶meter_dword[i]);
+ }
+ }
+
+ /* load new SS:SP value from TSS */
+ /* load SS descriptor */
+ load_ss(&ss_selector, &ss_descriptor, ss_descriptor.dpl);
+ if (ss_descriptor.u.segment.d_b)
+ ESP = ESP_for_cpl_x;
+ else
+ SP = (Bit16u) ESP_for_cpl_x;
+
+ /* load new CS:IP value from gate */
+ /* load CS descriptor */
+ /* set CPL to stack segment DPL */
+ /* set RPL of CS to CPL */
+ load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl);
+ EIP = new_EIP;
+
+ // push pointer of old stack onto new stack
+ if (gate_descriptor.type==4) {
+ push_16(return_SS);
+ push_16((Bit16u) return_ESP);
+ }
+ else {
+ push_32(return_SS);
+ push_32(return_ESP);
+ }
+
+ /* get word count from call gate, mask to 5 bits */
+ /* copy parameters from old stack onto new stack */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ if (gate_descriptor.type==4) {
+ for (i=param_count; i>0; i--) {
+ push_16(parameter_word[i-1]);
+ //access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + i*2,
+ // 2, 0, BX_WRITE, ¶meter_word[i]);
+ }
+ }
+ else {
+ for (i=param_count; i>0; i--) {
+ push_32(parameter_dword[i-1]);
+ //access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + i*4,
+ // 4, 0, BX_WRITE, ¶meter_dword[i]);
+ }
+ }
+
+ // push return address onto new stack
+ if (gate_descriptor.type==4) {
+ push_16(return_CS);
+ push_16((Bit16u) return_EIP);
+ }
+ else {
+ push_32(return_CS);
+ push_32(return_EIP);
+ }
+
+ return;
+ }
+
+ // CALL GATE TO SAME PRIVILEGE
+ else {
+ Bit32u temp_ESP;
+
+//BX_INFO(("CALL: Call Gate: to same priviliged level\n"));
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ if (gate_descriptor.type==12) {
+ //if (i->os_32) {}
+ // stack must room for 8-byte return address (2 are padding)
+ // else #SS(0)
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 8) ) {
+ BX_PANIC(("call_protected: stack doesn't have room for 8 bytes\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+ }
+ else {
+ // stack must room for 4-byte return address
+ // else #SS(0)
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 4) ) {
+ BX_PANIC(("call_protected: stack doesn't have room for 4 bytes\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+ }
+
+ // EIP must be within code segment limit, else #GP(0)
+ if ( new_EIP > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("call_protected: IP not within code segment limits\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ if (gate_descriptor.type==12) {
+ // push return address onto stack
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(EIP);
+ }
+ else {
+ // push return address onto stack
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_16(IP);
+ }
+
+ // load CS:EIP from gate
+ // load code segment descriptor into CS register
+ // set RPL of CS to CPL
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ EIP = new_EIP;
+
+ return;
+ }
+
+ BX_PANIC(("call_protected: call gate: should not get here\n"));
+ return;
+
+ default:
+ BX_PANIC(("call_protected: type = %d\n",
+ (unsigned) cs_descriptor.type));
+ return;
+ }
+ BX_PANIC(("call_protected: gate segment unfinished\n"));
+ }
+
+ BX_PANIC(("call_protected: shouldn't get here!\n"));
+ return;
+}
+#endif /* 286+ */
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::return_protected(BxInstruction_t *i, Bit16u pop_bytes)
+{
+ Bit16u raw_cs_selector, raw_ss_selector;
+ bx_selector_t cs_selector, ss_selector;
+ bx_descriptor_t cs_descriptor, ss_descriptor;
+ Bit32u stack_cs_offset, stack_param_offset;
+ Bit32u return_EIP, return_ESP, temp_ESP;
+ Bit32u dword1, dword2;
+ Bit16u return_IP;
+
+
+ /* + 6+N*2: SS | +12+N*4: SS */
+ /* + 4+N*2: SP | + 8+N*4: ESP */
+ /* parm N | + parm N */
+ /* parm 3 | + parm 3 */
+ /* parm 2 | + parm 2 */
+ /* parm 1 | + 8: parm 1 */
+ /* + 2: CS | + 4: CS */
+ /* + 0: IP | + 0: EIP */
+
+#if BX_CPU_LEVEL >= 3
+ if ( i->os_32 ) {
+ /* operand size=32: third word on stack must be within stack limits,
+ * else #SS(0); */
+ if (!can_pop(6)) {
+ BX_PANIC(("return_protected: 3rd word not in stack limits\n"));
+ /* #SS(0) */
+ return;
+ }
+ stack_cs_offset = 4;
+ stack_param_offset = 8;
+ }
+ else
+#endif
+ {
+ /* operand size=16: second word on stack must be within stack limits,
+ * else #SS(0);
+ */
+ if ( !can_pop(4) ) {
+ BX_PANIC(("return_protected: 2nd word not in stack limits\n"));
+ /* #SS(0) */
+ return;
+ }
+ stack_cs_offset = 2;
+ stack_param_offset = 4;
+ }
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) temp_ESP = ESP;
+ else temp_ESP = SP;
+
+ // return selector RPL must be >= CPL, else #GP(return selector)
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP +
+ stack_cs_offset, 2, CPL==3, BX_READ, &raw_cs_selector);
+ parse_selector(raw_cs_selector, &cs_selector);
+ if ( cs_selector.rpl < CPL ) {
+ BX_INFO(("return_protected: CS.rpl < CPL\n"));
+ BX_INFO((" CS.rpl=%u CPL=%u\n", (unsigned) cs_selector.rpl,
+ (unsigned) CPL));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // if return selector RPL == CPL then
+ // RETURN TO SAME LEVEL
+ if ( cs_selector.rpl == CPL ) {
+ //BX_INFO(("return: to same level %04x:%08x\n",
+ // BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ // BX_CPU_THIS_PTR prev_eip));
+ // return selector must be non-null, else #GP(0)
+ if ( (raw_cs_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("return_protected: CS null\n"));
+ /* #GP(0) */
+ return;
+ }
+
+ // selector index must be within its descriptor table limits,
+ // else #GP(selector)
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ // descriptor AR byte must indicate code segment, else #GP(selector)
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+ if (cs_descriptor.valid==0 ||
+ cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0) {
+ BX_INFO(("return_protected: same: AR byte not code\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ }
+
+ // if non-conforming then code segment DPL must = CPL,
+ // else #GP(selector)
+ if ((cs_descriptor.u.segment.c_ed==0) && (cs_descriptor.dpl!=CPL)) {
+ BX_PANIC(("return_protected: non-conforming, DPL!=CPL\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ // if conforming then code segment DPL must be <= CPL,
+ // else #GP(selector)
+ if (cs_descriptor.u.segment.c_ed && (cs_descriptor.dpl>CPL)) {
+ BX_INFO(("return_protected: conforming, DPL>CPL\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ }
+
+ // code segment must be present, else #NP(selector)
+ if (cs_descriptor.p==0) {
+ BX_INFO(("return_protected: not present\n"));
+ exception(BX_NP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // top word on stack must be within stack limits, else #SS(0)
+ if ( !can_pop(stack_param_offset + pop_bytes) ) {
+ BX_PANIC(("return_protected: top word not in stack limits\n"));
+ /* #SS(0) */
+ return;
+ }
+
+ // eIP must be in code segment limit, else #GP(0)
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &return_EIP);
+ }
+ else
+#endif
+ {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, CPL==3, BX_READ, &return_IP);
+ return_EIP = return_IP;
+ }
+
+ if ( return_EIP > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("return_protected: return IP > CS.limit\n"));
+ /* #GP(0) */
+ return;
+ }
+
+ // load CS:eIP from stack
+ // load CS register with descriptor
+ // increment eSP
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ BX_CPU_THIS_PTR eip = return_EIP;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += stack_param_offset + pop_bytes;
+ else
+ SP += stack_param_offset + pop_bytes;
+
+ return;
+ }
+
+ /* RETURN TO OUTER PRIVILEGE LEVEL */
+ else {
+ /* + 6+N*2: SS | +12+N*4: SS */
+ /* + 4+N*2: SP | + 8+N*4: ESP */
+ /* parm N | + parm N */
+ /* parm 3 | + parm 3 */
+ /* parm 2 | + parm 2 */
+ /* parm 1 | + 8: parm 1 */
+ /* + 2: CS | + 4: CS */
+ /* + 0: IP | + 0: EIP */
+
+//BX_INFO(("return: to outer level %04x:%08x\n",
+// BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+// BX_CPU_THIS_PTR prev_eip));
+
+ if (i->os_32) {
+ /* top 16+immediate bytes on stack must be within stack limits, else #SS(0) */
+ if ( !can_pop(16 + pop_bytes) ) {
+ BX_PANIC(("return_protected: 8 bytes not within stack limits\n"));
+ /* #SS(0) */
+ return;
+ }
+ }
+ else {
+ /* top 8+immediate bytes on stack must be within stack limits, else #SS(0) */
+ if ( !can_pop(8 + pop_bytes) ) {
+ BX_PANIC(("return_protected: 8 bytes not within stack limits\n"));
+ /* #SS(0) */
+ return;
+ }
+ }
+
+ /* examine return CS selector and associated descriptor */
+
+ /* selector must be non-null else #GP(0) */
+ if ( (raw_cs_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("return_protected: CS selector null\n"));
+ /* #GP(0) */
+ return;
+ }
+
+ /* selector index must be within its descriptor table limits,
+ * else #GP(selector) */
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ /* descriptor AR byte must indicate code segment else #GP(selector) */
+ if (cs_descriptor.valid==0 ||
+ cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0) {
+ BX_PANIC(("return_protected: AR byte not code\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ /* if non-conforming code then code seg DPL must equal return selector RPL
+ * else #GP(selector) */
+ if (cs_descriptor.u.segment.c_ed==0 &&
+ cs_descriptor.dpl!=cs_selector.rpl) {
+ BX_PANIC(("return_protected: non-conforming seg DPL != selector.rpl\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ /* if conforming then code segment DPL must be <= return selector RPL
+ * else #GP(selector) */
+ if (cs_descriptor.u.segment.c_ed &&
+ cs_descriptor.dpl>cs_selector.rpl) {
+ BX_PANIC(("return_protected: conforming seg DPL > selector.rpl\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ /* segment must be present else #NP(selector) */
+ if (cs_descriptor.p==0) {
+ BX_PANIC(("return_protected: segment not present\n"));
+ /* #NP(selector) */
+ return;
+ }
+
+ /* examine return SS selector and associated descriptor: */
+ if (i->os_32) {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 12 + pop_bytes,
+ 2, 0, BX_READ, &raw_ss_selector);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8 + pop_bytes,
+ 4, 0, BX_READ, &return_ESP);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, 0, BX_READ, &return_EIP);
+ }
+ else {
+ Bit16u return_SP;
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 6 + pop_bytes,
+ 2, 0, BX_READ, &raw_ss_selector);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4 + pop_bytes,
+ 2, 0, BX_READ, &return_SP);
+ return_ESP = return_SP;
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, 0, BX_READ, &return_IP);
+ return_EIP = return_IP;
+ }
+
+ /* selector must be non-null else #GP(0) */
+ if ( (raw_ss_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("return_protected: SS selector null\n"));
+ /* #GP(0) */
+ return;
+ }
+
+ /* selector index must be within its descriptor table limits,
+ * else #GP(selector) */
+ parse_selector(raw_ss_selector, &ss_selector);
+ fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &ss_descriptor);
+
+ /* selector RPL must = RPL of the return CS selector,
+ * else #GP(selector) */
+ if (ss_selector.rpl != cs_selector.rpl) {
+ BX_INFO(("return_protected: ss.rpl != cs.rpl\n"));
+ exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ return;
+ }
+
+ /* descriptor AR byte must indicate a writable data segment,
+ * else #GP(selector) */
+ if (ss_descriptor.valid==0 ||
+ ss_descriptor.segment==0 ||
+ ss_descriptor.u.segment.executable ||
+ ss_descriptor.u.segment.r_w==0) {
+ BX_PANIC(("return_protected: SS.AR byte not writable data\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ /* descriptor dpl must = RPL of the return CS selector,
+ * else #GP(selector) */
+ if (ss_descriptor.dpl != cs_selector.rpl) {
+ BX_PANIC(("return_protected: SS.dpl != cs.rpl\n"));
+ /* #GP(selector) */
+ return;
+ }
+
+ /* segment must be present else #SS(selector) */
+ if (ss_descriptor.p==0) {
+ BX_PANIC(("ss.p == 0\n"));
+ /* #NP(selector) */
+ return;
+ }
+
+ /* eIP must be in code segment limit, else #GP(0) */
+ if (return_EIP > cs_descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("return_protected: eIP > cs.limit\n"));
+ /* #GP(0) */
+ return;
+ }
+
+ /* set CPL to RPL of return CS selector */
+ /* load CS:IP from stack */
+ /* set CS RPL to CPL */
+ /* load the CS-cache with return CS descriptor */
+ load_cs(&cs_selector, &cs_descriptor, cs_selector.rpl);
+ BX_CPU_THIS_PTR eip = return_EIP;
+
+ /* load SS:SP from stack */
+ /* load SS-cache with return SS descriptor */
+ load_ss(&ss_selector, &ss_descriptor, cs_selector.rpl);
+ if (ss_descriptor.u.segment.d_b)
+ ESP = return_ESP;
+ else
+ SP = (Bit16u) return_ESP;
+
+ /* check ES, DS, FS, GS for validity */
+ validate_seg_regs();
+
+ return;
+ }
+
+ return;
+}
+#endif
+
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::iret_protected(BxInstruction_t *i)
+{
+ Bit16u raw_cs_selector, raw_ss_selector;
+ bx_selector_t cs_selector, ss_selector;
+ Bit32u dword1, dword2;
+ bx_descriptor_t cs_descriptor, ss_descriptor;
+
+ if (BX_CPU_THIS_PTR eflags.nt) { /* NT = 1: RETURN FROM NESTED TASK */
+ /* what's the deal with NT & VM ? */
+ Bit32u base32;
+ Bit16u raw_link_selector;
+ bx_selector_t link_selector;
+ bx_descriptor_t tss_descriptor;
+
+ if (BX_CPU_THIS_PTR eflags.vm)
+ BX_PANIC(("IRET: vm set?\n"));
+
+ // TASK_RETURN:
+
+ //BX_INFO(("IRET: nested task return\n"));
+
+ if (BX_CPU_THIS_PTR tr.cache.valid==0)
+ BX_PANIC(("IRET: TR not valid\n"));
+ if (BX_CPU_THIS_PTR tr.cache.type == 1)
+ base32 = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
+ else if (BX_CPU_THIS_PTR tr.cache.type == 9)
+ base32 = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
+ else {
+ BX_PANIC(("IRET: TR not valid\n"));
+ base32 = 0; // keep compiler happy
+ }
+
+ // examine back link selector in TSS addressed by current TR:
+ access_linear(base32 + 0, 2, 0, BX_READ, &raw_link_selector);
+
+ // must specify global, else #TS(new TSS selector)
+ parse_selector(raw_link_selector, &link_selector);
+ if (link_selector.ti) {
+ BX_PANIC(("iret: link selector.ti=1\n"));
+ exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+ }
+
+ // index must be within GDT limits, else #TS(new TSS selector)
+ fetch_raw_descriptor(&link_selector, &dword1, &dword2, BX_TS_EXCEPTION);
+
+ // AR byte must specify TSS, else #TS(new TSS selector)
+ // new TSS must be busy, else #TS(new TSS selector)
+ parse_descriptor(dword1, dword2, &tss_descriptor);
+ if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+ BX_INFO(("iret: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+ }
+ if ((tss_descriptor.type!=11) && (tss_descriptor.type!=3)) {
+ BX_INFO(("iret: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_link_selector & 0xfffc, 0);
+ }
+
+
+ // TSS must be present, else #NP(new TSS selector)
+ if (tss_descriptor.p==0) {
+ BX_INFO(("iret: task descriptor.p == 0\n"));
+ exception(BX_NP_EXCEPTION, raw_link_selector & 0xfffc, 0);
+ }
+
+ // switch tasks (without nesting) to TSS specified by back link selector
+ task_switch(&link_selector, &tss_descriptor,
+ BX_TASK_FROM_IRET, dword1, dword2);
+
+ // mark the task just abandoned as not busy
+
+ // eIP must be within code seg limit, else #GP(0)
+ if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("iret: eIP > cs.limit\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+ return;
+ }
+
+ else { /* NT = 0: INTERRUPT RETURN ON STACK -or STACK_RETURN_TO_V86 */
+ Bit16u top_nbytes_same, top_nbytes_outer;
+ Bit32u cs_offset, ss_offset;
+ Bit32u new_eip, new_esp, temp_ESP, new_eflags;
+ Bit16u new_ip, new_sp, new_flags;
+ Bit8u prev_cpl;
+
+ /* 16bit opsize | 32bit opsize
+ * ==============================
+ * SS eSP+8 | SS eSP+16
+ * SP eSP+6 | ESP eSP+12
+ * -------------------------------
+ * FLAGS eSP+4 | EFLAGS eSP+8
+ * CS eSP+2 | CS eSP+4
+ * IP eSP+0 | EIP eSP+0
+ */
+
+ if (i->os_32) {
+ top_nbytes_same = 12;
+ top_nbytes_outer = 20;
+ cs_offset = 4;
+ ss_offset = 16;
+ }
+ else {
+ top_nbytes_same = 6;
+ top_nbytes_outer = 10;
+ cs_offset = 2;
+ ss_offset = 8;
+ }
+
+ /* CS on stack must be within stack limits, else #SS(0) */
+ if ( !can_pop(top_nbytes_same) ) {
+ BX_PANIC(("iret: CS not within stack limits\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + cs_offset,
+ 2, CPL==3, BX_READ, &raw_cs_selector);
+
+ if (i->os_32) {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, CPL==3, BX_READ, &new_eip);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8,
+ 4, CPL==3, BX_READ, &new_eflags);
+
+ // if VM=1 in flags image on stack then STACK_RETURN_TO_V86
+ if (new_eflags & 0x00020000) {
+ if (CPL != 0)
+ BX_PANIC(("iret: VM set on stack, CPL!=0\n"));
+ BX_CPU_THIS_PTR stack_return_to_v86(new_eip, raw_cs_selector, new_eflags);
+ return;
+ }
+ }
+ else {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, CPL==3, BX_READ, &new_ip);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4,
+ 2, CPL==3, BX_READ, &new_flags);
+ }
+
+ parse_selector(raw_cs_selector, &cs_selector);
+
+ // return CS selector must be non-null, else #GP(0)
+ if ( (raw_cs_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("iret: return CS selector null\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ // selector index must be within descriptor table limits,
+ // else #GP(return selector)
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ // AR byte must indicate code segment else #GP(return selector)
+ if ( cs_descriptor.valid==0 ||
+ cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0 ) {
+ BX_PANIC(("iret: AR byte indicated non code segment\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // return CS selector RPL must be >= CPL, else #GP(return selector)
+ if (cs_selector.rpl < CPL) {
+ BX_PANIC(("iret: return selector RPL < CPL\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // if return code seg descriptor is conforming
+ // and return code seg DPL > return code seg selector RPL
+ // then #GP(return selector)
+ if ( cs_descriptor.u.segment.c_ed &&
+ cs_descriptor.dpl > cs_selector.rpl ) {
+ BX_PANIC(("iret: conforming, DPL > cs_selector.RPL\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // if return code seg descriptor is non-conforming
+ // and return code seg DPL != return code seg selector RPL
+ // then #GP(return selector)
+ if ( cs_descriptor.u.segment.c_ed==0 &&
+ cs_descriptor.dpl != cs_selector.rpl ) {
+ BX_INFO(("(mch) iret: Return with DPL != RPL. #GP(selector)\n"));
+ exception(BX_GP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ // segment must be present else #NP(return selector)
+ if ( cs_descriptor.p==0 ) {
+ BX_PANIC(("iret: not present\n"));
+ exception(BX_NP_EXCEPTION, raw_cs_selector & 0xfffc, 0);
+ return;
+ }
+
+ if (cs_selector.rpl == CPL) { /* INTERRUPT RETURN TO SAME LEVEL */
+ /* top 6/12 bytes on stack must be within limits, else #SS(0) */
+ /* satisfied above */
+
+ if (i->os_32) {
+ /* return EIP must be in code segment limit else #GP(0) */
+ if ( new_eip > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("iret: IP > descriptor limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ /* load CS:EIP from stack */
+ /* load CS-cache with new code segment descriptor */
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ EIP = new_eip;
+
+ /* load EFLAGS with 3rd doubleword from stack */
+ write_eflags(new_eflags, CPL==0, CPL<=IOPL, 0, 1);
+ }
+ else {
+ /* return IP must be in code segment limit else #GP(0) */
+ if ( new_ip > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("iret: IP > descriptor limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ /* load CS:IP from stack */
+ /* load CS-cache with new code segment descriptor */
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ EIP = new_ip;
+
+ /* load flags with third word on stack */
+ write_flags(new_flags, CPL==0, CPL<=IOPL);
+ }
+
+ /* increment stack by 6/12 */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += top_nbytes_same;
+ else
+ SP += top_nbytes_same;
+ return;
+ }
+ else { /* INTERRUPT RETURN TO OUTER PRIVILEGE LEVEL */
+ /* 16bit opsize | 32bit opsize
+ * ==============================
+ * SS eSP+8 | SS eSP+16
+ * SP eSP+6 | ESP eSP+12
+ * FLAGS eSP+4 | EFLAGS eSP+8
+ * CS eSP+2 | CS eSP+4
+ * IP eSP+0 | EIP eSP+0
+ */
+
+ /* top 10/20 bytes on stack must be within limits else #SS(0) */
+ if ( !can_pop(top_nbytes_outer) ) {
+ BX_PANIC(("iret: top 10/20 bytes not within stack limits\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* examine return SS selector and associated descriptor */
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + ss_offset,
+ 2, 0, BX_READ, &raw_ss_selector);
+
+ /* selector must be non-null, else #GP(0) */
+ if ( (raw_ss_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("iret: SS selector null\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ parse_selector(raw_ss_selector, &ss_selector);
+
+ /* selector RPL must = RPL of return CS selector,
+ * else #GP(SS selector) */
+ if ( ss_selector.rpl != cs_selector.rpl) {
+ BX_PANIC(("iret: SS.rpl != CS.rpl\n"));
+ exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ return;
+ }
+
+ /* selector index must be within its descriptor table limits,
+ * else #GP(SS selector) */
+ fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+
+ parse_descriptor(dword1, dword2, &ss_descriptor);
+
+ /* AR byte must indicate a writable data segment,
+ * else #GP(SS selector) */
+ if ( ss_descriptor.valid==0 ||
+ ss_descriptor.segment==0 ||
+ ss_descriptor.u.segment.executable ||
+ ss_descriptor.u.segment.r_w==0 ) {
+ BX_PANIC(("iret: SS AR byte not writable code segment\n"));
+ exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ return;
+ }
+
+ /* stack segment DPL must equal the RPL of the return CS selector,
+ * else #GP(SS selector) */
+ if ( ss_descriptor.dpl != cs_selector.rpl ) {
+ BX_PANIC(("iret: SS.dpl != CS selector RPL\n"));
+ exception(BX_GP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ return;
+ }
+
+ /* SS must be present, else #NP(SS selector) */
+ if ( ss_descriptor.p==0 ) {
+ BX_PANIC(("iret: SS not present!\n"));
+ exception(BX_NP_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ return;
+ }
+
+
+ if (i->os_32) {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 4, 0, BX_READ, &new_eip);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 8,
+ 4, 0, BX_READ, &new_eflags);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 12,
+ 4, 0, BX_READ, &new_esp);
+ }
+ else {
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 0,
+ 2, 0, BX_READ, &new_ip);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 4,
+ 2, 0, BX_READ, &new_flags);
+ access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_ESP + 6,
+ 2, 0, BX_READ, &new_sp);
+ new_eip = new_ip;
+ new_esp = new_sp;
+ new_eflags = new_flags;
+ }
+
+ /* EIP must be in code segment limit, else #GP(0) */
+ if ( new_eip > cs_descriptor.u.segment.limit_scaled ) {
+ BX_PANIC(("iret: IP > descriptor limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* load CS:EIP from stack */
+ /* load the CS-cache with CS descriptor */
+ /* set CPL to the RPL of the return CS selector */
+ prev_cpl = CPL; /* previous CPL */
+ load_cs(&cs_selector, &cs_descriptor, cs_selector.rpl);
+ BX_CPU_THIS_PTR eip = new_eip;
+
+ /* load flags from stack */
+ // perhaps I should always write_eflags(), thus zeroing
+ // out the upper 16bits of eflags for CS.D_B==0 ???
+ if (cs_descriptor.u.segment.d_b)
+ write_eflags(new_eflags, prev_cpl==0, prev_cpl<=IOPL, 0, 1);
+ else
+ write_flags((Bit16u) new_eflags, prev_cpl==0, prev_cpl<=IOPL);
+
+ // load SS:eSP from stack
+ // load the SS-cache with SS descriptor
+ load_ss(&ss_selector, &ss_descriptor, cs_selector.rpl);
+ if (ss_descriptor.u.segment.d_b)
+ ESP = new_esp;
+ else
+ SP = new_esp;
+
+ validate_seg_regs();
+
+ return;
+ }
+ }
+ BX_PANIC(("IRET: shouldn't get here!\n"));
+}
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::validate_seg_regs(void)
+{
+ if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl<CPL ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
+ }
+ if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl<CPL ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0;
+ }
+ if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl<CPL ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = 0;
+ }
+ if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl<CPL ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0;
+ }
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::MOV_RXIw(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = i->Iw;
+}
+
+ void
+BX_CPU_C::XCHG_RXAX(BxInstruction_t *i)
+{
+ Bit16u temp16;
+
+ temp16 = AX;
+ AX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx;
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = temp16;
+}
+
+
+ void
+BX_CPU_C::MOV_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16;
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ /* now write op2 to op1 */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op2_16);
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+}
+
+
+ void
+BX_CPU_C::MOV_GwEw(BxInstruction_t *i)
+{
+ Bit16u op2_16;
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ BX_WRITE_16BIT_REG(i->nnn, op2_16);
+}
+
+ void
+BX_CPU_C::MOV_EwSw(BxInstruction_t *i)
+{
+ Bit16u seg_reg;
+
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_EwSw: incomplete for CPU < 3\n"));
+#endif
+
+ seg_reg = BX_CPU_THIS_PTR sregs[i->nnn].selector.value;
+
+ if (i->mod == 0xc0) {
+ // ??? BX_WRITE_16BIT_REG(mem_addr, seg_reg);
+ if ( i->os_32 ) {
+ BX_WRITE_32BIT_REG(i->rm, seg_reg);
+ }
+ else {
+ BX_WRITE_16BIT_REG(i->rm, seg_reg);
+ }
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &seg_reg);
+ }
+}
+
+ void
+BX_CPU_C::MOV_SwEw(BxInstruction_t *i)
+{
+ Bit16u op2_16;
+
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_SwEw: incomplete for CPU < 3\n"));
+#endif
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[i->nnn], op2_16);
+
+ if (i->nnn == BX_SEG_REG_SS) {
+ // MOV SS inhibits interrupts, debug exceptions and single-step
+ // trap exceptions until the execution boundary following the
+ // next instruction is reached.
+ // Same code as POP_SS()
+ BX_CPU_THIS_PTR inhibit_mask |=
+ BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG;
+ BX_CPU_THIS_PTR async_event = 1;
+ }
+}
+
+ void
+BX_CPU_C::LEA_GwM(BxInstruction_t *i)
+{
+ if (i->mod == 0xc0) {
+ BX_PANIC(("LEA_GvM: op2 is a register"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ BX_WRITE_16BIT_REG(i->nnn, (Bit16u) i->rm_addr);
+}
+
+
+ void
+BX_CPU_C::MOV_AXOw(BxInstruction_t *i)
+{
+ Bit16u temp_16;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from memory address */
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ read_virtual_word(i->seg, addr_32, &temp_16);
+ }
+ else {
+ read_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
+ }
+
+ /* write to register */
+ AX = temp_16;
+}
+
+
+ void
+BX_CPU_C::MOV_OwAX(BxInstruction_t *i)
+{
+ Bit16u temp_16;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from register */
+ temp_16 = AX;
+
+ /* write to memory address */
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ write_virtual_word(i->seg, addr_32, &temp_16);
+ }
+ else {
+ write_virtual_word(BX_SEG_REG_DS, addr_32, &temp_16);
+ }
+}
+
+
+
+ void
+BX_CPU_C::MOV_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16;
+
+ op2_16 = i->Iw;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, op2_16);
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+}
+
+
+ void
+BX_CPU_C::MOVZX_GwEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVZX_GvEb: not supported on < 386\n"));
+#else
+ Bit8u op2_8;
+
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ /* zero extend byte op2 into word op1 */
+ BX_WRITE_16BIT_REG(i->nnn, (Bit16u) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVZX_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVZX_GvEw: not supported on < 386\n"));
+#else
+ Bit16u op2_16;
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ /* normal move */
+ BX_WRITE_16BIT_REG(i->nnn, op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVSX_GwEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVSX_GvEb: not supported on < 386\n"));
+#else
+ Bit8u op2_8;
+
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ /* sign extend byte op2 into word op1 */
+ BX_WRITE_16BIT_REG(i->nnn, (Bit8s) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVSX_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVSX_GvEw: not supported on < 386\n"));
+#else
+ Bit16u op2_16;
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ /* normal move */
+ BX_WRITE_16BIT_REG(i->nnn, op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+
+ void
+BX_CPU_C::XCHG_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16;
+
+#ifdef MAGIC_BREAKPOINT
+#if BX_DEBUGGER
+ // (mch) Magic break point
+ if (i->nnn == 3 && i->mod == 0xc0 && i->rm == 3) {
+ BX_CPU_THIS_PTR magic_break = 1;
+ }
+#endif
+#endif
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ BX_WRITE_16BIT_REG(i->rm, op2_16);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ write_RMW_virtual_word(op2_16);
+ }
+
+ BX_WRITE_16BIT_REG(i->nnn, op1_16);
+}
+
+
+ void
+BX_CPU_C::CMOV_GwEw(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 6) || (BX_CPU_LEVEL_HACKED >= 6)
+ // Note: CMOV accesses a memory source operand (read), regardless
+ // of whether condition is true or not. Thus, exceptions may
+ // occur even if the MOV does not take place.
+
+ Boolean condition;
+ Bit16u op2_16;
+
+ switch (i->b1) {
+ // CMOV opcodes:
+ case 0x140: condition = get_OF(); break;
+ case 0x141: condition = !get_OF(); break;
+ case 0x142: condition = get_CF(); break;
+ case 0x143: condition = !get_CF(); break;
+ case 0x144: condition = get_ZF(); break;
+ case 0x145: condition = !get_ZF(); break;
+ case 0x146: condition = get_CF() || get_ZF(); break;
+ case 0x147: condition = !get_CF() && !get_ZF(); break;
+ case 0x148: condition = get_SF(); break;
+ case 0x149: condition = !get_SF(); break;
+ case 0x14A: condition = get_PF(); break;
+ case 0x14B: condition = !get_PF(); break;
+ case 0x14C: condition = get_SF() != get_OF(); break;
+ case 0x14D: condition = get_SF() == get_OF(); break;
+ case 0x14E: condition = get_ZF() || (get_SF() != get_OF()); break;
+ case 0x14F: condition = !get_ZF() && (get_SF() == get_OF()); break;
+ default:
+ condition = 0;
+ BX_PANIC(("CMOV_GwEw: default case\n"));
+ }
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ if (condition) {
+ BX_WRITE_16BIT_REG(i->nnn, op2_16);
+ }
+#else
+ BX_PANIC(("cmov_gwew called\n"));
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+ void
+BX_CPU_C::XCHG_ERXEAX(BxInstruction_t *i)
+{
+ Bit32u temp32;
+
+ temp32 = EAX;
+ EAX = BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx;
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = temp32;
+}
+
+ void
+BX_CPU_C::MOV_ERXId(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = i->Id;
+}
+
+ void
+BX_CPU_C::MOV_EdGd(BxInstruction_t *i)
+{
+ Bit32u op2_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ /* now write op2 to op1 */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op2_32);
+ }
+ else {
+ write_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+}
+
+
+ void
+BX_CPU_C::MOV_GdEd(BxInstruction_t *i)
+{
+ Bit32u op2_32;
+
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ BX_WRITE_32BIT_REG(i->nnn, op2_32);
+}
+
+
+ void
+BX_CPU_C::LEA_GdM(BxInstruction_t *i)
+{
+ if (i->mod == 0xc0) {
+ BX_PANIC(("LEA_GvM: op2 is a register"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ /* write effective address of op2 in op1 */
+ BX_WRITE_32BIT_REG(i->nnn, i->rm_addr);
+}
+
+
+ void
+BX_CPU_C::MOV_EAXOd(BxInstruction_t *i)
+{
+ Bit32u temp_32;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from memory address */
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ read_virtual_dword(i->seg, addr_32, &temp_32);
+ }
+ else {
+ read_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
+ }
+
+ /* write to register */
+ EAX = temp_32;
+}
+
+
+ void
+BX_CPU_C::MOV_OdEAX(BxInstruction_t *i)
+{
+ Bit32u temp_32;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from register */
+ temp_32 = EAX;
+
+ /* write to memory address */
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ write_virtual_dword(i->seg, addr_32, &temp_32);
+ }
+ else {
+ write_virtual_dword(BX_SEG_REG_DS, addr_32, &temp_32);
+ }
+}
+
+
+
+ void
+BX_CPU_C::MOV_EdId(BxInstruction_t *i)
+{
+ Bit32u op2_32;
+
+ op2_32 = i->Id;
+
+ /* now write sum back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, op2_32);
+ }
+ else {
+ write_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+}
+
+
+ void
+BX_CPU_C::MOVZX_GdEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVZX_GvEb: not supported on < 386\n"));
+#else
+ Bit8u op2_8;
+
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ /* zero extend byte op2 into dword op1 */
+ BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVZX_GdEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVZX_GvEw: not supported on < 386\n"));
+#else
+ Bit16u op2_16;
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ /* zero extend word op2 into dword op1 */
+ BX_WRITE_32BIT_REG(i->nnn, (Bit32u) op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVSX_GdEb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVSX_GvEb: not supported on < 386\n"));
+#else
+ Bit8u op2_8;
+
+ if (i->mod == 0xc0) {
+ op2_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2_8);
+ }
+
+ /* sign extend byte op2 into dword op1 */
+ BX_WRITE_32BIT_REG(i->nnn, (Bit8s) op2_8);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+ void
+BX_CPU_C::MOVSX_GdEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOVSX_GvEw: not supported on < 386\n"));
+#else
+ Bit16u op2_16;
+
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ /* sign extend word op2 into dword op1 */
+ BX_WRITE_32BIT_REG(i->nnn, (Bit16s) op2_16);
+#endif /* BX_CPU_LEVEL < 3 */
+}
+
+
+ void
+BX_CPU_C::XCHG_EdGd(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ BX_WRITE_32BIT_REG(i->rm, op2_32);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ write_RMW_virtual_dword(op2_32);
+ }
+
+ BX_WRITE_32BIT_REG(i->nnn, op1_32);
+}
+
+
+ void
+BX_CPU_C::CMOV_GdEd(BxInstruction_t *i)
+{
+#if (BX_CPU_LEVEL >= 6) || (BX_CPU_LEVEL_HACKED >= 6)
+ // Note: CMOV accesses a memory source operand (read), regardless
+ // of whether condition is true or not. Thus, exceptions may
+ // occur even if the MOV does not take place.
+
+ Boolean condition;
+ Bit32u op2_32;
+
+
+ switch (i->b1) {
+ // CMOV opcodes:
+ case 0x140: condition = get_OF(); break;
+ case 0x141: condition = !get_OF(); break;
+ case 0x142: condition = get_CF(); break;
+ case 0x143: condition = !get_CF(); break;
+ case 0x144: condition = get_ZF(); break;
+ case 0x145: condition = !get_ZF(); break;
+ case 0x146: condition = get_CF() || get_ZF(); break;
+ case 0x147: condition = !get_CF() && !get_ZF(); break;
+ case 0x148: condition = get_SF(); break;
+ case 0x149: condition = !get_SF(); break;
+ case 0x14A: condition = get_PF(); break;
+ case 0x14B: condition = !get_PF(); break;
+ case 0x14C: condition = get_SF() != get_OF(); break;
+ case 0x14D: condition = get_SF() == get_OF(); break;
+ case 0x14E: condition = get_ZF() || (get_SF() != get_OF()); break;
+ case 0x14F: condition = !get_ZF() && (get_SF() == get_OF()); break;
+ default:
+ condition = 0;
+ BX_PANIC(("CMOV_GdEd: default case\n"));
+ }
+
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ if (condition) {
+ BX_WRITE_32BIT_REG(i->nnn, op2_32);
+ }
+#else
+ BX_PANIC(("cmov_gded called\n"));
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::MOV_RLIb(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x03].word.byte.rl = i->Ib;
+}
+
+ void
+BX_CPU_C::MOV_RHIb(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x03].word.byte.rh = i->Ib;
+}
+
+
+ void
+BX_CPU_C::MOV_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2;
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* now write op2 to op1 */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, op2);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+}
+
+
+ void
+BX_CPU_C::MOV_GbEb(BxInstruction_t *i)
+{
+ Bit8u op2;
+
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ BX_WRITE_8BIT_REG(i->nnn, op2);
+}
+
+
+
+ void
+BX_CPU_C::MOV_ALOb(BxInstruction_t *i)
+{
+ Bit8u temp_8;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from memory address */
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ read_virtual_byte(i->seg, addr_32, &temp_8);
+ }
+ else {
+ read_virtual_byte(BX_SEG_REG_DS, addr_32, &temp_8);
+ }
+
+
+ /* write to register */
+ AL = temp_8;
+}
+
+
+ void
+BX_CPU_C::MOV_ObAL(BxInstruction_t *i)
+{
+ Bit8u temp_8;
+ Bit32u addr_32;
+
+ addr_32 = i->Id;
+
+ /* read from register */
+ temp_8 = AL;
+
+ /* write to memory address */
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ write_virtual_byte(i->seg, addr_32, &temp_8);
+ }
+ else {
+ write_virtual_byte(BX_SEG_REG_DS, addr_32, &temp_8);
+ }
+}
+
+
+ void
+BX_CPU_C::MOV_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2;
+
+ op2 = i->Ib;
+
+ /* now write op2 back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, op2);
+ }
+ else {
+ write_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+}
+
+
+
+ void
+BX_CPU_C::XLAT(BxInstruction_t *i)
+{
+ Bit32u offset_32;
+ Bit8u al;
+
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ offset_32 = EBX + AL;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ {
+ offset_32 = BX + AL;
+ }
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ read_virtual_byte(i->seg, offset_32, &al);
+ }
+ else {
+ read_virtual_byte(BX_SEG_REG_DS, offset_32, &al);
+ }
+ AL = al;
+}
+
+ void
+BX_CPU_C::XCHG_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1;
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ BX_WRITE_8BIT_REG(i->rm, op2);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ write_RMW_virtual_byte(op2);
+ }
+
+ BX_WRITE_8BIT_REG(i->nnn, op1);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_DEBUGGER
+
+ void
+BX_CPU_C::debug(Bit32u offset)
+{
+ BX_INFO(("| EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n",
+ (unsigned) EAX, (unsigned) EBX, (unsigned) ECX, (unsigned) EDX));
+ BX_INFO(("| ESP=%08x EBP=%08x ESI=%08x EDI=%08x\n",
+ (unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
+ BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s\n",
+ BX_CPU_THIS_PTR eflags.iopl,
+ BX_CPU_THIS_PTR get_OF() ? "OV" : "NV",
+ BX_CPU_THIS_PTR eflags.df ? "DW" : "UP",
+ BX_CPU_THIS_PTR eflags.if_ ? "EI" : "DI",
+ BX_CPU_THIS_PTR get_SF() ? "NG" : "PL",
+ BX_CPU_THIS_PTR get_ZF() ? "ZR" : "NZ",
+ BX_CPU_THIS_PTR get_AF() ? "AC" : "NA",
+ BX_CPU_THIS_PTR get_PF() ? "PE" : "PO",
+ BX_CPU_THIS_PTR get_CF() ? "CY" : "NC"));
+ BX_INFO(("| SEG selector base limit G D\n"));
+ BX_INFO(("| SEG sltr(index|ti|rpl) base limit G D\n"));
+ BX_INFO(("| DS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b));
+ BX_INFO(("| ES:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b));
+ BX_INFO(("| FS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b));
+ BX_INFO(("| GS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b));
+ BX_INFO(("| SS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b));
+ BX_INFO(("| CS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b));
+ BX_INFO(("| EIP=%08x (%08x)\n", (unsigned) BX_CPU_THIS_PTR eip,
+ (unsigned) BX_CPU_THIS_PTR prev_eip));
+
+#if 0
+ /* (mch) Hack to display the area round EIP and prev_EIP */
+ char buf[100];
+ sprintf(buf, "%04x:%08x ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ for (int i = 0; i < 8; i++) {
+ Bit8u data;
+ BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR eip + i, &data);
+ sprintf(buf+strlen(buf), "%02x ", data);
+ }
+ sprintf(buf+strlen(buf), "\n");
+ BX_INFO((buf));
+
+ sprintf(buf, "%04x:%08x ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR prev_eip);
+ for (int i = 0; i < 8; i++) {
+ Bit8u data;
+ BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR prev_eip + i, &data);
+ sprintf(buf+strlen(buf), "%02x ", data);
+ }
+ sprintf(buf+strlen(buf), "\n");
+ BX_INFO((buf));
+#endif
+
+
+#if BX_DISASM
+ Boolean valid;
+ Bit32u phy_addr;
+ Bit8u instr_buf[32];
+ char char_buf[256];
+ unsigned isize;
+
+ dbg_xlate_linear2phy(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + offset,
+ &phy_addr, &valid);
+ if (valid) {
+ BX_CPU_THIS_PTR mem->dbg_fetch_mem(phy_addr, 16, instr_buf);
+ isize = bx_disassemble.disasm(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
+ instr_buf, char_buf);
+ for (unsigned j=0; j<isize; j++)
+ BX_INFO((">> %02x\n", (unsigned) instr_buf[j]));
+ BX_INFO((">> : %s\n", char_buf));
+ }
+ else {
+ BX_INFO(("(instruction unavailable) page not present\n"));
+ }
+#else
+ UNUSED(offset);
+#endif // #if BX_DISASM
+}
+
+#endif // BX_DEBUGGER
+
+
+ Bit32u
+sid_cpu_c::dbg_get_reg(unsigned reg)
+{
+ Bit32u return_val32;
+
+ switch (reg) {
+ case BX_DBG_REG_EAX: return(EAX);
+ case BX_DBG_REG_ECX: return(ECX);
+ case BX_DBG_REG_EDX: return(EDX);
+ case BX_DBG_REG_EBX: return(EBX);
+ case BX_DBG_REG_ESP: return(ESP);
+ case BX_DBG_REG_EBP: return(EBP);
+ case BX_DBG_REG_ESI: return(ESI);
+ case BX_DBG_REG_EDI: return(EDI);
+ case BX_DBG_REG_EIP: return(EIP);
+ case BX_DBG_REG_EFLAGS:
+ return_val32 = dbg_get_eflags();
+ return(return_val32);
+ case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+ case BX_DBG_REG_DS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+ case BX_DBG_REG_ES: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+ case BX_DBG_REG_FS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+ case BX_DBG_REG_GS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+ default:
+ BX_PANIC(("get_reg: request for unknown register\n"));
+ return(0);
+ }
+}
+
+ Boolean
+sid_cpu_c::dbg_set_reg(unsigned reg, Bit32u val)
+{
+ // returns 1=OK, 0=can't change
+ bx_segment_reg_t *seg;
+ Bit32u current_sys_bits;
+
+ switch (reg) {
+ case BX_DBG_REG_EAX: EAX = val; return(1);
+ case BX_DBG_REG_ECX: ECX = val; return(1);
+ case BX_DBG_REG_EDX: EDX = val; return(1);
+ case BX_DBG_REG_EBX: EBX = val; return(1);
+ case BX_DBG_REG_ESP: ESP = val; return(1);
+ case BX_DBG_REG_EBP: EBP = val; return(1);
+ case BX_DBG_REG_ESI: ESI = val; return(1);
+ case BX_DBG_REG_EDI: EDI = val; return(1);
+ case BX_DBG_REG_EIP: EIP = val; return(1);
+ case BX_DBG_REG_EFLAGS:
+#if 0
+ BX_INFO(("dbg_set_reg: can not handle eflags yet.\n"));
+ if ( val & 0xffff0000 ) {
+ BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags.\n"));
+ return(0);
+ }
+ // make sure none of the system bits are being changed
+ current_sys_bits = (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.tf << 8);
+ if ( current_sys_bits != (val & 0x0000f100) ) {
+ BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF.\n"));
+ return(0);
+ }
+#endif
+ BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR set_OF(val & 0x01);
+ if (BX_CPU_THIS_PTR eflags.if_)
+ BX_CPU_THIS_PTR async_event = 1;
+ return(1);
+ case BX_DBG_REG_CS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+ break;
+ case BX_DBG_REG_SS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+ break;
+ case BX_DBG_REG_DS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
+ break;
+ case BX_DBG_REG_ES:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES];
+ break;
+ case BX_DBG_REG_FS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS];
+ break;
+ case BX_DBG_REG_GS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS];
+ break;
+ default:
+ BX_PANIC(("dbg_set_reg: unrecognized register ID (%u)\n", reg));
+ return(0);
+ }
+
+ if (BX_CPU_THIS_PTR real_mode()) {
+ seg->selector.value = val;
+ seg->cache.valid = 1;
+ seg->cache.p = 1;
+ seg->cache.dpl = 0;
+ seg->cache.segment = 1; // regular segment
+ if (reg == BX_DBG_REG_CS) {
+ seg->cache.u.segment.executable = 1; // code segment
+ }
+ else {
+ seg->cache.u.segment.executable = 0; // data segment
+ }
+ seg->cache.u.segment.c_ed = 0; // expand up/non-conforming
+ seg->cache.u.segment.r_w = 1; // writeable
+ seg->cache.u.segment.a = 1; // accessed
+ seg->cache.u.segment.base = val << 4;
+ seg->cache.u.segment.limit = 0xffff;
+ seg->cache.u.segment.limit_scaled = 0xffff;
+ seg->cache.u.segment.g = 0; // byte granular
+ seg->cache.u.segment.d_b = 0; // default 16bit size
+ seg->cache.u.segment.avl = 0;
+ return(1); // ok
+ }
+
+ return(0); // can't change when not in real mode
+}
+#if BX_DEBUGGER
+ unsigned
+BX_CPU_C::dbg_query_pending(void)
+{
+ unsigned ret = 0;
+
+ if ( BX_HRQ ) { // DMA Hold Request
+ ret |= BX_DBG_PENDING_DMA;
+ }
+
+ if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+ ret |= BX_DBG_PENDING_IRQ;
+ }
+
+ return(ret);
+}
+
+#endif // BX_DEBUGGER
+
+ Bit32u
+sid_cpu_c::dbg_get_eflags(void)
+{
+ Bit32u val32;
+
+ val32 =
+ (BX_CPU_THIS_PTR get_CF()) |
+ (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+ ((BX_CPU_THIS_PTR get_PF()) << 2) |
+ (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+ ((BX_CPU_THIS_PTR get_AF()>0) << 4) |
+ (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+ ((BX_CPU_THIS_PTR get_ZF()>0) << 6) |
+ ((BX_CPU_THIS_PTR get_SF()>0) << 7) |
+ (BX_CPU_THIS_PTR eflags.tf << 8) |
+ (BX_CPU_THIS_PTR eflags.if_ << 9) |
+ (BX_CPU_THIS_PTR eflags.df << 10) |
+ ((BX_CPU_THIS_PTR get_OF()>0) << 11) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+ (BX_CPU_THIS_PTR eflags.rf << 16) |
+ (BX_CPU_THIS_PTR eflags.vm << 17);
+#if BX_CPU_LEVEL >= 4
+ val32 |= (BX_CPU_THIS_PTR eflags.ac << 18);
+ //val32 |= (BX_CPU_THIS_PTR eflags.vif << 19);
+ //val32 |= (BX_CPU_THIS_PTR eflags.vip << 20);
+ val32 |= (BX_CPU_THIS_PTR eflags.id << 21);
+#endif
+ return(val32);
+}
+
+#if BX_DEBUGGER
+ Bit32u
+BX_CPU_C::dbg_get_descriptor_l(bx_descriptor_t *d)
+{
+ Bit32u val;
+
+ if (d->valid == 0) {
+ return(0);
+ }
+
+ if (d->segment) {
+ val = ((d->u.segment.base & 0xffff) << 16) |
+ (d->u.segment.limit & 0xffff);
+ return(val);
+ }
+ else {
+ switch (d->type) {
+ case 0: // Reserved (not yet defined)
+ BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+ return(0);
+
+ case 1: // available 16bit TSS
+ val = ((d->u.tss286.base & 0xffff) << 16) |
+ (d->u.tss286.limit & 0xffff);
+ return(val);
+
+ case 2: // LDT
+ val = ((d->u.ldt.base & 0xffff) << 16) |
+ d->u.ldt.limit;
+ return(val);
+
+ case 9: // available 32bit TSS
+ val = ((d->u.tss386.base & 0xffff) << 16) |
+ (d->u.tss386.limit & 0xffff);
+ return(val);
+
+ default:
+ BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+ return(0);
+ }
+ }
+}
+
+ Bit32u
+BX_CPU_C::dbg_get_descriptor_h(bx_descriptor_t *d)
+{
+ Bit32u val;
+
+ if (d->valid == 0) {
+ return(0);
+ }
+
+ if (d->segment) {
+ val = (d->u.segment.base & 0xff000000) |
+ ((d->u.segment.base >> 16) & 0x000000ff) |
+ (d->u.segment.executable << 11) |
+ (d->u.segment.c_ed << 10) |
+ (d->u.segment.r_w << 9) |
+ (d->u.segment.a << 8) |
+ (d->segment << 12) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.segment.limit & 0xf0000) |
+ (d->u.segment.avl << 20) |
+ (d->u.segment.d_b << 22) |
+ (d->u.segment.g << 23);
+ return(val);
+ }
+ else {
+ switch (d->type) {
+ case 0: // Reserved (not yet defined)
+ BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+ return(0);
+
+ case 1: // available 16bit TSS
+ val = ((d->u.tss286.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15);
+ return(val);
+
+ case 2: // LDT
+ val = ((d->u.ldt.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.ldt.base & 0xff000000);
+ return(val);
+
+ case 9: // available 32bit TSS
+ val = ((d->u.tss386.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.tss386.limit & 0xf0000) |
+ (d->u.tss386.avl << 20) |
+ (d->u.tss386.g << 23) |
+ (d->u.tss386.base & 0xff000000);
+ return(val);
+
+ default:
+ BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+ return(0);
+ }
+ }
+}
+
+ Boolean
+BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
+{
+ if (sreg_no > 5)
+ return(0);
+ sreg->sel = BX_CPU_THIS_PTR sregs[sreg_no].selector.value;
+ sreg->des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+ sreg->des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+ sreg->valid = BX_CPU_THIS_PTR sregs[sreg_no].cache.valid;
+ return(1);
+}
+
+ Boolean
+BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
+{
+ cpu->eax = EAX;
+ cpu->ebx = EBX;
+ cpu->ecx = ECX;
+ cpu->edx = EDX;
+
+ cpu->ebp = EBP;
+ cpu->esi = ESI;
+ cpu->edi = EDI;
+ cpu->esp = ESP;
+
+ cpu->eflags = dbg_get_eflags();
+ cpu->eip = BX_CPU_THIS_PTR eip;
+
+ cpu->cs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ cpu->cs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+ cpu->cs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+ cpu->cs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid;
+
+ cpu->ss.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ cpu->ss.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+ cpu->ss.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+ cpu->ss.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid;
+
+ cpu->ds.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+ cpu->ds.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+ cpu->ds.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+ cpu->ds.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid;
+
+ cpu->es.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+ cpu->es.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+ cpu->es.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+ cpu->es.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid;
+
+ cpu->fs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+ cpu->fs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+ cpu->fs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+ cpu->fs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid;
+
+ cpu->gs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+ cpu->gs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+ cpu->gs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+ cpu->gs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid;
+
+
+ cpu->ldtr.sel = BX_CPU_THIS_PTR ldtr.selector.value;
+ cpu->ldtr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
+ cpu->ldtr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
+ cpu->ldtr.valid = BX_CPU_THIS_PTR ldtr.cache.valid;
+
+ cpu->tr.sel = BX_CPU_THIS_PTR tr.selector.value;
+ cpu->tr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
+ cpu->tr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
+ cpu->tr.valid = BX_CPU_THIS_PTR tr.cache.valid;
+
+ cpu->gdtr.base = BX_CPU_THIS_PTR gdtr.base;
+ cpu->gdtr.limit = BX_CPU_THIS_PTR gdtr.limit;
+
+ cpu->idtr.base = BX_CPU_THIS_PTR idtr.base;
+ cpu->idtr.limit = BX_CPU_THIS_PTR idtr.limit;
+
+ cpu->dr0 = BX_CPU_THIS_PTR dr0;
+ cpu->dr1 = BX_CPU_THIS_PTR dr1;
+ cpu->dr2 = BX_CPU_THIS_PTR dr2;
+ cpu->dr3 = BX_CPU_THIS_PTR dr3;
+ cpu->dr6 = BX_CPU_THIS_PTR dr6;
+ cpu->dr7 = BX_CPU_THIS_PTR dr7;
+
+ cpu->tr3 = 0;
+ cpu->tr4 = 0;
+ cpu->tr5 = 0;
+ cpu->tr6 = 0;
+ cpu->tr7 = 0;
+
+ // cr0:32=pg,cd,nw,am,wp,ne,ts,em,mp,pe
+ cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
+ cpu->cr1 = 0;
+ cpu->cr2 = BX_CPU_THIS_PTR cr2;
+ cpu->cr3 = BX_CPU_THIS_PTR cr3;
+ cpu->cr4 = 0;
+
+ cpu->inhibit_mask = BX_CPU_THIS_PTR inhibit_mask;
+
+ return(1);
+}
+
+ Boolean
+BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
+{
+ // returns 1=OK, 0=Error
+ Bit32u val;
+ Bit32u type;
+
+ // =================================================
+ // Do checks first, before setting any CPU registers
+ // =================================================
+
+ // CS, SS, DS, ES, FS, GS descriptor checks
+ if (!cpu->cs.valid) {
+ BX_ERROR(( "Error: CS not valid\n" ));
+ return(0); // error
+ }
+ if ( (cpu->cs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: CS not application type\n" ));
+ return(0); // error
+ }
+ if ( (cpu->cs.des_h & 0x0800) == 0 ) {
+ BX_ERROR(( "Error: CS not executable\n" ));
+ return(0); // error
+ }
+
+ if (!cpu->ss.valid) {
+ BX_ERROR(( "Error: SS not valid\n" ));
+ return(0); // error
+ }
+ if ( (cpu->ss.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: SS not application type\n" ));
+ return(0); // error
+ }
+
+ if (cpu->ds.valid) {
+ if ( (cpu->ds.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: DS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->es.valid) {
+ if ( (cpu->es.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: ES not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->fs.valid) {
+ if ( (cpu->fs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: FS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->gs.valid) {
+ if ( (cpu->gs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: GS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->ldtr.valid) {
+ if ( cpu->ldtr.des_h & 0x1000 ) {
+ BX_ERROR(( "Error: LDTR not system type\n" ));
+ return(0); // error
+ }
+ if ( ((cpu->ldtr.des_h >> 8) & 0x0f) != 2 ) {
+ BX_ERROR(( "Error: LDTR descriptor type not LDT\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->tr.valid) {
+ if ( cpu->tr.des_h & 0x1000 ) {
+ BX_ERROR(( "Error: TR not system type\n"));
+ return(0); // error
+ }
+ type = (cpu->tr.des_h >> 8) & 0x0f;
+
+ if ( (type != 1) && (type != 9) ) {
+ BX_ERROR(( "Error: TR descriptor type not TSS\n" ));
+ return(0); // error
+ }
+ }
+
+ // =============
+ // end of checks
+ // =============
+
+ EAX = cpu->eax;
+ EBX = cpu->ebx;
+ ECX = cpu->ecx;
+ EDX = cpu->edx;
+ EBP = cpu->ebp;
+ ESI = cpu->esi;
+ EDI = cpu->edi;
+ ESP = cpu->esp;
+
+ // eflags
+ val = cpu->eflags;
+ BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR eflags.tf = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR eflags.iopl = val & 0x03; val >>= 2;
+ BX_CPU_THIS_PTR eflags.nt = val & 0x01; val >>= 2;
+ BX_CPU_THIS_PTR eflags.rf = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.vm = val & 0x01; val >>= 1;
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR eflags.ac = val & 0x01; val >>= 1;
+ //BX_CPU_THIS_PTR eflags.vif = val & 0x01;
+ val >>= 1;
+ //BX_CPU_THIS_PTR eflags.vip = val & 0x01;
+ val >>= 1;
+ BX_CPU_THIS_PTR eflags.id = val & 0x01;
+#endif
+
+ BX_CPU_THIS_PTR eip = cpu->eip;
+
+
+
+ // CS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cpu->cs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpu->cs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = cpu->cs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = (cpu->cs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = (cpu->cs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = (cpu->cs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = (cpu->cs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (cpu->cs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = (cpu->cs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = (cpu->cs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = (cpu->cs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (cpu->cs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = (cpu->cs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit |= (cpu->cs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = (cpu->cs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = (cpu->cs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = (cpu->cs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
+
+
+ // SS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = cpu->ss.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (cpu->ss.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpu->ss.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = cpu->ss.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = (cpu->ss.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = (cpu->ss.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = (cpu->ss.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = (cpu->ss.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (cpu->ss.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = (cpu->ss.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = (cpu->ss.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = (cpu->ss.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (cpu->ss.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = (cpu->ss.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit |= (cpu->ss.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = (cpu->ss.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = (cpu->ss.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = (cpu->ss.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
+
+
+ // DS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = (cpu->ds.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = cpu->ds.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = cpu->ds.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = (cpu->ds.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = (cpu->ds.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = (cpu->ds.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = (cpu->ds.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (cpu->ds.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = (cpu->ds.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w = (cpu->ds.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = (cpu->ds.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (cpu->ds.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = (cpu->ds.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit |= (cpu->ds.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = (cpu->ds.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = (cpu->ds.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = (cpu->ds.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
+
+
+
+ // ES:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = (cpu->es.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = cpu->es.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = cpu->es.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = (cpu->es.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = (cpu->es.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = (cpu->es.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type = (cpu->es.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (cpu->es.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = (cpu->es.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w = (cpu->es.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = (cpu->es.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (cpu->es.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = (cpu->es.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit |= (cpu->es.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g = (cpu->es.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = (cpu->es.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = (cpu->es.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
+
+
+ // FS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti = (cpu->fs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = cpu->fs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = cpu->fs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = (cpu->fs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = (cpu->fs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = (cpu->fs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type = (cpu->fs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = (cpu->fs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = (cpu->fs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w = (cpu->fs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a = (cpu->fs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base = (cpu->fs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit = (cpu->fs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit |= (cpu->fs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g = (cpu->fs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = (cpu->fs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = (cpu->fs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
+
+
+ // GS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti = (cpu->gs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = cpu->gs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = cpu->gs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = (cpu->gs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = (cpu->gs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = (cpu->gs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type = (cpu->gs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = (cpu->gs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = (cpu->gs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w = (cpu->gs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a = (cpu->gs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base = (cpu->gs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit = (cpu->gs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit |= (cpu->gs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g = (cpu->gs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = (cpu->gs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = (cpu->gs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
+
+ // LDTR:
+ BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
+ BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
+ BX_CPU_THIS_PTR ldtr.selector.ti = (cpu->ldtr.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR ldtr.selector.rpl = cpu->ldtr.sel & 0x03;
+
+ BX_CPU_THIS_PTR ldtr.cache.valid = cpu->ldtr.valid;
+ BX_CPU_THIS_PTR ldtr.cache.p = (cpu->ldtr.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR ldtr.cache.dpl = (cpu->ldtr.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR ldtr.cache.segment = (cpu->ldtr.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR ldtr.cache.type = (cpu->ldtr.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (cpu->ldtr.des_l >> 16);
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff000000);
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = (cpu->ldtr.des_l & 0xffff);
+
+ // TR
+ type = (cpu->tr.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
+ BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
+ BX_CPU_THIS_PTR tr.selector.ti = (cpu->tr.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR tr.selector.rpl = cpu->tr.sel & 0x03;
+
+ BX_CPU_THIS_PTR tr.cache.valid = cpu->tr.valid;
+ BX_CPU_THIS_PTR tr.cache.p = (cpu->tr.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.dpl = (cpu->tr.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR tr.cache.segment = (cpu->tr.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.type = type;
+ if (type == 1) { // 286 TSS
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base = (cpu->tr.des_l >> 16);
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base |= (cpu->tr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR tr.cache.u.tss286.limit = (cpu->tr.des_l & 0xffff);
+ }
+ else { // type == 9, 386 TSS
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base = (cpu->tr.des_l >> 16);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base |= (cpu->tr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base |= (cpu->tr.des_h & 0xff000000);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.limit = (cpu->tr.des_l & 0xffff);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.g = (cpu->tr.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.u.tss386.avl = (cpu->tr.des_h >> 20) & 0x01;
+ }
+
+
+ // gdtr
+ BX_CPU_THIS_PTR gdtr.base = cpu->gdtr.base;
+ BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
+
+ // idtr
+ BX_CPU_THIS_PTR idtr.base = cpu->idtr.base;
+ BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
+
+
+ BX_CPU_THIS_PTR dr0 = cpu->dr0;
+ BX_CPU_THIS_PTR dr1 = cpu->dr1;
+ BX_CPU_THIS_PTR dr2 = cpu->dr2;
+ BX_CPU_THIS_PTR dr3 = cpu->dr3;
+ BX_CPU_THIS_PTR dr6 = cpu->dr6;
+ BX_CPU_THIS_PTR dr7 = cpu->dr7;
+
+ // BX_CPU_THIS_PTR tr3 = cpu->tr3;
+ // BX_CPU_THIS_PTR tr4 = cpu->tr4;
+ // BX_CPU_THIS_PTR tr5 = cpu->tr5;
+ // BX_CPU_THIS_PTR tr6 = cpu->tr6;
+ // BX_CPU_THIS_PTR tr7 = cpu->tr7;
+
+
+ // cr0, cr1, cr2, cr3, cr4
+ SetCR0(cpu->cr0);
+ BX_CPU_THIS_PTR cr1 = cpu->cr1;
+ BX_CPU_THIS_PTR cr2 = cpu->cr2;
+ BX_CPU_THIS_PTR cr3 = cpu->cr3;
+#if BX_CPU_LEVEL >= 5
+ BX_CPU_THIS_PTR cr4 = cpu->cr4;
+#endif
+
+ BX_CPU_THIS_PTR inhibit_mask = cpu->inhibit_mask;
+
+ //
+ // flush cached items, prefetch, paging, etc
+ //
+ BX_CPU_THIS_PTR CR3_change(cpu->cr3);
+ BX_CPU_THIS_PTR invalidate_prefetch_q();
+ BX_CPU_THIS_PTR async_event = 1;
+
+ return(1);
+}
+
+#if BX_SIM_ID == 0
+# define BX_DBG_NULL_CALLBACK bx_dbg_null_callback0
+#else
+# define BX_DBG_NULL_CALLBACK bx_dbg_null_callback1
+#endif
+ void
+BX_DBG_NULL_CALLBACK(unsigned val)
+{
+ // bochs uses the pc_system variables, so this function is
+ // a stub for notification by the debugger, that a change
+ // occurred.
+ UNUSED(val);
+}
+
+ void
+#if BX_SIM_ID == 0
+bx_dbg_init_cpu_mem_env0(bx_dbg_callback_t *callback, int argc, char *argv[])
+#else
+bx_dbg_init_cpu_mem_env1(bx_dbg_callback_t *callback, int argc, char *argv[])
+#endif
+{
+ UNUSED(argc);
+ UNUSED(argv);
+
+#if 0
+#warning hardcoding BX_CPU_THIS_PTR mem[0] and cpu[0]
+ callback->setphymem = BX_MEM(0)->dbg_set_mem;
+ callback->getphymem = BX_MEM(0)->dbg_fetch_mem;
+ callback->xlate_linear2phy = BX_CPU(0)->dbg_xlate_linear2phy;
+ callback->set_reg = BX_CPU(0)->dbg_set_reg;
+ callback->get_reg = BX_CPU(0)->dbg_get_reg;
+ callback->get_sreg = BX_CPU(0)->dbg_get_sreg;
+ callback->get_cpu = BX_CPU(0)->dbg_get_cpu;
+ callback->set_cpu = BX_CPU(0)->dbg_set_cpu;
+ callback->dirty_page_tbl_size = sizeof(BX_MEM(0)->dbg_dirty_pages);
+ callback->dirty_page_tbl = BX_MEM(0)->dbg_dirty_pages;
+ callback->atexit = BX_CPU(0)->atexit;
+ callback->query_pending = BX_CPU(0)->dbg_query_pending;
+ callback->execute = BX_CPU(0)->cpu_loop;
+ callback->take_irq = BX_CPU(0)->dbg_take_irq;
+ callback->take_dma = BX_CPU(0)->dbg_take_dma;
+ callback->reset_cpu = BX_CPU(0)->reset;
+ callback->init_mem = BX_MEM(0)->init_memory;
+ callback->load_ROM = BX_MEM(0)->load_ROM;
+ callback->set_A20 = NULL;
+ callback->set_NMI = BX_DBG_NULL_CALLBACK;
+ callback->set_RESET = BX_DBG_NULL_CALLBACK;
+ callback->set_INTR = BX_CPU(0)->set_INTR;
+ callback->force_interrupt = BX_CPU(0)->dbg_force_interrupt;
+
+#if BX_INSTRUMENTATION
+ callback->instr_start = bx_instr_start;
+ callback->instr_stop = bx_instr_stop;
+ callback->instr_reset = bx_instr_reset;
+ callback->instr_print = bx_instr_print;
+#endif
+#if BX_USE_LOADER
+ callback->loader = bx_dbg_loader;
+#endif
+ callback->crc32 = BX_MEM(0)->dbg_crc32;
+#endif
+}
+
+
+
+ void
+BX_CPU_C::atexit(void)
+{
+ if (protected_mode()) BX_INFO(("protected mode\n" ));
+ else if (v8086_mode()) BX_INFO(("v8086 mode\n" ));
+ else BX_INFO(("real mode\n"));
+ BX_INFO(("CS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16 ));
+ if (protected_mode()) BX_INFO(("protected mode\n"));
+ else if (v8086_mode()) BX_INFO(("v8086 mode\n"));
+ else BX_INFO(("real mode\n"));
+ BX_INFO(("CS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16));
+ BX_INFO(("SS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_SS].cache.u.segment.d_b ? 32 : 16));
+
+ debug(BX_CPU_THIS_PTR prev_eip);
+}
+#endif // #if BX_DEBUGGER
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::debug(Bit32u offset)
+{
+ BX_INFO(("| EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n",
+ (unsigned) EAX, (unsigned) EBX, (unsigned) ECX, (unsigned) EDX));
+ BX_INFO(("| ESP=%08x EBP=%08x ESI=%08x EDI=%08x\n",
+ (unsigned) ESP, (unsigned) EBP, (unsigned) ESI, (unsigned) EDI));
+ BX_INFO(("| IOPL=%1u %s %s %s %s %s %s %s %s\n",
+ BX_CPU_THIS_PTR eflags.iopl,
+ BX_CPU_THIS_PTR get_OF() ? "OV" : "NV",
+ BX_CPU_THIS_PTR eflags.df ? "DW" : "UP",
+ BX_CPU_THIS_PTR eflags.if_ ? "EI" : "DI",
+ BX_CPU_THIS_PTR get_SF() ? "NG" : "PL",
+ BX_CPU_THIS_PTR get_ZF() ? "ZR" : "NZ",
+ BX_CPU_THIS_PTR get_AF() ? "AC" : "NA",
+ BX_CPU_THIS_PTR get_PF() ? "PE" : "PO",
+ BX_CPU_THIS_PTR get_CF() ? "CY" : "NC"));
+ BX_INFO(("| SEG selector base limit G D\n"));
+ BX_INFO(("| SEG sltr(index|ti|rpl) base limit G D\n"));
+ BX_INFO(("| DS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b));
+ BX_INFO(("| ES:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b));
+ BX_INFO(("| FS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b));
+ BX_INFO(("| GS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b));
+ BX_INFO(("| SS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b));
+ BX_INFO(("| CS:%04x( %04x| %01u| %1u) %08x %08x %1u %1u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b));
+ BX_INFO(("| EIP=%08x (%08x)\n", (unsigned) BX_CPU_THIS_PTR eip,
+ (unsigned) BX_CPU_THIS_PTR prev_eip));
+
+#if 0
+ /* (mch) Hack to display the area round EIP and prev_EIP */
+ char buf[100];
+ sprintf(buf, "%04x:%08x ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR eip);
+ for (int i = 0; i < 8; i++) {
+ Bit8u data;
+ BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR eip + i, &data);
+ sprintf(buf+strlen(buf), "%02x ", data);
+ }
+ sprintf(buf+strlen(buf), "\n");
+ BX_INFO((buf));
+
+ sprintf(buf, "%04x:%08x ", BX_CPU_THIS_PTR sregs[BX_SREG_CS].selector.value, BX_CPU_THIS_PTR prev_eip);
+ for (int i = 0; i < 8; i++) {
+ Bit8u data;
+ BX_CPU_THIS_PTR read_virtual_byte(BX_SREG_CS, BX_CPU_THIS_PTR prev_eip + i, &data);
+ sprintf(buf+strlen(buf), "%02x ", data);
+ }
+ sprintf(buf+strlen(buf), "\n");
+ BX_INFO((buf));
+#endif
+
+
+#if BX_DISASM
+ Boolean valid;
+ Bit32u phy_addr;
+ Bit8u instr_buf[32];
+ char char_buf[256];
+ unsigned isize;
+
+ dbg_xlate_linear2phy(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base + offset,
+ &phy_addr, &valid);
+ if (valid) {
+ BX_CPU_THIS_PTR mem->dbg_fetch_mem(phy_addr, 16, instr_buf);
+ isize = bx_disassemble.disasm(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b,
+ instr_buf, char_buf);
+ for (unsigned j=0; j<isize; j++)
+ BX_INFO((">> %02x\n", (unsigned) instr_buf[j]));
+ BX_INFO((">> : %s\n", char_buf));
+ }
+ else {
+ BX_INFO(("(instruction unavailable) page not present\n"));
+ }
+#else
+ UNUSED(offset);
+#endif // #if BX_DISASM
+}
+
+
+#if BX_DEBUGGER
+ Bit32u
+BX_CPU_C::dbg_get_reg(unsigned reg)
+{
+ Bit32u return_val32;
+
+ switch (reg) {
+ case BX_DBG_REG_EAX: return(EAX);
+ case BX_DBG_REG_ECX: return(ECX);
+ case BX_DBG_REG_EDX: return(EDX);
+ case BX_DBG_REG_EBX: return(EBX);
+ case BX_DBG_REG_ESP: return(ESP);
+ case BX_DBG_REG_EBP: return(EBP);
+ case BX_DBG_REG_ESI: return(ESI);
+ case BX_DBG_REG_EDI: return(EDI);
+ case BX_DBG_REG_EIP: return(EIP);
+ case BX_DBG_REG_EFLAGS:
+ return_val32 = dbg_get_eflags();
+ return(return_val32);
+ case BX_DBG_REG_CS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ case BX_DBG_REG_SS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+ case BX_DBG_REG_DS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+ case BX_DBG_REG_ES: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+ case BX_DBG_REG_FS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+ case BX_DBG_REG_GS: return(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+ default:
+ BX_PANIC(("get_reg: request for unknown register\n"));
+ return(0);
+ }
+}
+
+ Boolean
+BX_CPU_C::dbg_set_reg(unsigned reg, Bit32u val)
+{
+ // returns 1=OK, 0=can't change
+ bx_segment_reg_t *seg;
+ Bit32u current_sys_bits;
+
+ switch (reg) {
+ case BX_DBG_REG_EAX: EAX = val; return(1);
+ case BX_DBG_REG_ECX: ECX = val; return(1);
+ case BX_DBG_REG_EDX: EDX = val; return(1);
+ case BX_DBG_REG_EBX: EBX = val; return(1);
+ case BX_DBG_REG_ESP: ESP = val; return(1);
+ case BX_DBG_REG_EBP: EBP = val; return(1);
+ case BX_DBG_REG_ESI: ESI = val; return(1);
+ case BX_DBG_REG_EDI: EDI = val; return(1);
+ case BX_DBG_REG_EIP: EIP = val; return(1);
+ case BX_DBG_REG_EFLAGS:
+ BX_INFO(("dbg_set_reg: can not handle eflags yet.\n"));
+ if ( val & 0xffff0000 ) {
+ BX_INFO(("dbg_set_reg: can not set upper 16 bits of eflags.\n"));
+ return(0);
+ }
+ // make sure none of the system bits are being changed
+ current_sys_bits = (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.tf << 8);
+ if ( current_sys_bits != (val & 0x0000f100) ) {
+ BX_INFO(("dbg_set_reg: can not modify NT, IOPL, or TF.\n"));
+ return(0);
+ }
+ BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR set_OF(val & 0x01);
+ if (BX_CPU_THIS_PTR eflags.if_)
+ BX_CPU_THIS_PTR async_event = 1;
+ return(1);
+ case BX_DBG_REG_CS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+ break;
+ case BX_DBG_REG_SS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+ break;
+ case BX_DBG_REG_DS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS];
+ break;
+ case BX_DBG_REG_ES:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES];
+ break;
+ case BX_DBG_REG_FS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS];
+ break;
+ case BX_DBG_REG_GS:
+ seg = &BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS];
+ break;
+ default:
+ BX_PANIC(("dbg_set_reg: unrecognized register ID (%u)\n", reg));
+ return(0);
+ }
+
+ if (BX_CPU_THIS_PTR real_mode()) {
+ seg->selector.value = val;
+ seg->cache.valid = 1;
+ seg->cache.p = 1;
+ seg->cache.dpl = 0;
+ seg->cache.segment = 1; // regular segment
+ if (reg == BX_DBG_REG_CS) {
+ seg->cache.u.segment.executable = 1; // code segment
+ }
+ else {
+ seg->cache.u.segment.executable = 0; // data segment
+ }
+ seg->cache.u.segment.c_ed = 0; // expand up/non-conforming
+ seg->cache.u.segment.r_w = 1; // writeable
+ seg->cache.u.segment.a = 1; // accessed
+ seg->cache.u.segment.base = val << 4;
+ seg->cache.u.segment.limit = 0xffff;
+ seg->cache.u.segment.limit_scaled = 0xffff;
+ seg->cache.u.segment.g = 0; // byte granular
+ seg->cache.u.segment.d_b = 0; // default 16bit size
+ seg->cache.u.segment.avl = 0;
+ return(1); // ok
+ }
+
+ return(0); // can't change when not in real mode
+}
+
+ unsigned
+BX_CPU_C::dbg_query_pending(void)
+{
+ unsigned ret = 0;
+
+ if ( BX_HRQ ) { // DMA Hold Request
+ ret |= BX_DBG_PENDING_DMA;
+ }
+
+ if ( BX_CPU_THIS_PTR INTR && BX_CPU_THIS_PTR eflags.if_ ) {
+ ret |= BX_DBG_PENDING_IRQ;
+ }
+
+ return(ret);
+}
+
+
+
+ Bit32u
+BX_CPU_C::dbg_get_eflags(void)
+{
+ Bit32u val32;
+
+ val32 =
+ (BX_CPU_THIS_PTR get_CF()) |
+ (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+ ((BX_CPU_THIS_PTR get_PF()) << 2) |
+ (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+ ((BX_CPU_THIS_PTR get_AF()>0) << 4) |
+ (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+ ((BX_CPU_THIS_PTR get_ZF()>0) << 6) |
+ ((BX_CPU_THIS_PTR get_SF()>0) << 7) |
+ (BX_CPU_THIS_PTR eflags.tf << 8) |
+ (BX_CPU_THIS_PTR eflags.if_ << 9) |
+ (BX_CPU_THIS_PTR eflags.df << 10) |
+ ((BX_CPU_THIS_PTR get_OF()>0) << 11) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+ (BX_CPU_THIS_PTR eflags.rf << 16) |
+ (BX_CPU_THIS_PTR eflags.vm << 17);
+#if BX_CPU_LEVEL >= 4
+ val32 |= (BX_CPU_THIS_PTR eflags.ac << 18);
+ //val32 |= (BX_CPU_THIS_PTR eflags.vif << 19);
+ //val32 |= (BX_CPU_THIS_PTR eflags.vip << 20);
+ val32 |= (BX_CPU_THIS_PTR eflags.id << 21);
+#endif
+ return(val32);
+}
+
+
+ Bit32u
+BX_CPU_C::dbg_get_descriptor_l(bx_descriptor_t *d)
+{
+ Bit32u val;
+
+ if (d->valid == 0) {
+ return(0);
+ }
+
+ if (d->segment) {
+ val = ((d->u.segment.base & 0xffff) << 16) |
+ (d->u.segment.limit & 0xffff);
+ return(val);
+ }
+ else {
+ switch (d->type) {
+ case 0: // Reserved (not yet defined)
+ BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+ return(0);
+
+ case 1: // available 16bit TSS
+ val = ((d->u.tss286.base & 0xffff) << 16) |
+ (d->u.tss286.limit & 0xffff);
+ return(val);
+
+ case 2: // LDT
+ val = ((d->u.ldt.base & 0xffff) << 16) |
+ d->u.ldt.limit;
+ return(val);
+
+ case 9: // available 32bit TSS
+ val = ((d->u.tss386.base & 0xffff) << 16) |
+ (d->u.tss386.limit & 0xffff);
+ return(val);
+
+ default:
+ BX_ERROR(( "#get_descriptor_l(): type %d not finished\n", d->type ));
+ return(0);
+ }
+ }
+}
+
+ Bit32u
+BX_CPU_C::dbg_get_descriptor_h(bx_descriptor_t *d)
+{
+ Bit32u val;
+
+ if (d->valid == 0) {
+ return(0);
+ }
+
+ if (d->segment) {
+ val = (d->u.segment.base & 0xff000000) |
+ ((d->u.segment.base >> 16) & 0x000000ff) |
+ (d->u.segment.executable << 11) |
+ (d->u.segment.c_ed << 10) |
+ (d->u.segment.r_w << 9) |
+ (d->u.segment.a << 8) |
+ (d->segment << 12) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.segment.limit & 0xf0000) |
+ (d->u.segment.avl << 20) |
+ (d->u.segment.d_b << 22) |
+ (d->u.segment.g << 23);
+ return(val);
+ }
+ else {
+ switch (d->type) {
+ case 0: // Reserved (not yet defined)
+ BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+ return(0);
+
+ case 1: // available 16bit TSS
+ val = ((d->u.tss286.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15);
+ return(val);
+
+ case 2: // LDT
+ val = ((d->u.ldt.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.ldt.base & 0xff000000);
+ return(val);
+
+ case 9: // available 32bit TSS
+ val = ((d->u.tss386.base >> 16) & 0xff) |
+ (d->type << 8) |
+ (d->dpl << 13) |
+ (d->p << 15) |
+ (d->u.tss386.limit & 0xf0000) |
+ (d->u.tss386.avl << 20) |
+ (d->u.tss386.g << 23) |
+ (d->u.tss386.base & 0xff000000);
+ return(val);
+
+ default:
+ BX_ERROR(( "#get_descriptor_h(): type %d not finished\n", d->type ));
+ return(0);
+ }
+ }
+}
+
+ Boolean
+BX_CPU_C::dbg_get_sreg(bx_dbg_sreg_t *sreg, unsigned sreg_no)
+{
+ if (sreg_no > 5)
+ return(0);
+ sreg->sel = BX_CPU_THIS_PTR sregs[sreg_no].selector.value;
+ sreg->des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+ sreg->des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[sreg_no].cache);
+ sreg->valid = BX_CPU_THIS_PTR sregs[sreg_no].cache.valid;
+ return(1);
+}
+
+ Boolean
+BX_CPU_C::dbg_get_cpu(bx_dbg_cpu_t *cpu)
+{
+ cpu->eax = EAX;
+ cpu->ebx = EBX;
+ cpu->ecx = ECX;
+ cpu->edx = EDX;
+
+ cpu->ebp = EBP;
+ cpu->esi = ESI;
+ cpu->edi = EDI;
+ cpu->esp = ESP;
+
+ cpu->eflags = dbg_get_eflags();
+ cpu->eip = BX_CPU_THIS_PTR eip;
+
+ cpu->cs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ cpu->cs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+ cpu->cs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache);
+ cpu->cs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid;
+
+ cpu->ss.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ cpu->ss.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+ cpu->ss.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache);
+ cpu->ss.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid;
+
+ cpu->ds.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+ cpu->ds.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+ cpu->ds.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache);
+ cpu->ds.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid;
+
+ cpu->es.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+ cpu->es.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+ cpu->es.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache);
+ cpu->es.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid;
+
+ cpu->fs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+ cpu->fs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+ cpu->fs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache);
+ cpu->fs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid;
+
+ cpu->gs.sel = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+ cpu->gs.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+ cpu->gs.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache);
+ cpu->gs.valid = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid;
+
+
+ cpu->ldtr.sel = BX_CPU_THIS_PTR ldtr.selector.value;
+ cpu->ldtr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR ldtr.cache);
+ cpu->ldtr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache);
+ cpu->ldtr.valid = BX_CPU_THIS_PTR ldtr.cache.valid;
+
+ cpu->tr.sel = BX_CPU_THIS_PTR tr.selector.value;
+ cpu->tr.des_l = dbg_get_descriptor_l(&BX_CPU_THIS_PTR tr.cache);
+ cpu->tr.des_h = dbg_get_descriptor_h(&BX_CPU_THIS_PTR tr.cache);
+ cpu->tr.valid = BX_CPU_THIS_PTR tr.cache.valid;
+
+ cpu->gdtr.base = BX_CPU_THIS_PTR gdtr.base;
+ cpu->gdtr.limit = BX_CPU_THIS_PTR gdtr.limit;
+
+ cpu->idtr.base = BX_CPU_THIS_PTR idtr.base;
+ cpu->idtr.limit = BX_CPU_THIS_PTR idtr.limit;
+
+ cpu->dr0 = BX_CPU_THIS_PTR dr0;
+ cpu->dr1 = BX_CPU_THIS_PTR dr1;
+ cpu->dr2 = BX_CPU_THIS_PTR dr2;
+ cpu->dr3 = BX_CPU_THIS_PTR dr3;
+ cpu->dr6 = BX_CPU_THIS_PTR dr6;
+ cpu->dr7 = BX_CPU_THIS_PTR dr7;
+
+ cpu->tr3 = 0;
+ cpu->tr4 = 0;
+ cpu->tr5 = 0;
+ cpu->tr6 = 0;
+ cpu->tr7 = 0;
+
+ // cr0:32=pg,cd,nw,am,wp,ne,ts,em,mp,pe
+ cpu->cr0 = BX_CPU_THIS_PTR cr0.val32;
+ cpu->cr1 = 0;
+ cpu->cr2 = BX_CPU_THIS_PTR cr2;
+ cpu->cr3 = BX_CPU_THIS_PTR cr3;
+ cpu->cr4 = 0;
+
+ cpu->inhibit_mask = BX_CPU_THIS_PTR inhibit_mask;
+
+ return(1);
+}
+
+ Boolean
+BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
+{
+ // returns 1=OK, 0=Error
+ Bit32u val;
+ Bit32u type;
+
+ // =================================================
+ // Do checks first, before setting any CPU registers
+ // =================================================
+
+ // CS, SS, DS, ES, FS, GS descriptor checks
+ if (!cpu->cs.valid) {
+ BX_ERROR(( "Error: CS not valid\n" ));
+ return(0); // error
+ }
+ if ( (cpu->cs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: CS not application type\n" ));
+ return(0); // error
+ }
+ if ( (cpu->cs.des_h & 0x0800) == 0 ) {
+ BX_ERROR(( "Error: CS not executable\n" ));
+ return(0); // error
+ }
+
+ if (!cpu->ss.valid) {
+ BX_ERROR(( "Error: SS not valid\n" ));
+ return(0); // error
+ }
+ if ( (cpu->ss.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: SS not application type\n" ));
+ return(0); // error
+ }
+
+ if (cpu->ds.valid) {
+ if ( (cpu->ds.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: DS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->es.valid) {
+ if ( (cpu->es.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: ES not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->fs.valid) {
+ if ( (cpu->fs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: FS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->gs.valid) {
+ if ( (cpu->gs.des_h & 0x1000) == 0 ) {
+ BX_ERROR(( "Error: GS not application type\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->ldtr.valid) {
+ if ( cpu->ldtr.des_h & 0x1000 ) {
+ BX_ERROR(( "Error: LDTR not system type\n" ));
+ return(0); // error
+ }
+ if ( ((cpu->ldtr.des_h >> 8) & 0x0f) != 2 ) {
+ BX_ERROR(( "Error: LDTR descriptor type not LDT\n" ));
+ return(0); // error
+ }
+ }
+
+ if (cpu->tr.valid) {
+ if ( cpu->tr.des_h & 0x1000 ) {
+ BX_ERROR(( "Error: TR not system type\n"));
+ return(0); // error
+ }
+ type = (cpu->tr.des_h >> 8) & 0x0f;
+
+ if ( (type != 1) && (type != 9) ) {
+ BX_ERROR(( "Error: TR descriptor type not TSS\n" ));
+ return(0); // error
+ }
+ }
+
+ // =============
+ // end of checks
+ // =============
+
+ EAX = cpu->eax;
+ EBX = cpu->ebx;
+ ECX = cpu->ecx;
+ EDX = cpu->edx;
+ EBP = cpu->ebp;
+ ESI = cpu->esi;
+ EDI = cpu->edi;
+ ESP = cpu->esp;
+
+ // eflags
+ val = cpu->eflags;
+ BX_CPU_THIS_PTR set_CF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_PF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_AF(val & 0x01); val >>= 2;
+ BX_CPU_THIS_PTR set_ZF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR set_SF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR eflags.tf = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.if_ = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.df = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR set_OF(val & 0x01); val >>= 1;
+ BX_CPU_THIS_PTR eflags.iopl = val & 0x03; val >>= 2;
+ BX_CPU_THIS_PTR eflags.nt = val & 0x01; val >>= 2;
+ BX_CPU_THIS_PTR eflags.rf = val & 0x01; val >>= 1;
+ BX_CPU_THIS_PTR eflags.vm = val & 0x01; val >>= 1;
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR eflags.ac = val & 0x01; val >>= 1;
+ //BX_CPU_THIS_PTR eflags.vif = val & 0x01;
+ val >>= 1;
+ //BX_CPU_THIS_PTR eflags.vip = val & 0x01;
+ val >>= 1;
+ BX_CPU_THIS_PTR eflags.id = val & 0x01;
+#endif
+
+ BX_CPU_THIS_PTR eip = cpu->eip;
+
+
+
+ // CS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cpu->cs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cpu->cs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cpu->cs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpu->cs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = cpu->cs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = (cpu->cs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = (cpu->cs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = (cpu->cs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = (cpu->cs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (cpu->cs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = (cpu->cs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = (cpu->cs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = (cpu->cs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (cpu->cs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base |= (cpu->cs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = (cpu->cs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit |= (cpu->cs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = (cpu->cs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = (cpu->cs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = (cpu->cs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
+
+
+ // SS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = cpu->ss.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = cpu->ss.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (cpu->ss.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpu->ss.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = cpu->ss.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = (cpu->ss.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = (cpu->ss.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = (cpu->ss.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = (cpu->ss.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (cpu->ss.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = (cpu->ss.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = (cpu->ss.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = (cpu->ss.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (cpu->ss.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base |= (cpu->ss.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = (cpu->ss.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit |= (cpu->ss.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = (cpu->ss.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = (cpu->ss.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = (cpu->ss.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit;
+
+
+ // DS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = cpu->ds.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = cpu->ds.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = (cpu->ds.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = cpu->ds.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = cpu->ds.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = (cpu->ds.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = (cpu->ds.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = (cpu->ds.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = (cpu->ds.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (cpu->ds.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = (cpu->ds.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w = (cpu->ds.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = (cpu->ds.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (cpu->ds.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base |= (cpu->ds.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = (cpu->ds.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit |= (cpu->ds.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = (cpu->ds.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = (cpu->ds.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = (cpu->ds.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit;
+
+
+
+ // ES:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = cpu->es.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = cpu->es.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = (cpu->es.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = cpu->es.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = cpu->es.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = (cpu->es.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = (cpu->es.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = (cpu->es.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type = (cpu->es.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (cpu->es.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = (cpu->es.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w = (cpu->es.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = (cpu->es.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (cpu->es.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base |= (cpu->es.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = (cpu->es.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit |= (cpu->es.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g = (cpu->es.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = (cpu->es.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = (cpu->es.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit;
+
+
+ // FS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = cpu->fs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = cpu->fs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti = (cpu->fs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = cpu->fs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = cpu->fs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = (cpu->fs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = (cpu->fs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = (cpu->fs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type = (cpu->fs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = (cpu->fs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = (cpu->fs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w = (cpu->fs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a = (cpu->fs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base = (cpu->fs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base |= (cpu->fs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit = (cpu->fs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit |= (cpu->fs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g = (cpu->fs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = (cpu->fs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = (cpu->fs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit;
+
+
+ // GS:
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = cpu->gs.sel;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = cpu->gs.sel >> 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti = (cpu->gs.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = cpu->gs.sel & 0x03;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = cpu->gs.valid;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = (cpu->gs.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = (cpu->gs.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = (cpu->gs.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type = (cpu->gs.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = (cpu->gs.des_h >> 11) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = (cpu->gs.des_h >> 10) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w = (cpu->gs.des_h >> 9) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a = (cpu->gs.des_h >> 8) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base = (cpu->gs.des_l >> 16);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base |= (cpu->gs.des_h & 0xff000000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit = (cpu->gs.des_l & 0xffff);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit |= (cpu->gs.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g = (cpu->gs.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = (cpu->gs.des_h >> 22) & 0x01;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = (cpu->gs.des_h >> 20) & 0x01;
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g)
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+ (BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit << 12) | 0x0fff;
+ else
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit;
+
+ // LDTR:
+ BX_CPU_THIS_PTR ldtr.selector.value = cpu->ldtr.sel;
+ BX_CPU_THIS_PTR ldtr.selector.index = cpu->ldtr.sel >> 3;
+ BX_CPU_THIS_PTR ldtr.selector.ti = (cpu->ldtr.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR ldtr.selector.rpl = cpu->ldtr.sel & 0x03;
+
+ BX_CPU_THIS_PTR ldtr.cache.valid = cpu->ldtr.valid;
+ BX_CPU_THIS_PTR ldtr.cache.p = (cpu->ldtr.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR ldtr.cache.dpl = (cpu->ldtr.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR ldtr.cache.segment = (cpu->ldtr.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR ldtr.cache.type = (cpu->ldtr.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (cpu->ldtr.des_l >> 16);
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base |= (cpu->ldtr.des_h & 0xff000000);
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = (cpu->ldtr.des_l & 0xffff);
+
+ // TR
+ type = (cpu->tr.des_h >> 8) & 0x0f;
+ BX_CPU_THIS_PTR tr.selector.value = cpu->tr.sel;
+ BX_CPU_THIS_PTR tr.selector.index = cpu->tr.sel >> 3;
+ BX_CPU_THIS_PTR tr.selector.ti = (cpu->tr.sel >> 2) & 0x01;
+ BX_CPU_THIS_PTR tr.selector.rpl = cpu->tr.sel & 0x03;
+
+ BX_CPU_THIS_PTR tr.cache.valid = cpu->tr.valid;
+ BX_CPU_THIS_PTR tr.cache.p = (cpu->tr.des_h >> 15) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.dpl = (cpu->tr.des_h >> 13) & 0x03;
+ BX_CPU_THIS_PTR tr.cache.segment = (cpu->tr.des_h >> 12) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.type = type;
+ if (type == 1) { // 286 TSS
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base = (cpu->tr.des_l >> 16);
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base |= (cpu->tr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR tr.cache.u.tss286.limit = (cpu->tr.des_l & 0xffff);
+ }
+ else { // type == 9, 386 TSS
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base = (cpu->tr.des_l >> 16);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base |= (cpu->tr.des_h & 0xff) << 16;
+ BX_CPU_THIS_PTR tr.cache.u.tss386.base |= (cpu->tr.des_h & 0xff000000);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.limit = (cpu->tr.des_l & 0xffff);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.limit |= (cpu->tr.des_h & 0x000f0000);
+ BX_CPU_THIS_PTR tr.cache.u.tss386.g = (cpu->tr.des_h >> 23) & 0x01;
+ BX_CPU_THIS_PTR tr.cache.u.tss386.avl = (cpu->tr.des_h >> 20) & 0x01;
+ }
+
+
+ // gdtr
+ BX_CPU_THIS_PTR gdtr.base = cpu->gdtr.base;
+ BX_CPU_THIS_PTR gdtr.limit = cpu->gdtr.limit;
+
+ // idtr
+ BX_CPU_THIS_PTR idtr.base = cpu->idtr.base;
+ BX_CPU_THIS_PTR idtr.limit = cpu->idtr.limit;
+
+
+ BX_CPU_THIS_PTR dr0 = cpu->dr0;
+ BX_CPU_THIS_PTR dr1 = cpu->dr1;
+ BX_CPU_THIS_PTR dr2 = cpu->dr2;
+ BX_CPU_THIS_PTR dr3 = cpu->dr3;
+ BX_CPU_THIS_PTR dr6 = cpu->dr6;
+ BX_CPU_THIS_PTR dr7 = cpu->dr7;
+
+ // BX_CPU_THIS_PTR tr3 = cpu->tr3;
+ // BX_CPU_THIS_PTR tr4 = cpu->tr4;
+ // BX_CPU_THIS_PTR tr5 = cpu->tr5;
+ // BX_CPU_THIS_PTR tr6 = cpu->tr6;
+ // BX_CPU_THIS_PTR tr7 = cpu->tr7;
+
+
+ // cr0, cr1, cr2, cr3, cr4
+ SetCR0(cpu->cr0);
+ BX_CPU_THIS_PTR cr1 = cpu->cr1;
+ BX_CPU_THIS_PTR cr2 = cpu->cr2;
+ BX_CPU_THIS_PTR cr3 = cpu->cr3;
+#if BX_CPU_LEVEL >= 5
+ BX_CPU_THIS_PTR cr4 = cpu->cr4;
+#endif
+
+ BX_CPU_THIS_PTR inhibit_mask = cpu->inhibit_mask;
+
+ //
+ // flush cached items, prefetch, paging, etc
+ //
+ BX_CPU_THIS_PTR CR3_change(cpu->cr3);
+ BX_CPU_THIS_PTR invalidate_prefetch_q();
+ BX_CPU_THIS_PTR async_event = 1;
+
+ return(1);
+}
+
+#if BX_SIM_ID == 0
+# define BX_DBG_NULL_CALLBACK bx_dbg_null_callback0
+#else
+# define BX_DBG_NULL_CALLBACK bx_dbg_null_callback1
+#endif
+ void
+BX_DBG_NULL_CALLBACK(unsigned val)
+{
+ // bochs uses the pc_system variables, so this function is
+ // a stub for notification by the debugger, that a change
+ // occurred.
+ UNUSED(val);
+}
+
+ void
+#if BX_SIM_ID == 0
+bx_dbg_init_cpu_mem_env0(bx_dbg_callback_t *callback, int argc, char *argv[])
+#else
+bx_dbg_init_cpu_mem_env1(bx_dbg_callback_t *callback, int argc, char *argv[])
+#endif
+{
+ UNUSED(argc);
+ UNUSED(argv);
+
+#if 0
+#warning hardcoding BX_CPU_THIS_PTR mem[0] and cpu[0]
+ callback->setphymem = BX_MEM(0)->dbg_set_mem;
+ callback->getphymem = BX_MEM(0)->dbg_fetch_mem;
+ callback->xlate_linear2phy = BX_CPU(0)->dbg_xlate_linear2phy;
+ callback->set_reg = BX_CPU(0)->dbg_set_reg;
+ callback->get_reg = BX_CPU(0)->dbg_get_reg;
+ callback->get_sreg = BX_CPU(0)->dbg_get_sreg;
+ callback->get_cpu = BX_CPU(0)->dbg_get_cpu;
+ callback->set_cpu = BX_CPU(0)->dbg_set_cpu;
+ callback->dirty_page_tbl_size = sizeof(BX_MEM(0)->dbg_dirty_pages);
+ callback->dirty_page_tbl = BX_MEM(0)->dbg_dirty_pages;
+ callback->atexit = BX_CPU(0)->atexit;
+ callback->query_pending = BX_CPU(0)->dbg_query_pending;
+ callback->execute = BX_CPU(0)->cpu_loop;
+ callback->take_irq = BX_CPU(0)->dbg_take_irq;
+ callback->take_dma = BX_CPU(0)->dbg_take_dma;
+ callback->reset_cpu = BX_CPU(0)->reset;
+ callback->init_mem = BX_MEM(0)->init_memory;
+ callback->load_ROM = BX_MEM(0)->load_ROM;
+ callback->set_A20 = NULL;
+ callback->set_NMI = BX_DBG_NULL_CALLBACK;
+ callback->set_RESET = BX_DBG_NULL_CALLBACK;
+ callback->set_INTR = BX_CPU(0)->set_INTR;
+ callback->force_interrupt = BX_CPU(0)->dbg_force_interrupt;
+
+#if BX_INSTRUMENTATION
+ callback->instr_start = bx_instr_start;
+ callback->instr_stop = bx_instr_stop;
+ callback->instr_reset = bx_instr_reset;
+ callback->instr_print = bx_instr_print;
+#endif
+#if BX_USE_LOADER
+ callback->loader = bx_dbg_loader;
+#endif
+ callback->crc32 = BX_MEM(0)->dbg_crc32;
+#endif
+}
+
+#endif // #if BX_DEBUGGER
+
+ void
+BX_CPU_C::atexit(void)
+{
+ if (protected_mode()) BX_INFO(("protected mode\n" ));
+ else if (v8086_mode()) BX_INFO(("v8086 mode\n" ));
+ else BX_INFO(("real mode\n"));
+ BX_INFO(("CS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16 ));
+ if (protected_mode()) BX_INFO(("protected mode\n"));
+ else if (v8086_mode()) BX_INFO(("v8086 mode\n"));
+ else BX_INFO(("real mode\n"));
+ BX_INFO(("CS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_CS].cache.u.segment.d_b ? 32 : 16));
+ BX_INFO(("SS.d_b = %u bit\n",
+ BX_CPU_THIS_PTR sregs[BX_SREG_SS].cache.u.segment.d_b ? 32 : 16));
+
+ debug(BX_CPU_THIS_PTR prev_eip);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+static Bit16u *aaa[8] = {
+ & BX,
+ & BX,
+ & BP,
+ & BP,
+ & SI,
+ & DI,
+ & BP,
+ & BX,
+ };
+
+static Bit16u *bbb[8] = {
+ & SI,
+ & DI,
+ & SI,
+ & DI,
+ (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+ (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+ (Bit16u *) & BX_CPU_THIS_PTR empty_register,
+ (Bit16u *) & BX_CPU_THIS_PTR empty_register
+ };
+#endif // BX_USE_CPU_SMF
+
+
+
+ void
+BX_CPU_C::decode_exgx16(unsigned modrm)
+{
+#if 0
+ Bit8u displ8;
+ Bit16u displ16;
+ unsigned mod, rm;
+
+#if BX_WEIRDISMS
+ i->seg_reg = NULL;
+#endif
+
+ // | 76 | 543 | 210
+ // | mod | ttt | rm
+
+ BX_INSTR_MODRM16(modrm);
+ i->nnn = (modrm>>3) & 0x07;
+ mod = modrm & 0xc0;
+ rm = modrm & 0x07;
+
+ if (mod == 0xc0) {
+ i->rm_addr = rm;
+ BX_CPU_THIS_PTR rm_type = BX_REGISTER_REF;
+ return;
+ }
+ else { // mod != 3
+ BX_CPU_THIS_PTR rm_type = BX_MEMORY_REF;
+
+ if (mod == 0x40) {
+ displ8 = fetch_next_byte();
+ i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit8s) displ8);
+ if (i->seg_reg == NULL)
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+ else
+ i->seg_reg = i->seg_reg;
+ return;
+ }
+ if (mod == 0x80) {
+ displ16 = fetch_next_word();
+ i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm] + (Bit16s) displ16);
+ if (i->seg_reg == NULL)
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+ else
+ i->seg_reg = i->seg_reg;
+ return;
+ }
+
+ // mod == 0x00
+ if (rm==6)
+ i->rm_addr = fetch_next_word();
+ else
+ i->rm_addr = (Bit16u) (*aaa[rm] + *bbb[rm]);
+
+ if (i->seg_reg == NULL)
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+ else
+ i->seg_reg = i->seg_reg;
+ return;
+ }
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::decode_exgx32(unsigned modrm)
+{
+#if 0
+ unsigned mod, rm, ss;
+ unsigned sib, base, index;
+ Bit32u displ32, index_reg_val, base_reg_val;
+ Bit8u displ8;
+
+ /* NOTES:
+ * seg_reg_mod01_base & mod10_base aren't correct???
+ */
+ /* use 32bit addressing modes. orthogonal base & index registers,
+ scaling available, etc. */
+
+ BX_INSTR_MODRM32(modrm);
+
+ mod = modrm & 0xc0;
+ rm = modrm & 0x07;
+
+ i->nnn = (modrm>>3) & 0x07;
+
+ if (mod == 0xc0) { /* mod, reg, reg */
+ i->rm_addr = rm;
+ BX_CPU_THIS_PTR rm_type = BX_REGISTER_REF;
+#if BX_WEIRDISMS
+ i->seg_reg = NULL;
+#endif
+ }
+ else { /* mod != 3 */
+ BX_CPU_THIS_PTR rm_type = BX_MEMORY_REF;
+ if (rm != 4) { /* rm != 100b, no s-i-b byte */
+ // one byte modrm
+ if (mod == 0x00) {
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = & BX_CPU_THIS_PTR ds;
+ if (rm == 5) { // no reg, 32-bit displacement
+ i->rm_addr = fetch_next_dword();
+ }
+ else {
+ // else reg indirect, no displacement
+ i->rm_addr = BX_READ_32BIT_REG(rm);
+ }
+ return;
+ }
+ if (mod == 0x40) {
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+ // reg, 8-bit displacement, sign extend
+ displ8 = fetch_next_byte();
+ i->rm_addr = BX_READ_32BIT_REG(rm);
+ i->rm_addr += ((Bit8s) displ8);
+ return;
+ }
+ // mod == 0x80
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+ // reg, 32-bit displacement
+ displ32 = fetch_next_dword();
+ i->rm_addr = BX_READ_32BIT_REG(rm);
+ i->rm_addr += displ32;
+ return;
+ }
+ else { /* rm == 4, s-i-b byte follows */
+ sib = fetch_next_byte();
+ BX_INSTR_SIB32(sib);
+ base = sib & 0x07; sib >>= 3;
+ index = sib & 0x07; sib >>= 3;
+ ss = sib;
+
+ if (mod == 0x00) {
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod00_base32[base];
+ if (base != 5) /* base != 101b, no displacement */
+ base_reg_val = BX_READ_32BIT_REG(base);
+ else {
+ BX_INSTR_SIB_mod0_base5(ss);
+ base_reg_val = fetch_next_dword();
+ }
+ index_reg_val = 0;
+ if (index != 4) {
+ index_reg_val = BX_READ_32BIT_REG(index);
+ index_reg_val <<= ss;
+ }
+#ifdef BX_INSTR_SIB_MOD0_IND4
+ else {
+ BX_INSTR_SIB_MOD0_IND4();
+ }
+#endif
+ i->rm_addr = base_reg_val + index_reg_val;
+ return;
+ }
+ if (mod == 0x40) {
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod01_base32[base];
+ displ8 = fetch_next_byte();
+ base_reg_val = BX_READ_32BIT_REG(base);
+ index_reg_val = 0;
+ if (index != 4) {
+ index_reg_val = BX_READ_32BIT_REG(index);
+ index_reg_val <<= ss;
+ }
+#ifdef BX_INSTR_SIB_MOD1_IND4
+ else {
+ BX_INSTR_SIB_MOD1_IND4();
+ }
+#endif
+ i->rm_addr = base_reg_val + index_reg_val + (Bit8s) displ8;
+ return;
+ }
+
+ // mod == 0x80
+ if (i->seg_reg)
+ i->seg_reg = i->seg_reg;
+ else
+ i->seg_reg = BX_CPU_THIS_PTR sreg_mod10_base32[base];
+ displ32 = fetch_next_dword();
+ base_reg_val = BX_READ_32BIT_REG(base);
+ index_reg_val = 0;
+ if (index != 4) {
+ index_reg_val = BX_READ_32BIT_REG(index);
+ index_reg_val <<= ss;
+ }
+#ifdef BX_INSTR_SIB_MOD2_IND4
+ else {
+ BX_INSTR_SIB_MOD2_IND4();
+ }
+#endif
+ i->rm_addr = base_reg_val + index_reg_val + displ32;
+ return;
+ }
+ } /* if (mod != 3) */
+#endif
+}
--- /dev/null
+// exception-sid.cc - override the bochs cpu interrupt member function. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#include "x86.h"
+
+ void
+sid_cpu_c::interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+ Bit16u error_code)
+{
+ if (vector == 0x80)
+ {
+ int temp = this->gen_reg[0].erx;
+ this->sid_cpu->do_syscall();
+#if X86_CPU_DEBUG
+ printf("Syscall number: %d was executed with the following return value: %d\n", temp, this->gen_reg[0].erx);
+#endif
+ }
+ else if (vector == 0x03)
+ {
+ // INT3 was encountered -- trap to debugger
+ this->sid_cpu->do_breakpoint();
+ }
+ else
+ {
+ BX_CPU_C::interrupt(vector, is_INT, is_error_code, error_code);
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+/* Exception classes. These are used as indexes into the 'is_exception_OK'
+ * array below, and are stored in the 'exception' array also
+ */
+#define BX_ET_BENIGN 0
+#define BX_ET_CONTRIBUTORY 1
+#define BX_ET_PAGE_FAULT 2
+
+#define BX_ET_DOUBLE_FAULT 10
+
+
+const Boolean BX_CPU_C::is_exception_OK[3][3] = {
+ { 1, 1, 1 }, /* 1st exception is BENIGN */
+ { 1, 0, 1 }, /* 1st exception is CONTRIBUTORY */
+ { 1, 0, 0 } /* 1st exception is PAGE_FAULT */
+ };
+
+
+ void
+BX_CPU_C::interrupt(Bit8u vector, Boolean is_INT, Boolean is_error_code,
+ Bit16u error_code)
+{
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_intsig;
+#if BX_DEBUG_LINUX
+ if (bx_dbg.linux_syscall) {
+ if (vector == 0x80) bx_dbg_linux_syscall ();
+ }
+#endif
+#endif
+
+//BX_DEBUG(( "::interrupt(%u)\n", vector ));
+
+ BX_INSTR_INTERRUPT(vector);
+ invalidate_prefetch_q();
+
+ // Discard any traps and inhibits for new context; traps will
+ // resume upon return.
+ BX_CPU_THIS_PTR debug_trap = 0;
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+
+#if BX_CPU_LEVEL >= 2
+// unsigned prev_errno;
+
+#if BX_DEBUGGER
+ if (bx_dbg.interrupts)
+ BX_INFO(("interrupt(): vector = %u, INT = %u, EXT = %u\n",
+ (unsigned) vector, (unsigned) is_INT, (unsigned) BX_CPU_THIS_PTR EXT));
+#endif
+BX_CPU_THIS_PTR save_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS];
+BX_CPU_THIS_PTR save_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS];
+BX_CPU_THIS_PTR save_eip = EIP;
+BX_CPU_THIS_PTR save_esp = ESP;
+
+// prev_errno = BX_CPU_THIS_PTR errorno;
+
+ if(!real_mode()) {
+ Bit32u dword1, dword2;
+ bx_descriptor_t gate_descriptor, cs_descriptor;
+ bx_selector_t cs_selector;
+
+ Bit16u raw_tss_selector;
+ bx_selector_t tss_selector;
+ bx_descriptor_t tss_descriptor;
+
+ Bit16u gate_dest_selector;
+ Bit32u gate_dest_offset;
+
+
+ // interrupt vector must be within IDT table limits,
+ // else #GP(vector number*8 + 2 + EXT)
+ if ( (vector*8 + 7) > BX_CPU_THIS_PTR idtr.limit) {
+#if BX_DEBUGGER
+ if (bx_dbg.interrupts) {
+ BX_INFO(("IDT.limit = %04x\n", (unsigned) BX_CPU_THIS_PTR idtr.limit));
+ BX_INFO(("IDT.base = %06x\n", (unsigned) BX_CPU_THIS_PTR idtr.base));
+ BX_INFO(("interrupt vector must be within IDT table limits\n"));
+ BX_INFO(("bailing\n"));
+ }
+ BX_INFO(("interrupt(): vector > idtr.limit\n"));
+#endif
+ exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+ }
+
+ // descriptor AR byte must indicate interrupt gate, trap gate,
+ // or task gate, else #GP(vector*8 + 2 + EXT)
+ access_linear(BX_CPU_THIS_PTR idtr.base + vector*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR idtr.base + vector*8 + 4, 4, 0,
+ BX_READ, &dword2);
+
+ parse_descriptor(dword1, dword2, &gate_descriptor);
+
+ if ( (gate_descriptor.valid==0) || gate_descriptor.segment) {
+ BX_PANIC(("interrupt(): gate descriptor is not valid sys seg\n"));
+ exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+ }
+
+ switch (gate_descriptor.type) {
+ case 5: // task gate
+ case 6: // 286 interrupt gate
+ case 7: // 286 trap gate
+ case 14: // 386 interrupt gate
+ case 15: // 386 trap gate
+ break;
+ default:
+ BX_INFO(("interrupt(): gate.type(%u) != {5,6,7,14,15}\n",
+ (unsigned) gate_descriptor.type));
+ exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+ return;
+ }
+
+ // if software interrupt, then gate descripor DPL must be >= CPL,
+ // else #GP(vector * 8 + 2 + EXT)
+ if (is_INT && (gate_descriptor.dpl < CPL)) {
+/* ??? */
+ BX_INFO(("interrupt(): is_INT && (dpl < CPL)\n"));
+ exception(BX_GP_EXCEPTION, vector*8 + 2, 0);
+ return;
+ }
+
+ // Gate must be present, else #NP(vector * 8 + 2 + EXT)
+ if (gate_descriptor.p == 0) {
+ BX_INFO(("interrupt(): p == 0\n"));
+ exception(BX_NP_EXCEPTION, vector*8 + 2, 0);
+ }
+
+ switch (gate_descriptor.type) {
+ case 5: // 286/386 task gate
+ // examine selector to TSS, given in task gate descriptor
+ raw_tss_selector = gate_descriptor.u.taskgate.tss_selector;
+ parse_selector(raw_tss_selector, &tss_selector);
+
+ // must specify global in the local/global bit,
+ // else #TS(TSS selector)
+// +++
+// 486/Pent books say #TSS(selector)
+// PPro+ says #GP(selector)
+ if (tss_selector.ti) {
+ BX_PANIC(("interrupt: tss_selector.ti=1\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ return;
+ }
+
+ // index must be within GDT limits, else #TS(TSS selector)
+ fetch_raw_descriptor(&tss_selector, &dword1, &dword2,
+ BX_TS_EXCEPTION);
+
+ // AR byte must specify available TSS,
+ // else #TS(TSS selector)
+ parse_descriptor(dword1, dword2, &tss_descriptor);
+ if (tss_descriptor.valid==0 || tss_descriptor.segment) {
+ BX_PANIC(("exception: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ return;
+ }
+ if (tss_descriptor.type!=9 && tss_descriptor.type!=1) {
+ BX_PANIC(("exception: TSS selector points to bad TSS\n"));
+ exception(BX_TS_EXCEPTION, raw_tss_selector & 0xfffc, 0);
+ return;
+ }
+
+
+ // TSS must be present, else #NP(TSS selector)
+ // done in task_switch()
+
+ // switch tasks with nesting to TSS
+ task_switch(&tss_selector, &tss_descriptor,
+ BX_TASK_FROM_CALL_OR_INT, dword1, dword2);
+
+ // if interrupt was caused by fault with error code
+ // stack limits must allow push of 2 more bytes, else #SS(0)
+ // push error code onto stack
+
+ //??? push_16 vs push_32
+ if ( is_error_code ) {
+ //if (tss_descriptor.type==9)
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b)
+ push_32(error_code);
+ else
+ push_16(error_code);
+ }
+
+ // instruction pointer must be in CS limit, else #GP(0)
+ //if (EIP > cs_descriptor.u.segment.limit_scaled) {}
+ if (EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("exception(): eIP > CS.limit\n"));
+ exception(BX_GP_EXCEPTION, 0x0000, 0);
+ }
+ return;
+ break;
+
+ case 6: // 286 interrupt gate
+ case 7: // 286 trap gate
+ case 14: // 386 interrupt gate
+ case 15: // 386 trap gate
+ if ( gate_descriptor.type >= 14 ) { // 386 gate
+ gate_dest_selector = gate_descriptor.u.gate386.dest_selector;
+ gate_dest_offset = gate_descriptor.u.gate386.dest_offset;
+ }
+ else { // 286 gate
+ gate_dest_selector = gate_descriptor.u.gate286.dest_selector;
+ gate_dest_offset = gate_descriptor.u.gate286.dest_offset;
+ }
+
+ // examine CS selector and descriptor given in gate descriptor
+ // selector must be non-null else #GP(EXT)
+ if ( (gate_dest_selector & 0xfffc) == 0 ) {
+ BX_PANIC(("int_trap_gate(): selector null\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ parse_selector(gate_dest_selector, &cs_selector);
+
+ // selector must be within its descriptor table limits
+ // else #GP(selector+EXT)
+ fetch_raw_descriptor(&cs_selector, &dword1, &dword2,
+ BX_GP_EXCEPTION);
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ // descriptor AR byte must indicate code seg
+ // and code segment descriptor DPL<=CPL, else #GP(selector+EXT)
+ if ( cs_descriptor.valid==0 ||
+ cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0 ||
+ cs_descriptor.dpl>CPL ) {
+ BX_INFO(("interrupt(): not code segment\n"));
+ exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+ }
+
+ // segment must be present, else #NP(selector + EXT)
+ if ( cs_descriptor.p==0 ) {
+ BX_PANIC(("interrupt(): segment not present\n"));
+ exception(BX_NP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+ }
+
+ // if code segment is non-conforming and DPL < CPL then
+ // INTERRUPT TO INNER PRIVILEGE:
+ if ( cs_descriptor.u.segment.c_ed==0 && cs_descriptor.dpl<CPL ) {
+ Bit16u old_SS, old_CS, SS_for_cpl_x;
+ Bit32u ESP_for_cpl_x, old_EIP, old_ESP;
+ bx_descriptor_t ss_descriptor;
+ bx_selector_t ss_selector;
+ int bytes;
+#if BX_DEBUGGER
+ if (bx_dbg.interrupts)
+ BX_INFO(("interrupt(): INTERRUPT TO INNER PRIVILEGE\n"));
+#endif
+ // check selector and descriptor for new stack in current TSS
+ get_SS_ESP_from_TSS(cs_descriptor.dpl,
+ &SS_for_cpl_x, &ESP_for_cpl_x);
+
+ // Selector must be non-null else #TS(EXT)
+ if ( (SS_for_cpl_x & 0xfffc) == 0 ) {
+ BX_PANIC(("interrupt(): SS selector null\n"));
+ /* TS(ext) */
+ exception(BX_TS_EXCEPTION, 0, 0);
+ }
+
+ // selector index must be within its descriptor table limits
+ // else #TS(SS selector + EXT)
+ parse_selector(SS_for_cpl_x, &ss_selector);
+ // fetch 2 dwords of descriptor; call handles out of limits checks
+ fetch_raw_descriptor(&ss_selector, &dword1, &dword2,
+ BX_TS_EXCEPTION);
+ parse_descriptor(dword1, dword2, &ss_descriptor);
+
+ // selector rpl must = dpl of code segment,
+ // else #TS(SS selector + ext)
+ if (ss_selector.rpl != cs_descriptor.dpl) {
+ BX_PANIC(("interrupt(): SS.rpl != CS.dpl\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ }
+
+ // stack seg DPL must = DPL of code segment,
+ // else #TS(SS selector + ext)
+ if (ss_descriptor.dpl != cs_descriptor.dpl) {
+ BX_PANIC(("interrupt(): SS.dpl != CS.dpl\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ }
+
+ // descriptor must indicate writable data segment,
+ // else #TS(SS selector + EXT)
+ if (ss_descriptor.valid==0 ||
+ ss_descriptor.segment==0 ||
+ ss_descriptor.u.segment.executable==1 ||
+ ss_descriptor.u.segment.r_w==0) {
+ BX_PANIC(("interrupt(): SS not writable data segment\n"));
+ exception(BX_TS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ }
+
+ // seg must be present, else #SS(SS selector + ext)
+ if (ss_descriptor.p==0) {
+ BX_PANIC(("interrupt(): SS not present\n"));
+ exception(BX_SS_EXCEPTION, SS_for_cpl_x & 0xfffc, 0);
+ }
+
+ if (gate_descriptor.type>=14) {
+ // 386 int/trap gate
+ // new stack must have room for 20|24 bytes, else #SS(0)
+ if ( is_error_code )
+ bytes = 24;
+ else
+ bytes = 20;
+ if (v8086_mode())
+ bytes += 16;
+ }
+ else {
+ // new stack must have room for 10|12 bytes, else #SS(0)
+ if ( is_error_code )
+ bytes = 12;
+ else
+ bytes = 10;
+ if (v8086_mode()) {
+ bytes += 8;
+ BX_PANIC(("interrupt: int/trap gate VM\n"));
+ }
+ }
+
+// 486,Pentium books
+// new stack must have room for 10/12 bytes, else #SS(0) 486 book
+// PPro+
+// new stack must have room for 10/12 bytes, else #SS(seg selector)
+ if ( !can_push(&ss_descriptor, ESP_for_cpl_x, bytes) ) {
+ BX_PANIC(("interrupt(): new stack doesn't have room for %u bytes\n",
+ (unsigned) bytes));
+ // SS(???)
+ }
+
+ // IP must be within CS segment boundaries, else #GP(0)
+ if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("interrupt(): gate eIP > CS.limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ old_ESP = ESP;
+ old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ old_EIP = EIP;
+ old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+
+ // load new SS:SP values from TSS
+ load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl);
+
+ if (ss_descriptor.u.segment.d_b)
+ ESP = ESP_for_cpl_x;
+ else
+ SP = ESP_for_cpl_x; // leave upper 16bits
+
+ // load new CS:IP values from gate
+ // set CPL to new code segment DPL
+ // set RPL of CS to CPL
+ load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl);
+ EIP = gate_dest_offset;
+
+ if (gate_descriptor.type>=14) { // 386 int/trap gate
+ if (v8086_mode()) {
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0;
+ }
+ // push long pointer to old stack onto new stack
+ push_32(old_SS);
+ push_32(old_ESP);
+
+ // push EFLAGS
+ push_32(read_eflags());
+
+ // push long pointer to return address onto new stack
+ push_32(old_CS);
+ push_32(old_EIP);
+
+ if ( is_error_code )
+ push_32(error_code);
+ }
+ else { // 286 int/trap gate
+ if (v8086_mode()) {
+ BX_PANIC(("286 int/trap gate, VM\n"));
+ }
+ // push long pointer to old stack onto new stack
+ push_16(old_SS);
+ push_16(old_ESP); // ignores upper 16bits
+
+ // push FLAGS
+ push_16(read_flags());
+
+ // push return address onto new stack
+ push_16(old_CS);
+ push_16(old_EIP); // ignores upper 16bits
+
+ if ( is_error_code )
+ push_16(error_code);
+ }
+
+ // if INTERRUPT GATE set IF to 0
+ if ( !(gate_descriptor.type & 1) ) // even is int-gate
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+ BX_CPU_THIS_PTR eflags.tf = 0;
+ BX_CPU_THIS_PTR eflags.vm = 0;
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ BX_CPU_THIS_PTR eflags.nt = 0;
+ return;
+ }
+
+ if (v8086_mode()) {
+ exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+ }
+
+ // if code segment is conforming OR code segment DPL = CPL then
+ // INTERRUPT TO SAME PRIVILEGE LEVEL:
+ if ( cs_descriptor.u.segment.c_ed==1 || cs_descriptor.dpl==CPL ) {
+ int bytes;
+ Bit32u temp_ESP;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+#if BX_DEBUGGER
+ if (bx_dbg.interrupts)
+ BX_INFO(("int_trap_gate286(): INTERRUPT TO SAME PRIVILEGE\n"));
+#endif
+ // Current stack limits must allow pushing 6|8 bytes, else #SS(0)
+ if (gate_descriptor.type >= 14) { // 386 gate
+ if ( is_error_code )
+ bytes = 16;
+ else
+ bytes = 12;
+ }
+ else { // 286 gate
+ if ( is_error_code )
+ bytes = 8;
+ else
+ bytes = 6;
+ }
+
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache,
+ temp_ESP, bytes) ) {
+ BX_INFO(("interrupt(): stack doesn't have room\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+
+ // eIP must be in CS limit else #GP(0)
+ if (gate_dest_offset > cs_descriptor.u.segment.limit_scaled) {
+ BX_PANIC(("interrupt(): IP > cs descriptor limit\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ // push flags onto stack
+ // push current CS selector onto stack
+ // push return offset onto stack
+ if (gate_descriptor.type >= 14) { // 386 gate
+ push_32(read_eflags());
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_32(EIP);
+ if ( is_error_code )
+ push_32(error_code);
+ }
+ else { // 286 gate
+ push_16(read_flags());
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ push_16(IP);
+ if ( is_error_code )
+ push_16(error_code);
+ }
+
+ // load CS:IP from gate
+ // load CS descriptor
+ // set the RPL field of CS to CPL
+ load_cs(&cs_selector, &cs_descriptor, CPL);
+ EIP = gate_dest_offset;
+
+ // if interrupt gate then set IF to 0
+ if ( !(gate_descriptor.type & 1) ) // even is int-gate
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+ BX_CPU_THIS_PTR eflags.tf = 0;
+ BX_CPU_THIS_PTR eflags.nt = 0;
+ BX_CPU_THIS_PTR eflags.vm = 0;
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ return;
+ }
+
+ // else #GP(CS selector + ext)
+ BX_INFO(("interrupt: bad descriptor\n"));
+ BX_INFO(("c_ed=%u, descriptor.dpl=%u, CPL=%u\n",
+ (unsigned) cs_descriptor.u.segment.c_ed,
+ (unsigned) cs_descriptor.dpl,
+ (unsigned) CPL));
+ BX_INFO(("cs.segment = %u\n", (unsigned) cs_descriptor.segment));
+ exception(BX_GP_EXCEPTION, cs_selector.value & 0xfffc, 0);
+ break;
+
+ default:
+ BX_PANIC(("bad descriptor type in interrupt()!\n"));
+ break;
+ }
+ }
+ else
+#endif
+ { /* real mode */
+ Bit16u cs_selector, ip;
+
+ if ( (vector*4+3) > BX_CPU_THIS_PTR idtr.limit )
+ BX_PANIC(("interrupt(real mode) vector > limit\n"));
+
+ push_16(read_flags());
+
+ cs_selector = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ push_16(cs_selector);
+ ip = BX_CPU_THIS_PTR eip;
+ push_16(ip);
+
+ access_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector, 2, 0, BX_READ, &ip);
+ IP = ip;
+ access_linear(BX_CPU_THIS_PTR idtr.base + 4 * vector + 2, 2, 0, BX_READ, &cs_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_selector);
+
+ /* INT affects the following flags: I,T */
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+ BX_CPU_THIS_PTR eflags.tf = 0;
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR eflags.ac = 0;
+#endif
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::exception(unsigned vector, Bit16u error_code, Boolean is_INT)
+ // vector: 0..255: vector in IDT
+ // error_code: if exception generates and error, push this error code
+{
+ Boolean push_error;
+ Bit8u exception_type;
+ unsigned prev_errno;
+
+//BX_DEBUG(( "::exception(%u)\n", vector ));
+
+ BX_INSTR_EXCEPTION(vector);
+ invalidate_prefetch_q();
+
+ UNUSED(is_INT);
+#if BX_DEBUGGER
+ if (bx_dbg.exceptions)
+ BX_INFO(("exception(%02x h)\n", (unsigned) vector));
+#endif
+ // if not initial error, restore previous register values from
+ // previous attempt to handle exception
+ if (BX_CPU_THIS_PTR errorno) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS] = BX_CPU_THIS_PTR save_cs;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS] = BX_CPU_THIS_PTR save_ss;
+ EIP = BX_CPU_THIS_PTR save_eip;
+ ESP = BX_CPU_THIS_PTR save_esp;
+ }
+
+ BX_CPU_THIS_PTR errorno++;
+ if (BX_CPU_THIS_PTR errorno >= 3) {
+ BX_PANIC(("exception(): 3rd exception with no resolution\n"));
+ }
+
+ /* careful not to get here with curr_exception[1]==DOUBLE_FAULT */
+ /* ...index on DOUBLE_FAULT below, will be out of bounds */
+
+ /* if 1st was a double fault (software INT?), then shutdown */
+ if ( (BX_CPU_THIS_PTR errorno==2) && (BX_CPU_THIS_PTR curr_exception[0]==BX_ET_DOUBLE_FAULT) ) {
+ BX_PANIC(("exception(): tripple fault encountered\n"));
+ }
+
+ /* ??? this is not totally correct, should be done depending on
+ * vector */
+ /* backup IP to value before error occurred */
+ EIP = BX_CPU_THIS_PTR prev_eip;
+ ESP = BX_CPU_THIS_PTR prev_esp;
+
+ // note: fault-class exceptions _except_ #DB set RF in
+ // eflags image.
+
+ switch (vector) {
+ case 0: // DIV by 0
+ push_error = 0;
+ exception_type = BX_ET_CONTRIBUTORY;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 1: // debug exceptions
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ break;
+ case 2: // NMI
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ break;
+ case 3: // breakpoint
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ break;
+ case 4: // overflow
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ break;
+ case 5: // bounds check
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 6: // invalid opcode
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 7: // device not available
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 8: // double fault
+ push_error = 1;
+ exception_type = BX_ET_DOUBLE_FAULT;
+ break;
+ case 9: // coprocessor segment overrun (286,386 only)
+ push_error = 0;
+ exception_type = BX_ET_CONTRIBUTORY;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ BX_PANIC(("exception(9): unfinished\n"));
+ break;
+ case 10: // invalid TSS
+ push_error = 1;
+ exception_type = BX_ET_CONTRIBUTORY;
+ error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 11: // segment not present
+ push_error = 1;
+ exception_type = BX_ET_CONTRIBUTORY;
+ error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 12: // stack fault
+ push_error = 1;
+ exception_type = BX_ET_CONTRIBUTORY;
+ error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 13: // general protection
+ push_error = 1;
+ exception_type = BX_ET_CONTRIBUTORY;
+ error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 14: // page fault
+ push_error = 1;
+ exception_type = BX_ET_PAGE_FAULT;
+ // ??? special format error returned
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+ case 15: // reserved
+ BX_PANIC(("exception(15): reserved\n"));
+ push_error = 0; // keep compiler happy for now
+ exception_type = 0; // keep compiler happy for now
+ break;
+ case 16: // floating-point error
+ push_error = 0;
+ exception_type = BX_ET_BENIGN;
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+#if BX_CPU_LEVEL >= 4
+ case 17: // alignment check
+ BX_PANIC(("exception(): alignment-check, vector 17 unimplemented\n"));
+ push_error = 0; // keep compiler happy for now
+ exception_type = 0; // keep compiler happy for now
+ BX_CPU_THIS_PTR eflags.rf = 1;
+ break;
+#endif
+#if BX_CPU_LEVEL >= 5
+ case 18: // machine check
+ BX_PANIC(("exception(): machine-check, vector 18 unimplemented\n"));
+ push_error = 0; // keep compiler happy for now
+ exception_type = 0; // keep compiler happy for now
+ break;
+#endif
+ default:
+ BX_PANIC(("exception(%u): bad vector\n", (unsigned) vector));
+ push_error = 0; // keep compiler happy for now
+ exception_type = 0; // keep compiler happy for now
+ break;
+ }
+
+ if (exception_type != BX_ET_PAGE_FAULT) {
+ // Page faults have different format
+ error_code = (error_code & 0xfffe) | BX_CPU_THIS_PTR EXT;
+ }
+ BX_CPU_THIS_PTR EXT = 1;
+
+ /* if we've already had 1st exception, see if 2nd causes a
+ * Double Fault instead. Otherwise, just record 1st exception
+ */
+ if (BX_CPU_THIS_PTR errorno >= 2) {
+ if (is_exception_OK[BX_CPU_THIS_PTR curr_exception[0]][exception_type])
+ BX_CPU_THIS_PTR curr_exception[1] = exception_type;
+ else {
+ BX_CPU_THIS_PTR curr_exception[1] = BX_ET_DOUBLE_FAULT;
+ vector = 8;
+ }
+ }
+ else {
+ BX_CPU_THIS_PTR curr_exception[0] = exception_type;
+ }
+
+
+#if BX_CPU_LEVEL >= 2
+ if (!real_mode()) {
+ prev_errno = BX_CPU_THIS_PTR errorno;
+ BX_CPU_THIS_PTR interrupt(vector, 0, push_error, error_code);
+// if (BX_CPU_THIS_PTR errorno > prev_errno) {
+// BX_INFO(("segment_exception(): errorno changed\n"));
+// longjmp(jmp_buf_env, 1); // go back to main decode loop
+// return;
+// }
+
+// if (push_error) {
+// /* push error code on stack, after handling interrupt */
+// /* pushed as a word or dword depending upon default size ??? */
+// if (ss.cache.u.segment.d_b)
+// push_32((Bit32u) error_code); /* upper bits reserved */
+// else
+// push_16(error_code);
+// if (BX_CPU_THIS_PTR errorno > prev_errno) {
+// BX_PANIC(("segment_exception(): errorno changed\n"));
+// return;
+// }
+// }
+ BX_CPU_THIS_PTR errorno = 0; // error resolved
+ longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
+ }
+ else // real mode
+#endif
+ {
+ // not INT, no error code pushed
+ BX_CPU_THIS_PTR interrupt(vector, 0, 0, 0);
+ BX_CPU_THIS_PTR errorno = 0; // error resolved
+ longjmp(BX_CPU_THIS_PTR jmp_buf_env, 1); // go back to main decode loop
+ }
+}
+
+
+ int
+BX_CPU_C::int_number(bx_segment_reg_t *seg)
+{
+ if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS])
+ return(BX_SS_EXCEPTION);
+ else
+ return(BX_GP_EXCEPTION);
+}
+
+ void
+BX_CPU_C::shutdown_cpu(void)
+{
+
+#if BX_CPU_LEVEL > 2
+ BX_PANIC(("shutdown_cpu(): not implemented for 386\n"));
+#endif
+
+ invalidate_prefetch_q();
+ BX_PANIC(("shutdown_cpu(): not finished\n"));
+
+}
--- /dev/null
+// fetchdecode-sid.cc - override the bochs cpu fetchdecode member function. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+///////////////////////////
+// prefix bytes
+// opcode bytes
+// modrm/sib
+// address displacement
+// immediate constant
+///////////////////////////
+
+
+
+// sign extended to osize:
+// 6a push ib
+// 6b imul gvevib
+// 70..7f jo..jnle
+// 83 G1 0..7 ADD..CMP Evib
+
+// is 6b imul_gvevib sign extended? don't think
+// I'm sign extending it properly in old decode/execute
+
+//check all the groups. Make sure to add duplicates rather
+// than error.
+
+// mark instructions as changing control transfer, then
+// don't always load from fetch_ptr, etc.
+
+// cant use immediate as another because of Group3 where
+// some have immediate and some don't, and those won't
+// be picked up by logic until indirection.
+
+// get attr and execute ptr at same time
+
+// maybe move 16bit only i's like MOV_EwSw, MOV_SwEw
+// to 32 bit modules.
+
+// use 0F as a prefix too?
+
+
+
+#if 0
+void BxResolveError(BxInstruction_t *);
+#endif
+
+#if BX_DYNAMIC_TRANSLATION
+// For 16-bit address mode, this matrix describes the registers
+// used to formulate the offset, indexed by the RM field.
+// This info is needed by the dynamic translation code for dataflow.
+static unsigned BxMemRegsUsed16[8] = {
+ (1<<3) | (1<<6), // BX + SI
+ (1<<3) | (1<<7), // BX + DI
+ (1<<5) | (1<<6), // BP + SI
+ (1<<5) | (1<<7), // BP + DI
+ (1<<6), // SI
+ (1<<7), // DI
+ (1<<5), // BP
+ (1<<3) // BX
+ };
+#endif
+
+static BxExecutePtr_t BxResolve16Mod0[8] = {
+ &BX_CPU_C::Resolve16Mod0Rm0,
+ &BX_CPU_C::Resolve16Mod0Rm1,
+ &BX_CPU_C::Resolve16Mod0Rm2,
+ &BX_CPU_C::Resolve16Mod0Rm3,
+ &BX_CPU_C::Resolve16Mod0Rm4,
+ &BX_CPU_C::Resolve16Mod0Rm5,
+ NULL, // d16, no registers used
+ &BX_CPU_C::Resolve16Mod0Rm7
+ };
+
+static BxExecutePtr_t BxResolve16Mod1or2[8] = {
+ &BX_CPU_C::Resolve16Mod1or2Rm0,
+ &BX_CPU_C::Resolve16Mod1or2Rm1,
+ &BX_CPU_C::Resolve16Mod1or2Rm2,
+ &BX_CPU_C::Resolve16Mod1or2Rm3,
+ &BX_CPU_C::Resolve16Mod1or2Rm4,
+ &BX_CPU_C::Resolve16Mod1or2Rm5,
+ &BX_CPU_C::Resolve16Mod1or2Rm6,
+ &BX_CPU_C::Resolve16Mod1or2Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod0[8] = {
+ &BX_CPU_C::Resolve32Mod0Rm0,
+ &BX_CPU_C::Resolve32Mod0Rm1,
+ &BX_CPU_C::Resolve32Mod0Rm2,
+ &BX_CPU_C::Resolve32Mod0Rm3,
+ NULL, // escape to 2-byte
+ NULL, // d32, no registers used
+ &BX_CPU_C::Resolve32Mod0Rm6,
+ &BX_CPU_C::Resolve32Mod0Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod1or2[8] = {
+ &BX_CPU_C::Resolve32Mod1or2Rm0,
+ &BX_CPU_C::Resolve32Mod1or2Rm1,
+ &BX_CPU_C::Resolve32Mod1or2Rm2,
+ &BX_CPU_C::Resolve32Mod1or2Rm3,
+ NULL, // escape to 2-byte
+ &BX_CPU_C::Resolve32Mod1or2Rm5,
+ &BX_CPU_C::Resolve32Mod1or2Rm6,
+ &BX_CPU_C::Resolve32Mod1or2Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod0Base[8] = {
+ &BX_CPU_C::Resolve32Mod0Base0,
+ &BX_CPU_C::Resolve32Mod0Base1,
+ &BX_CPU_C::Resolve32Mod0Base2,
+ &BX_CPU_C::Resolve32Mod0Base3,
+ &BX_CPU_C::Resolve32Mod0Base4,
+ &BX_CPU_C::Resolve32Mod0Base5,
+ &BX_CPU_C::Resolve32Mod0Base6,
+ &BX_CPU_C::Resolve32Mod0Base7,
+ };
+
+static BxExecutePtr_t BxResolve32Mod1or2Base[8] = {
+ &BX_CPU_C::Resolve32Mod1or2Base0,
+ &BX_CPU_C::Resolve32Mod1or2Base1,
+ &BX_CPU_C::Resolve32Mod1or2Base2,
+ &BX_CPU_C::Resolve32Mod1or2Base3,
+ &BX_CPU_C::Resolve32Mod1or2Base4,
+ &BX_CPU_C::Resolve32Mod1or2Base5,
+ &BX_CPU_C::Resolve32Mod1or2Base6,
+ &BX_CPU_C::Resolve32Mod1or2Base7,
+ };
+
+typedef struct BxOpcodeInfo_t {
+ Bit16u Attr;
+ SidExecutePtr_t ExecutePtr;
+ struct BxOpcodeInfo_t *AnotherArray;
+} BxOpcodeInfo_t;
+
+static BxOpcodeInfo_t BxOpcodeInfoG1EbIb[8] = {
+ /* 0 */ { BxImmediate_Ib, &BX_CPU_C::ADD_EbIb },
+ /* 1 */ { BxImmediate_Ib, &BX_CPU_C::OR_EbIb },
+ /* 2 */ { BxImmediate_Ib, &BX_CPU_C::ADC_EbIb },
+ /* 3 */ { BxImmediate_Ib, &BX_CPU_C::SBB_EbIb },
+ /* 4 */ { BxImmediate_Ib, &BX_CPU_C::AND_EbIb },
+ /* 5 */ { BxImmediate_Ib, &BX_CPU_C::SUB_EbIb },
+ /* 6 */ { BxImmediate_Ib, &BX_CPU_C::XOR_EbIb },
+ /* 7 */ { BxImmediate_Ib, &BX_CPU_C::CMP_EbIb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ew[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ADD_EwIw },
+ /* 1 */ { 0, &BX_CPU_C::OR_EwIw },
+ /* 2 */ { 0, &BX_CPU_C::ADC_EwIw },
+ /* 3 */ { 0, &BX_CPU_C::SBB_EwIw },
+ /* 4 */ { 0, &BX_CPU_C::AND_EwIw },
+ /* 5 */ { 0, &BX_CPU_C::SUB_EwIw },
+ /* 6 */ { 0, &BX_CPU_C::XOR_EwIw },
+ /* 7 */ { 0, &BX_CPU_C::CMP_EwIw }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ed[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ADD_EdId },
+ /* 1 */ { 0, &BX_CPU_C::OR_EdId },
+ /* 2 */ { 0, &BX_CPU_C::ADC_EdId },
+ /* 3 */ { 0, &BX_CPU_C::SBB_EdId },
+ /* 4 */ { 0, &BX_CPU_C::AND_EdId },
+ /* 5 */ { 0, &BX_CPU_C::SUB_EdId },
+ /* 6 */ { 0, &BX_CPU_C::XOR_EdId },
+ /* 7 */ { 0, &BX_CPU_C::CMP_EdId }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Eb[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Eb },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Eb },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Eb },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Eb },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Eb },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Eb },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Eb },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Eb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ew[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Ew },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Ew },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Ew },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Ew },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Ew },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Ew },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Ew },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Ew }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ed[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Ed },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Ed },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Ed },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Ed },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Ed },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Ed },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Ed },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Ed }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Eb[8] = {
+ /* 0 */ { BxImmediate_Ib, &BX_CPU_C::TEST_EbIb },
+ /* 1 */ { BxImmediate_Ib, &BX_CPU_C::TEST_EbIb },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Eb },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Eb },
+ /* 4 */ { 0, &BX_CPU_C::MUL_ALEb },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_ALEb },
+ /* 6 */ { 0, &BX_CPU_C::DIV_ALEb },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_ALEb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ew[8] = {
+ /* 0 */ { BxImmediate_Iw, &BX_CPU_C::TEST_EwIw },
+ /* 1 */ { BxImmediate_Iw, &BX_CPU_C::TEST_EwIw },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Ew },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Ew },
+ /* 4 */ { 0, &BX_CPU_C::MUL_AXEw },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_AXEw },
+ /* 6 */ { 0, &BX_CPU_C::DIV_AXEw },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_AXEw }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ed[8] = {
+ /* 0 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EdId },
+ /* 1 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EdId },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Ed },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Ed },
+ /* 4 */ { 0, &BX_CPU_C::MUL_EAXEd },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_EAXEd },
+ /* 6 */ { 0, &BX_CPU_C::DIV_EAXEd },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_EAXEd }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG4[8] = {
+ /* 0 */ { 0, &BX_CPU_C::INC_Eb },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Eb },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { 0, &BX_CPU_C::BxError },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG5w[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::INC_Ew },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Ew },
+ /* 2 */ { 0, &BX_CPU_C::CALL_Ew },
+ /* 3 */ { 0, &BX_CPU_C::CALL16_Ep },
+ /* 4 */ { 0, &BX_CPU_C::JMP_Ew },
+ /* 5 */ { 0, &BX_CPU_C::JMP16_Ep },
+ /* 6 */ { 0, &BX_CPU_C::PUSH_Ew },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG5d[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::INC_Ed },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Ed },
+ /* 2 */ { 0, &BX_CPU_C::CALL_Ed },
+ /* 3 */ { 0, &BX_CPU_C::CALL32_Ep },
+ /* 4 */ { 0, &BX_CPU_C::JMP_Ed },
+ /* 5 */ { 0, &BX_CPU_C::JMP32_Ep },
+ /* 6 */ { 0, &BX_CPU_C::PUSH_Ed },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::SLDT_Ew },
+ /* 1 */ { 0, &BX_CPU_C::STR_Ew },
+ /* 2 */ { 0, &BX_CPU_C::LLDT_Ew },
+ /* 3 */ { 0, &BX_CPU_C::LTR_Ew },
+ /* 4 */ { 0, &BX_CPU_C::VERR_Ew },
+ /* 5 */ { 0, &BX_CPU_C::VERW_Ew },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG7[8] = {
+ /* 0 */ { 0, &BX_CPU_C::SGDT_Ms },
+ /* 1 */ { 0, &BX_CPU_C::SIDT_Ms },
+ /* 2 */ { 0, &BX_CPU_C::LGDT_Ms },
+ /* 3 */ { 0, &BX_CPU_C::LIDT_Ms },
+ /* 4 */ { 0, &BX_CPU_C::SMSW_Ew },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::LMSW_Ew },
+ /* 7 */ { 0, &BX_CPU_C::INVLPG }
+ };
+
+
+static BxOpcodeInfo_t BxOpcodeInfoG8EvIb[8] = {
+ /* 0 */ { 0, &BX_CPU_C::BxError },
+ /* 1 */ { 0, &BX_CPU_C::BxError },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { BxImmediate_Ib, &BX_CPU_C::BT_EvIb },
+ /* 5 */ { BxImmediate_Ib, &BX_CPU_C::BTS_EvIb },
+ /* 6 */ { BxImmediate_Ib, &BX_CPU_C::BTR_EvIb },
+ /* 7 */ { BxImmediate_Ib, &BX_CPU_C::BTC_EvIb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG9[8] = {
+ /* 0 */ { 0, &BX_CPU_C::BxError },
+ /* 1 */ { 0, &BX_CPU_C::CMPXCHG8B },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { 0, &BX_CPU_C::BxError },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+
+// 512 entries for 16bit mode
+// 512 entries for 32bit mode
+
+static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
+ // 512 entries for 16bit mode
+ /* 00 */ { BxAnother, &BX_CPU_C::ADD_EbGb },
+ /* 01 */ { BxAnother, &BX_CPU_C::ADD_EwGw },
+ /* 02 */ { BxAnother, &BX_CPU_C::ADD_GbEb },
+ /* 03 */ { BxAnother, &BX_CPU_C::ADD_GwEw },
+ /* 04 */ { BxImmediate_Ib, &BX_CPU_C::ADD_ALIb },
+ /* 05 */ { BxImmediate_Iv, &BX_CPU_C::ADD_AXIw },
+ /* 06 */ { 0, &BX_CPU_C::PUSH_ES },
+ /* 07 */ { 0, &BX_CPU_C::POP_ES },
+ /* 08 */ { BxAnother, &BX_CPU_C::OR_EbGb },
+ /* 09 */ { BxAnother, &BX_CPU_C::OR_EwGw },
+ /* 0A */ { BxAnother, &BX_CPU_C::OR_GbEb },
+ /* 0B */ { BxAnother, &BX_CPU_C::OR_GwEw },
+ /* 0C */ { BxImmediate_Ib, &BX_CPU_C::OR_ALIb },
+ /* 0D */ { BxImmediate_Iv, &BX_CPU_C::OR_AXIw },
+ /* 0E */ { 0, &BX_CPU_C::PUSH_CS },
+ /* 0F */ { BxAnother, &BX_CPU_C::BxError }, // 2-byte escape
+ /* 10 */ { BxAnother, &BX_CPU_C::ADC_EbGb },
+ /* 11 */ { BxAnother, &BX_CPU_C::ADC_EwGw },
+ /* 12 */ { BxAnother, &BX_CPU_C::ADC_GbEb },
+ /* 13 */ { BxAnother, &BX_CPU_C::ADC_GwEw },
+ /* 14 */ { BxImmediate_Ib, &BX_CPU_C::ADC_ALIb },
+ /* 15 */ { BxImmediate_Iv, &BX_CPU_C::ADC_AXIw },
+ /* 16 */ { 0, &BX_CPU_C::PUSH_SS },
+ /* 17 */ { 0, &BX_CPU_C::POP_SS },
+ /* 18 */ { BxAnother, &BX_CPU_C::SBB_EbGb },
+ /* 19 */ { BxAnother, &BX_CPU_C::SBB_EwGw },
+ /* 1A */ { BxAnother, &BX_CPU_C::SBB_GbEb },
+ /* 1B */ { BxAnother, &BX_CPU_C::SBB_GwEw },
+ /* 1C */ { BxImmediate_Ib, &BX_CPU_C::SBB_ALIb },
+ /* 1D */ { BxImmediate_Iv, &BX_CPU_C::SBB_AXIw },
+ /* 1E */ { 0, &BX_CPU_C::PUSH_DS },
+ /* 1F */ { 0, &BX_CPU_C::POP_DS },
+ /* 20 */ { BxAnother, &BX_CPU_C::AND_EbGb },
+ /* 21 */ { BxAnother, &BX_CPU_C::AND_EwGw },
+ /* 22 */ { BxAnother, &BX_CPU_C::AND_GbEb },
+ /* 23 */ { BxAnother, &BX_CPU_C::AND_GwEw },
+ /* 24 */ { BxImmediate_Ib, &BX_CPU_C::AND_ALIb },
+ /* 25 */ { BxImmediate_Iv, &BX_CPU_C::AND_AXIw },
+ /* 26 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // ES:
+ /* 27 */ { 0, &BX_CPU_C::DAA },
+ /* 28 */ { BxAnother, &BX_CPU_C::SUB_EbGb },
+ /* 29 */ { BxAnother, &BX_CPU_C::SUB_EwGw },
+ /* 2A */ { BxAnother, &BX_CPU_C::SUB_GbEb },
+ /* 2B */ { BxAnother, &BX_CPU_C::SUB_GwEw },
+ /* 2C */ { BxImmediate_Ib, &BX_CPU_C::SUB_ALIb },
+ /* 2D */ { BxImmediate_Iv, &BX_CPU_C::SUB_AXIw },
+ /* 2E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // CS:
+ /* 2F */ { 0, &BX_CPU_C::DAS },
+ /* 30 */ { BxAnother, &BX_CPU_C::XOR_EbGb },
+ /* 31 */ { BxAnother, &BX_CPU_C::XOR_EwGw },
+ /* 32 */ { BxAnother, &BX_CPU_C::XOR_GbEb },
+ /* 33 */ { BxAnother, &BX_CPU_C::XOR_GwEw },
+ /* 34 */ { BxImmediate_Ib, &BX_CPU_C::XOR_ALIb },
+ /* 35 */ { BxImmediate_Iv, &BX_CPU_C::XOR_AXIw },
+ /* 36 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // SS:
+ /* 37 */ { 0, &BX_CPU_C::AAA },
+ /* 38 */ { BxAnother, &BX_CPU_C::CMP_EbGb },
+ /* 39 */ { BxAnother, &BX_CPU_C::CMP_EwGw },
+ /* 3A */ { BxAnother, &BX_CPU_C::CMP_GbEb },
+ /* 3B */ { BxAnother, &BX_CPU_C::CMP_GwEw },
+ /* 3C */ { BxImmediate_Ib, &BX_CPU_C::CMP_ALIb },
+ /* 3D */ { BxImmediate_Iv, &BX_CPU_C::CMP_AXIw },
+ /* 3E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // DS:
+ /* 3F */ { 0, &BX_CPU_C::AAS },
+ /* 40 */ { 0, &BX_CPU_C::INC_RX },
+ /* 41 */ { 0, &BX_CPU_C::INC_RX },
+ /* 42 */ { 0, &BX_CPU_C::INC_RX },
+ /* 43 */ { 0, &BX_CPU_C::INC_RX },
+ /* 44 */ { 0, &BX_CPU_C::INC_RX },
+ /* 45 */ { 0, &BX_CPU_C::INC_RX },
+ /* 46 */ { 0, &BX_CPU_C::INC_RX },
+ /* 47 */ { 0, &BX_CPU_C::INC_RX },
+ /* 48 */ { 0, &BX_CPU_C::DEC_RX },
+ /* 49 */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4A */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4B */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4C */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4D */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4E */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4F */ { 0, &BX_CPU_C::DEC_RX },
+ /* 50 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 51 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 52 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 53 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 54 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 55 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 56 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 57 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 58 */ { 0, &BX_CPU_C::POP_RX },
+ /* 59 */ { 0, &BX_CPU_C::POP_RX },
+ /* 5A */ { 0, &BX_CPU_C::POP_RX },
+ /* 5B */ { 0, &BX_CPU_C::POP_RX },
+ /* 5C */ { 0, &BX_CPU_C::POP_RX },
+ /* 5D */ { 0, &BX_CPU_C::POP_RX },
+ /* 5E */ { 0, &BX_CPU_C::POP_RX },
+ /* 5F */ { 0, &BX_CPU_C::POP_RX },
+ /* 60 */ { 0, &BX_CPU_C::PUSHAD16 },
+ /* 61 */ { 0, &BX_CPU_C::POPAD16 },
+ /* 62 */ { BxAnother, &BX_CPU_C::BOUND_GvMa },
+ /* 63 */ { BxAnother, &BX_CPU_C::ARPL_EwGw },
+ /* 64 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // FS:
+ /* 65 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // GS:
+ /* 66 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // OS:
+ /* 67 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // AS:
+ /* 68 */ { BxImmediate_Iv, &BX_CPU_C::PUSH_Iw },
+ /* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GwEwIw },
+ /* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Iw },
+ /* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GwEwIw },
+ /* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
+ /* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YvDX },
+ /* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
+ /* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXv },
+ /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ew },
+ /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 83 */ { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ew },
+ /* 84 */ { BxAnother, &BX_CPU_C::TEST_EbGb },
+ /* 85 */ { BxAnother, &BX_CPU_C::TEST_EwGw },
+ /* 86 */ { BxAnother, &BX_CPU_C::XCHG_EbGb },
+ /* 87 */ { BxAnother, &BX_CPU_C::XCHG_EwGw },
+ /* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
+ /* 89 */ { BxAnother, &BX_CPU_C::MOV_EwGw },
+ /* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
+ /* 8B */ { BxAnother, &BX_CPU_C::MOV_GwEw },
+ /* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
+ /* 8D */ { BxAnother, &BX_CPU_C::LEA_GwM },
+ /* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
+ /* 8F */ { BxAnother, &BX_CPU_C::POP_Ew },
+ /* 90 */ { 0, &BX_CPU_C::NOP },
+ /* 91 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 92 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 93 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 94 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 95 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 96 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 97 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 98 */ { 0, &BX_CPU_C::CBW },
+ /* 99 */ { 0, &BX_CPU_C::CWD },
+ /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL16_Ap },
+ /* 9B */ { 0, &BX_CPU_C::FWAIT },
+ /* 9C */ { 0, &BX_CPU_C::PUSHF_Fv },
+ /* 9D */ { 0, &BX_CPU_C::POPF_Fv },
+ /* 9E */ { 0, &BX_CPU_C::SAHF },
+ /* 9F */ { 0, &BX_CPU_C::LAHF },
+ /* A0 */ { BxImmediate_O, &BX_CPU_C::MOV_ALOb },
+ /* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_AXOw },
+ /* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
+ /* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OwAX },
+ /* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
+ /* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XvYv },
+ /* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
+ /* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XvYv },
+ /* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
+ /* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_AXIw },
+ /* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
+ /* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YveAX },
+ /* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
+ /* AD */ { BxRepeatable, &BX_CPU_C::LODSW_eAXXv },
+ /* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
+ /* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_eAXXv },
+ /* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B3 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B4 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B5 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B6 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B7 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B8 */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* B9 */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BA */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BB */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BC */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BD */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BE */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+ /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ew },
+ /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear16_Iw },
+ /* C3 */ { 0, &BX_CPU_C::RETnear16 },
+ /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp },
+ /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp },
+ /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb },
+ /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EwIw },
+ /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb },
+ /* C9 */ { 0, &BX_CPU_C::LEAVE },
+ /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar16_Iw },
+ /* CB */ { 0, &BX_CPU_C::RETfar16 },
+ /* CC */ { 0, &sid_cpu_c::INT3 },
+ /* CD */ { BxImmediate_Ib, &sid_cpu_c::INT_Ib },
+ /* CE */ { 0, &BX_CPU_C::INTO },
+ /* CF */ { 0, &BX_CPU_C::IRET16 },
+ /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ew },
+ /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D3 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ew },
+ /* D4 */ { BxImmediate_Ib, &BX_CPU_C::AAM },
+ /* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
+ /* D6 */ { 0, &BX_CPU_C::SALC },
+ /* D7 */ { 0, &BX_CPU_C::XLAT },
+ /* D8 */ { BxAnother, &BX_CPU_C::ESC0 },
+ /* D9 */ { BxAnother, &BX_CPU_C::ESC1 },
+ /* DA */ { BxAnother, &BX_CPU_C::ESC2 },
+ /* DB */ { BxAnother, &BX_CPU_C::ESC3 },
+ /* DC */ { BxAnother, &BX_CPU_C::ESC4 },
+ /* DD */ { BxAnother, &BX_CPU_C::ESC5 },
+ /* DE */ { BxAnother, &BX_CPU_C::ESC6 },
+ /* DF */ { BxAnother, &BX_CPU_C::ESC7 },
+ /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
+ /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
+ /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
+ /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb },
+ /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb },
+ /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_eAXIb },
+ /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL },
+ /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbeAX },
+ /* E8 */ { BxImmediate_BrOff16, &BX_CPU_C::CALL_Aw },
+ /* E9 */ { BxImmediate_BrOff16, &BX_CPU_C::JMP_Jw },
+ /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap },
+ /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jw },
+ /* EC */ { 0, &BX_CPU_C::IN_ALDX },
+ /* ED */ { 0, &BX_CPU_C::IN_eAXDX },
+ /* EE */ { 0, &BX_CPU_C::OUT_DXAL },
+ /* EF */ { 0, &BX_CPU_C::OUT_DXeAX },
+ /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK
+ /* F1 */ { 0, &BX_CPU_C::INT1 },
+ /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ
+ /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP, REPE/REPZ
+ /* F4 */ { 0, &BX_CPU_C::HLT },
+ /* F5 */ { 0, &BX_CPU_C::CMC },
+ /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb },
+ /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ew },
+ /* F8 */ { 0, &BX_CPU_C::CLC },
+ /* F9 */ { 0, &BX_CPU_C::STC },
+ /* FA */ { 0, &BX_CPU_C::CLI },
+ /* FB */ { 0, &BX_CPU_C::STI },
+ /* FC */ { 0, &BX_CPU_C::CLD },
+ /* FD */ { 0, &BX_CPU_C::STD },
+ /* FE */ { BxAnother | BxGroup4, NULL, BxOpcodeInfoG4 },
+ /* FF */ { BxAnother | BxGroup5, NULL, BxOpcodeInfoG5w },
+
+ /* 0F 00 */ { BxAnother | BxGroup6, NULL, BxOpcodeInfoG6 },
+ /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
+ /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw },
+ /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw },
+ /* 0F 04 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 05 */ { 0, &BX_CPU_C::LOADALL },
+ /* 0F 06 */ { 0, &BX_CPU_C::CLTS },
+ /* 0F 07 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 08 */ { 0, &BX_CPU_C::INVD },
+ /* 0F 09 */ { 0, &BX_CPU_C::WBINVD },
+ /* 0F 0A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 10 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 11 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 12 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 13 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 14 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 15 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 16 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 17 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 18 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 19 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
+ /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
+ /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
+ /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd },
+ /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd },
+ /* 0F 25 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd },
+ /* 0F 27 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 28 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 29 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 30 */ { 0, &BX_CPU_C::WRMSR },
+ /* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
+ /* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
+ /* 0F 33 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 34 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 36 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 37 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 38 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 39 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 40 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 41 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 42 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 43 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 44 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 45 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 46 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 47 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 48 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 49 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4A */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4B */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4C */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4D */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4E */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4F */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 50 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 51 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 52 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 53 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 54 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 55 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 56 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 57 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 58 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 59 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 60 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 61 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 62 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 63 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 64 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 65 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 66 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 67 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 68 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 69 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 70 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 71 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 72 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 73 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 74 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 75 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 76 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 77 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 78 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 79 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 80 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 81 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 82 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 83 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 84 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 85 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 86 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 87 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 88 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 89 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8A */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8B */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8C */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8D */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8E */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8F */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb },
+ /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb },
+ /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb },
+ /* 0F 93 */ { BxAnother, &BX_CPU_C::SETNB_Eb },
+ /* 0F 94 */ { BxAnother, &BX_CPU_C::SETZ_Eb },
+ /* 0F 95 */ { BxAnother, &BX_CPU_C::SETNZ_Eb },
+ /* 0F 96 */ { BxAnother, &BX_CPU_C::SETBE_Eb },
+ /* 0F 97 */ { BxAnother, &BX_CPU_C::SETNBE_Eb },
+ /* 0F 98 */ { BxAnother, &BX_CPU_C::SETS_Eb },
+ /* 0F 99 */ { BxAnother, &BX_CPU_C::SETNS_Eb },
+ /* 0F 9A */ { BxAnother, &BX_CPU_C::SETP_Eb },
+ /* 0F 9B */ { BxAnother, &BX_CPU_C::SETNP_Eb },
+ /* 0F 9C */ { BxAnother, &BX_CPU_C::SETL_Eb },
+ /* 0F 9D */ { BxAnother, &BX_CPU_C::SETNL_Eb },
+ /* 0F 9E */ { BxAnother, &BX_CPU_C::SETLE_Eb },
+ /* 0F 9F */ { BxAnother, &BX_CPU_C::SETNLE_Eb },
+ /* 0F A0 */ { 0, &BX_CPU_C::PUSH_FS },
+ /* 0F A1 */ { 0, &BX_CPU_C::POP_FS },
+ /* 0F A2 */ { 0, &BX_CPU_C::CPUID },
+ /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EvGv },
+ /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EwGw },
+ /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EwGw },
+ /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS },
+ /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS },
+ /* 0F A8 */ { 0, &BX_CPU_C::PUSH_GS },
+ /* 0F A9 */ { 0, &BX_CPU_C::POP_GS },
+ /* 0F AA */ { 0, &BX_CPU_C::RSM },
+ /* 0F AB */ { BxAnother, &BX_CPU_C::BTS_EvGv },
+ /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EwGw },
+ /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EwGw },
+ /* 0F AE */ { 0, &BX_CPU_C::BxError },
+ /* 0F AF */ { BxAnother, &BX_CPU_C::IMUL_GwEw },
+ /* 0F B0 */ { BxAnother, &BX_CPU_C::CMPXCHG_EbGb },
+ /* 0F B1 */ { BxAnother, &BX_CPU_C::CMPXCHG_EwGw },
+ /* 0F B2 */ { BxAnother, &BX_CPU_C::LSS_GvMp },
+ /* 0F B3 */ { BxAnother, &BX_CPU_C::BTR_EvGv },
+ /* 0F B4 */ { BxAnother, &BX_CPU_C::LFS_GvMp },
+ /* 0F B5 */ { BxAnother, &BX_CPU_C::LGS_GvMp },
+ /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GwEb },
+ /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GwEw },
+ /* 0F B8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F B9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+ /* 0F BB */ { BxAnother, &BX_CPU_C::BTC_EvGv },
+ /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GvEv },
+ /* 0F BD */ { BxAnother, &BX_CPU_C::BSR_GvEv },
+ /* 0F BE */ { BxAnother, &BX_CPU_C::MOVSX_GwEb },
+ /* 0F BF */ { BxAnother, &BX_CPU_C::MOVSX_GwEw },
+ /* 0F C0 */ { BxAnother, &BX_CPU_C::XADD_EbGb },
+ /* 0F C1 */ { BxAnother, &BX_CPU_C::XADD_EwGw },
+ /* 0F C2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C7 */ { BxAnother | BxGroup9, NULL, BxOpcodeInfoG9 },
+ /* 0F C8 */ { 0, &BX_CPU_C::BSWAP_EAX },
+ /* 0F C9 */ { 0, &BX_CPU_C::BSWAP_ECX },
+ /* 0F CA */ { 0, &BX_CPU_C::BSWAP_EDX },
+ /* 0F CB */ { 0, &BX_CPU_C::BSWAP_EBX },
+ /* 0F CC */ { 0, &BX_CPU_C::BSWAP_ESP },
+ /* 0F CD */ { 0, &BX_CPU_C::BSWAP_EBP },
+ /* 0F CE */ { 0, &BX_CPU_C::BSWAP_ESI },
+ /* 0F CF */ { 0, &BX_CPU_C::BSWAP_EDI },
+ /* 0F D0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F DA */ { 0, &BX_CPU_C::BxError },
+ /* 0F DB */ { 0, &BX_CPU_C::BxError },
+ /* 0F DC */ { 0, &BX_CPU_C::BxError },
+ /* 0F DD */ { 0, &BX_CPU_C::BxError },
+ /* 0F DE */ { 0, &BX_CPU_C::BxError },
+ /* 0F DF */ { 0, &BX_CPU_C::BxError },
+ /* 0F E0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F EA */ { 0, &BX_CPU_C::BxError },
+ /* 0F EB */ { 0, &BX_CPU_C::BxError },
+ /* 0F EC */ { 0, &BX_CPU_C::BxError },
+ /* 0F ED */ { 0, &BX_CPU_C::BxError },
+ /* 0F EE */ { 0, &BX_CPU_C::BxError },
+ /* 0F EF */ { 0, &BX_CPU_C::BxError },
+ /* 0F F0 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F1 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F2 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F3 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F4 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F5 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F6 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F7 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F8 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F9 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FA */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FB */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FC */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FD */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FE */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FF */ { 0, &BX_CPU_C::UndefinedOpcode },
+
+ // 512 entries for 32bit mod
+ /* 00 */ { BxAnother, &BX_CPU_C::ADD_EbGb },
+ /* 01 */ { BxAnother, &BX_CPU_C::ADD_EdGd },
+ /* 02 */ { BxAnother, &BX_CPU_C::ADD_GbEb },
+ /* 03 */ { BxAnother, &BX_CPU_C::ADD_GdEd },
+ /* 04 */ { BxImmediate_Ib, &BX_CPU_C::ADD_ALIb },
+ /* 05 */ { BxImmediate_Iv, &BX_CPU_C::ADD_EAXId },
+ /* 06 */ { 0, &BX_CPU_C::PUSH_ES },
+ /* 07 */ { 0, &BX_CPU_C::POP_ES },
+ /* 08 */ { BxAnother, &BX_CPU_C::OR_EbGb },
+ /* 09 */ { BxAnother, &BX_CPU_C::OR_EdGd },
+ /* 0A */ { BxAnother, &BX_CPU_C::OR_GbEb },
+ /* 0B */ { BxAnother, &BX_CPU_C::OR_GdEd },
+ /* 0C */ { BxImmediate_Ib, &BX_CPU_C::OR_ALIb },
+ /* 0D */ { BxImmediate_Iv, &BX_CPU_C::OR_EAXId },
+ /* 0E */ { 0, &BX_CPU_C::PUSH_CS },
+ /* 0F */ { BxAnother, &BX_CPU_C::BxError }, // 2-byte escape
+ /* 10 */ { BxAnother, &BX_CPU_C::ADC_EbGb },
+ /* 11 */ { BxAnother, &BX_CPU_C::ADC_EdGd },
+ /* 12 */ { BxAnother, &BX_CPU_C::ADC_GbEb },
+ /* 13 */ { BxAnother, &BX_CPU_C::ADC_GdEd },
+ /* 14 */ { BxImmediate_Ib, &BX_CPU_C::ADC_ALIb },
+ /* 15 */ { BxImmediate_Iv, &BX_CPU_C::ADC_EAXId },
+ /* 16 */ { 0, &BX_CPU_C::PUSH_SS },
+ /* 17 */ { 0, &BX_CPU_C::POP_SS },
+ /* 18 */ { BxAnother, &BX_CPU_C::SBB_EbGb },
+ /* 19 */ { BxAnother, &BX_CPU_C::SBB_EdGd },
+ /* 1A */ { BxAnother, &BX_CPU_C::SBB_GbEb },
+ /* 1B */ { BxAnother, &BX_CPU_C::SBB_GdEd },
+ /* 1C */ { BxImmediate_Ib, &BX_CPU_C::SBB_ALIb },
+ /* 1D */ { BxImmediate_Iv, &BX_CPU_C::SBB_EAXId },
+ /* 1E */ { 0, &BX_CPU_C::PUSH_DS },
+ /* 1F */ { 0, &BX_CPU_C::POP_DS },
+ /* 20 */ { BxAnother, &BX_CPU_C::AND_EbGb },
+ /* 21 */ { BxAnother, &BX_CPU_C::AND_EdGd },
+ /* 22 */ { BxAnother, &BX_CPU_C::AND_GbEb },
+ /* 23 */ { BxAnother, &BX_CPU_C::AND_GdEd },
+ /* 24 */ { BxImmediate_Ib, &BX_CPU_C::AND_ALIb },
+ /* 25 */ { BxImmediate_Iv, &BX_CPU_C::AND_EAXId },
+ /* 26 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // ES:
+ /* 27 */ { 0, &BX_CPU_C::DAA },
+ /* 28 */ { BxAnother, &BX_CPU_C::SUB_EbGb },
+ /* 29 */ { BxAnother, &BX_CPU_C::SUB_EdGd },
+ /* 2A */ { BxAnother, &BX_CPU_C::SUB_GbEb },
+ /* 2B */ { BxAnother, &BX_CPU_C::SUB_GdEd },
+ /* 2C */ { BxImmediate_Ib, &BX_CPU_C::SUB_ALIb },
+ /* 2D */ { BxImmediate_Iv, &BX_CPU_C::SUB_EAXId },
+ /* 2E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // CS:
+ /* 2F */ { 0, &BX_CPU_C::DAS },
+ /* 30 */ { BxAnother, &BX_CPU_C::XOR_EbGb },
+ /* 31 */ { BxAnother, &BX_CPU_C::XOR_EdGd },
+ /* 32 */ { BxAnother, &BX_CPU_C::XOR_GbEb },
+ /* 33 */ { BxAnother, &BX_CPU_C::XOR_GdEd },
+ /* 34 */ { BxImmediate_Ib, &BX_CPU_C::XOR_ALIb },
+ /* 35 */ { BxImmediate_Iv, &BX_CPU_C::XOR_EAXId },
+ /* 36 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // SS:
+ /* 37 */ { 0, &BX_CPU_C::AAA },
+ /* 38 */ { BxAnother, &BX_CPU_C::CMP_EbGb },
+ /* 39 */ { BxAnother, &BX_CPU_C::CMP_EdGd },
+ /* 3A */ { BxAnother, &BX_CPU_C::CMP_GbEb },
+ /* 3B */ { BxAnother, &BX_CPU_C::CMP_GdEd },
+ /* 3C */ { BxImmediate_Ib, &BX_CPU_C::CMP_ALIb },
+ /* 3D */ { BxImmediate_Iv, &BX_CPU_C::CMP_EAXId },
+ /* 3E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // DS:
+ /* 3F */ { 0, &BX_CPU_C::AAS },
+ /* 40 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 41 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 42 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 43 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 44 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 45 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 46 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 47 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 48 */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 49 */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4A */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4B */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4C */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4D */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4E */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4F */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 50 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 51 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 52 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 53 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 54 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 55 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 56 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 57 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 58 */ { 0, &BX_CPU_C::POP_ERX },
+ /* 59 */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5A */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5B */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5C */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5D */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5E */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5F */ { 0, &BX_CPU_C::POP_ERX },
+ /* 60 */ { 0, &BX_CPU_C::PUSHAD32 },
+ /* 61 */ { 0, &BX_CPU_C::POPAD32 },
+ /* 62 */ { BxAnother, &BX_CPU_C::BOUND_GvMa },
+ /* 63 */ { BxAnother, &BX_CPU_C::ARPL_EwGw },
+ /* 64 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // FS:
+ /* 65 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // GS:
+ /* 66 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // OS:
+ /* 67 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // AS:
+ /* 68 */ { BxImmediate_Iv, &BX_CPU_C::PUSH_Id },
+ /* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GdEdId },
+ /* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Id },
+ /* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GdEdId },
+ /* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
+ /* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YvDX },
+ /* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
+ /* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXv },
+ /* 70 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 71 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 72 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 73 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 74 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 75 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 76 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 77 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 78 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 79 */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7A */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7B */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7C */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7D */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7E */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 7F */ { BxImmediate_BrOff8, &sid_cpu_c::JCC_Jd },
+ /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ed },
+ /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 83 */ { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ed },
+ /* 84 */ { BxAnother, &BX_CPU_C::TEST_EbGb },
+ /* 85 */ { BxAnother, &BX_CPU_C::TEST_EdGd },
+ /* 86 */ { BxAnother, &BX_CPU_C::XCHG_EbGb },
+ /* 87 */ { BxAnother, &BX_CPU_C::XCHG_EdGd },
+ /* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
+ /* 89 */ { BxAnother, &BX_CPU_C::MOV_EdGd },
+ /* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
+ /* 8B */ { BxAnother, &BX_CPU_C::MOV_GdEd },
+ /* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
+ /* 8D */ { BxAnother, &BX_CPU_C::LEA_GdM },
+ /* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
+ /* 8F */ { BxAnother, &BX_CPU_C::POP_Ed },
+ /* 90 */ { 0, &BX_CPU_C::NOP },
+ /* 91 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 92 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 93 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 94 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 95 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 96 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 97 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 98 */ { 0, &BX_CPU_C::CWDE },
+ /* 99 */ { 0, &BX_CPU_C::CDQ },
+ /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL32_Ap },
+ /* 9B */ { 0, &BX_CPU_C::FWAIT },
+ /* 9C */ { 0, &BX_CPU_C::PUSHF_Fv },
+ /* 9D */ { 0, &BX_CPU_C::POPF_Fv },
+ /* 9E */ { 0, &BX_CPU_C::SAHF },
+ /* 9F */ { 0, &BX_CPU_C::LAHF },
+ /* A0 */ { BxImmediate_O, &BX_CPU_C::MOV_ALOb },
+ /* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_EAXOd },
+ /* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
+ /* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OdEAX },
+ /* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
+ /* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XvYv },
+ /* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
+ /* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XvYv },
+ /* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
+ /* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EAXId },
+ /* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
+ /* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YveAX },
+ /* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
+ /* AD */ { BxRepeatable, &BX_CPU_C::LODSW_eAXXv },
+ /* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
+ /* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_eAXXv },
+ /* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B3 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B4 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B5 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B6 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B7 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B8 */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* B9 */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BA */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BB */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BC */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BD */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BE */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+ /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ed },
+ /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear32_Iw },
+ /* C3 */ { 0, &BX_CPU_C::RETnear32 },
+ /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp },
+ /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp },
+ /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb },
+ /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EdId },
+ /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb },
+ /* C9 */ { 0, &BX_CPU_C::LEAVE },
+ /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar32_Iw },
+ /* CB */ { 0, &BX_CPU_C::RETfar32 },
+ /* CC */ { 0, &sid_cpu_c::INT3 },
+ /* CD */ { BxImmediate_Ib, &sid_cpu_c::INT_Ib },
+ /* CE */ { 0, &BX_CPU_C::INTO },
+ /* CF */ { 0, &BX_CPU_C::IRET32 },
+ /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ed },
+ /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D3 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ed },
+ /* D4 */ { BxImmediate_Ib, &BX_CPU_C::AAM },
+ /* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
+ /* D6 */ { 0, &BX_CPU_C::SALC },
+ /* D7 */ { 0, &BX_CPU_C::XLAT },
+ /* D8 */ { BxAnother, &BX_CPU_C::ESC0 },
+ /* D9 */ { BxAnother, &BX_CPU_C::ESC1 },
+ /* DA */ { BxAnother, &BX_CPU_C::ESC2 },
+ /* DB */ { BxAnother, &BX_CPU_C::ESC3 },
+ /* DC */ { BxAnother, &BX_CPU_C::ESC4 },
+ /* DD */ { BxAnother, &BX_CPU_C::ESC5 },
+ /* DE */ { BxAnother, &BX_CPU_C::ESC6 },
+ /* DF */ { BxAnother, &BX_CPU_C::ESC7 },
+ /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
+ /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
+ /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
+ /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb },
+ /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb },
+ /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_eAXIb },
+ /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL },
+ /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbeAX },
+ /* E8 */ { BxImmediate_BrOff32, &BX_CPU_C::CALL_Ad },
+ /* E9 */ { BxImmediate_BrOff32, &BX_CPU_C::JMP_Jd },
+ /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap },
+ /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jd },
+ /* EC */ { 0, &BX_CPU_C::IN_ALDX },
+ /* ED */ { 0, &BX_CPU_C::IN_eAXDX },
+ /* EE */ { 0, &BX_CPU_C::OUT_DXAL },
+ /* EF */ { 0, &BX_CPU_C::OUT_DXeAX },
+ /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK:
+ /* F1 */ { 0, &BX_CPU_C::INT1 },
+ /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ
+ /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP,REPE/REPZ
+ /* F4 */ { 0, &BX_CPU_C::HLT },
+ /* F5 */ { 0, &BX_CPU_C::CMC },
+ /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb },
+ /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ed },
+ /* F8 */ { 0, &BX_CPU_C::CLC },
+ /* F9 */ { 0, &BX_CPU_C::STC },
+ /* FA */ { 0, &BX_CPU_C::CLI },
+ /* FB */ { 0, &BX_CPU_C::STI },
+ /* FC */ { 0, &BX_CPU_C::CLD },
+ /* FD */ { 0, &BX_CPU_C::STD },
+ /* FE */ { BxAnother | BxGroup4, NULL, BxOpcodeInfoG4 },
+ /* FF */ { BxAnother | BxGroup5, NULL, BxOpcodeInfoG5d },
+
+ /* 0F 00 */ { BxAnother | BxGroup6, NULL, BxOpcodeInfoG6 },
+ /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
+ /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw },
+ /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw },
+ /* 0F 04 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 05 */ { 0, &BX_CPU_C::LOADALL },
+ /* 0F 06 */ { 0, &BX_CPU_C::CLTS },
+ /* 0F 07 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 08 */ { 0, &BX_CPU_C::INVD },
+ /* 0F 09 */ { 0, &BX_CPU_C::WBINVD },
+ /* 0F 0A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 10 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 11 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 12 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 13 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 14 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 15 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 16 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 17 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 18 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 19 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
+ /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
+ /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
+ /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd },
+ /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd },
+ /* 0F 25 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd },
+ /* 0F 27 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 28 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 29 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 30 */ { 0, &BX_CPU_C::WRMSR },
+ /* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
+ /* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
+ /* 0F 33 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 34 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 36 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 37 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 38 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 39 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 40 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 41 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 42 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 43 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 44 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 45 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 46 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 47 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 48 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 49 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4A */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4B */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4C */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4D */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4E */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4F */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 50 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 51 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 52 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 53 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 54 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 55 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 56 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 57 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 58 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 59 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 60 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 61 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 62 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 63 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 64 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 65 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 66 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 67 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 68 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 69 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 70 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 71 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 72 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 73 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 74 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 75 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 76 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 77 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 78 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 79 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 80 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 81 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 82 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 83 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 84 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 85 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 86 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 87 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 88 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 89 */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8A */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8B */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8C */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8D */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8E */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 8F */ { BxImmediate_BrOff32, &sid_cpu_c::JCC_Jd },
+ /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb },
+ /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb },
+ /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb },
+ /* 0F 93 */ { BxAnother, &BX_CPU_C::SETNB_Eb },
+ /* 0F 94 */ { BxAnother, &BX_CPU_C::SETZ_Eb },
+ /* 0F 95 */ { BxAnother, &BX_CPU_C::SETNZ_Eb },
+ /* 0F 96 */ { BxAnother, &BX_CPU_C::SETBE_Eb },
+ /* 0F 97 */ { BxAnother, &BX_CPU_C::SETNBE_Eb },
+ /* 0F 98 */ { BxAnother, &BX_CPU_C::SETS_Eb },
+ /* 0F 99 */ { BxAnother, &BX_CPU_C::SETNS_Eb },
+ /* 0F 9A */ { BxAnother, &BX_CPU_C::SETP_Eb },
+ /* 0F 9B */ { BxAnother, &BX_CPU_C::SETNP_Eb },
+ /* 0F 9C */ { BxAnother, &BX_CPU_C::SETL_Eb },
+ /* 0F 9D */ { BxAnother, &BX_CPU_C::SETNL_Eb },
+ /* 0F 9E */ { BxAnother, &BX_CPU_C::SETLE_Eb },
+ /* 0F 9F */ { BxAnother, &BX_CPU_C::SETNLE_Eb },
+ /* 0F A0 */ { 0, &BX_CPU_C::PUSH_FS },
+ /* 0F A1 */ { 0, &BX_CPU_C::POP_FS },
+ /* 0F A2 */ { 0, &BX_CPU_C::CPUID },
+ /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EvGv },
+ /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EdGd },
+ /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EdGd },
+ /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS },
+ /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS },
+ /* 0F A8 */ { 0, &BX_CPU_C::PUSH_GS },
+ /* 0F A9 */ { 0, &BX_CPU_C::POP_GS },
+ /* 0F AA */ { 0, &BX_CPU_C::RSM },
+ /* 0F AB */ { BxAnother, &BX_CPU_C::BTS_EvGv },
+ /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EdGd },
+ /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EdGd },
+ /* 0F AE */ { 0, &BX_CPU_C::BxError },
+ /* 0F AF */ { BxAnother, &BX_CPU_C::IMUL_GdEd },
+ /* 0F B0 */ { BxAnother, &BX_CPU_C::CMPXCHG_EbGb },
+ /* 0F B1 */ { BxAnother, &BX_CPU_C::CMPXCHG_EdGd },
+ /* 0F B2 */ { BxAnother, &BX_CPU_C::LSS_GvMp },
+ /* 0F B3 */ { BxAnother, &BX_CPU_C::BTR_EvGv },
+ /* 0F B4 */ { BxAnother, &BX_CPU_C::LFS_GvMp },
+ /* 0F B5 */ { BxAnother, &BX_CPU_C::LGS_GvMp },
+ /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GdEb },
+ /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GdEw },
+ /* 0F B8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F B9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+ /* 0F BB */ { BxAnother, &BX_CPU_C::BTC_EvGv },
+ /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GvEv },
+ /* 0F BD */ { BxAnother, &BX_CPU_C::BSR_GvEv },
+ /* 0F BE */ { BxAnother, &BX_CPU_C::MOVSX_GdEb },
+ /* 0F BF */ { BxAnother, &BX_CPU_C::MOVSX_GdEw },
+ /* 0F C0 */ { BxAnother, &BX_CPU_C::XADD_EbGb },
+ /* 0F C1 */ { BxAnother, &BX_CPU_C::XADD_EdGd },
+ /* 0F C2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C7 */ { BxAnother | BxGroup9, NULL, BxOpcodeInfoG9 },
+ /* 0F C8 */ { 0, &BX_CPU_C::BSWAP_EAX },
+ /* 0F C9 */ { 0, &BX_CPU_C::BSWAP_ECX },
+ /* 0F CA */ { 0, &BX_CPU_C::BSWAP_EDX },
+ /* 0F CB */ { 0, &BX_CPU_C::BSWAP_EBX },
+ /* 0F CC */ { 0, &BX_CPU_C::BSWAP_ESP },
+ /* 0F CD */ { 0, &BX_CPU_C::BSWAP_EBP },
+ /* 0F CE */ { 0, &BX_CPU_C::BSWAP_ESI },
+ /* 0F CF */ { 0, &BX_CPU_C::BSWAP_EDI },
+ /* 0F D0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F DA */ { 0, &BX_CPU_C::BxError },
+ /* 0F DB */ { 0, &BX_CPU_C::BxError },
+ /* 0F DC */ { 0, &BX_CPU_C::BxError },
+ /* 0F DD */ { 0, &BX_CPU_C::BxError },
+ /* 0F DE */ { 0, &BX_CPU_C::BxError },
+ /* 0F DF */ { 0, &BX_CPU_C::BxError },
+ /* 0F E0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F EA */ { 0, &BX_CPU_C::BxError },
+ /* 0F EB */ { 0, &BX_CPU_C::BxError },
+ /* 0F EC */ { 0, &BX_CPU_C::BxError },
+ /* 0F ED */ { 0, &BX_CPU_C::BxError },
+ /* 0F EE */ { 0, &BX_CPU_C::BxError },
+ /* 0F EF */ { 0, &BX_CPU_C::BxError },
+ /* 0F F0 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F1 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F2 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F3 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F4 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F5 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F6 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F7 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F8 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F9 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FA */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FB */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FC */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FD */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FE */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FF */ { 0, &BX_CPU_C::UndefinedOpcode },
+ };
+
+
+
+
+ unsigned
+sid_cpu_c::FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+ unsigned remain, Boolean is_32)
+{
+ // remain must be at least 1
+
+ unsigned b1, b2, ilen=1, attr;
+ unsigned imm_mode, offset;
+
+ instruction->os_32 = instruction->as_32 = is_32;
+ instruction->ResolveModrm = NULL;
+ instruction->seg = BX_SEG_REG_NULL;
+ instruction->rep_used = 0;
+
+fetch_b1:
+ b1 = *iptr++;
+
+another_byte:
+ offset = instruction->os_32 << 9; // * 512
+ instruction->attr = attr = BxOpcodeInfo[b1+offset].Attr;
+
+ if (attr & BxAnother) {
+ if (attr & BxPrefix) {
+ switch (b1) {
+ case 0x66: // OpSize
+ instruction->os_32 = !is_32;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+
+ case 0x67: // AddrSize
+ instruction->as_32 = !is_32;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+
+ case 0xf2: // REPNE/REPNZ
+ case 0xf3: // REP/REPE/REPZ
+ instruction->rep_used = b1;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+ break;
+
+ case 0x2e: // CS:
+ instruction->seg = BX_SEG_REG_CS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x26: // ES:
+ instruction->seg = BX_SEG_REG_ES;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x36: // SS:
+ instruction->seg = BX_SEG_REG_SS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x3e: // DS:
+ instruction->seg = BX_SEG_REG_DS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x64: // FS:
+ instruction->seg = BX_SEG_REG_FS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x65: // GS:
+ instruction->seg = BX_SEG_REG_GS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0xf0: // LOCK:
+ ilen++; goto fetch_b1;
+ break;
+
+ default:
+BX_PANIC(("fetch_decode: prefix default = 0x%02x\n", b1));
+ }
+ }
+ // opcode requires another byte
+ if (ilen < remain) {
+ ilen++;
+ b2 = *iptr++;
+ if (b1 == 0x0f) {
+ // 2-byte prefix
+ b1 = 0x100 | b2;
+ goto another_byte;
+ }
+ }
+ else
+ return(0);
+
+ // Parse mod-nnn-rm and related bytes
+ unsigned rm;
+ instruction->modrm = b2;
+ rm =
+ instruction->rm = b2 & 0x07;
+ instruction->mod = b2 & 0xc0; // leave unshifted
+ instruction->nnn = (b2 >> 3) & 0x07;
+ if (instruction->mod == 0xc0) { // mod == 11b
+ goto modrm_done;
+ }
+ if (instruction->as_32) {
+ // 32-bit addressing modes; note that mod==11b handled above
+ if (rm != 4) { // no s-i-b byte
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
+#endif
+ if (instruction->mod == 0x00) { // mod == 00b
+ instruction->ResolveModrm = BxResolve32Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_SEG_REG_DS;
+ if (rm == 5) {
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr++) << 24;
+ instruction->rm_addr = imm32u;
+ ilen += 4;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = 0;
+#endif
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod==00b, rm!=4, rm!=5
+ goto modrm_done;
+ }
+ if (instruction->mod == 0x40) { // mod == 01b
+ instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+get_8bit_displ:
+ if (ilen < remain) {
+ // 8 sign extended to 32
+ instruction->displ32u = (Bit8s) *iptr++;
+ ilen++;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // (mod == 0x80) mod == 10b
+ instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+get_32bit_displ:
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr++) << 24;
+ instruction->displ32u = imm32u;
+ ilen += 4;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ else { // mod!=11b, rm==4, s-i-b byte follows
+ unsigned sib, base;
+ if (ilen < remain) {
+ sib = *iptr++;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ instruction->sib = sib;
+ base =
+ instruction->base = sib & 0x07; sib >>= 3;
+ instruction->index = sib & 0x07; sib >>= 3;
+ instruction->scale = sib;
+#if BX_DYNAMIC_TRANSLATION
+ if (instruction->index == 0x04) // 100b
+ instruction->DTMemRegsUsed = 0;
+ else
+ instruction->DTMemRegsUsed = 1<<instruction->index;
+#endif
+ if (instruction->mod == 0x00) { // mod==00b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod0Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod0_base32[base];
+ if (instruction->base == 0x05) {
+ goto get_32bit_displ;
+ }
+ // mod==00b, rm==4, base!=5
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed |= 1<<base;
+#endif
+ goto modrm_done;
+ }
+#if BX_DYNAMIC_TRANSLATION
+ // for remaining 32bit cases
+ instruction->DTMemRegsUsed |= 1<<base;
+#endif
+ if (instruction->mod == 0x40) { // mod==01b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+ goto get_8bit_displ;
+ }
+ // (instruction->mod == 0x80), mod==10b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+ goto get_32bit_displ;
+ }
+ }
+ else {
+ // 16-bit addressing modes, mod==11b handled above
+ if (instruction->mod == 0x40) { // mod == 01b
+ instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ if (ilen < remain) {
+ // 8 sign extended to 16
+ instruction->displ16u = (Bit8s) *iptr++;
+ ilen++;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ if (instruction->mod == 0x80) { // mod == 10b
+ instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ if ((ilen+1) < remain) {
+ Bit16u displ16u;
+ displ16u = *iptr++;
+ displ16u |= (*iptr++) << 8;
+ instruction->displ16u = displ16u;
+ ilen += 2;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod must be 00b at this point
+ instruction->ResolveModrm = BxResolve16Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod0[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+ if (rm == 0x06) {
+ if ((ilen+1) < remain) {
+ Bit16u displ16u;
+ displ16u = *iptr++;
+ displ16u |= (*iptr++) << 8;
+ instruction->rm_addr = displ16u;
+ ilen += 2;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod=00b rm!=6
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ }
+
+modrm_done:
+ if (attr & BxGroupN) {
+ BxOpcodeInfo_t *OpcodeInfoPtr;
+
+ OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
+ instruction->execute_sid = OpcodeInfoPtr[instruction->nnn].ExecutePtr;
+ // get additional attributes from group table
+ attr |= OpcodeInfoPtr[instruction->nnn].Attr;
+ instruction->attr = attr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = 0; // for now
+#endif
+ }
+ else {
+ instruction->execute_sid = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+ instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+ }
+ }
+ else {
+ // Opcode does not require a MODRM byte.
+ // Note that a 2-byte opcode (0F XX) will jump to before
+ // the if() above after fetching the 2nd byte, so this path is
+ // taken in all cases if a modrm byte is NOT required.
+ instruction->execute_sid = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+ instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+ }
+
+
+ imm_mode = attr & BxImmediate;
+
+ if (imm_mode) {
+ switch (imm_mode) {
+ case BxImmediate_Ib:
+ if (ilen < remain) {
+ instruction->Ib = *iptr;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_Ib_SE: // Sign extend to OS size
+ if (ilen < remain) {
+ Bit8s temp8s;
+ temp8s = *iptr;
+ if (instruction->os_32)
+ instruction->Id = (Bit32s) temp8s;
+ else
+ instruction->Iw = (Bit16s) temp8s;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_Iv: // same as BxImmediate_BrOff32
+ case BxImmediate_IvIw: // CALL_Ap
+ if (instruction->os_32) {
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr) << 24;
+ instruction->Id = imm32u;
+ ilen += 4;
+ }
+ else {
+ return(0);
+ }
+ }
+ else {
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ }
+ if (imm_mode != BxImmediate_IvIw)
+ break;
+ iptr++;
+ // Get Iw for BxImmediate_IvIw
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw2 = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_O:
+ if (instruction->as_32) {
+ // fetch 32bit address into Id
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr) << 24;
+ instruction->Id = imm32u;
+ ilen += 4;
+ }
+ else {
+ return(0);
+ }
+ }
+ else {
+ // fetch 16bit address into Id
+ if ((ilen+1) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr) << 8;
+ instruction->Id = imm32u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ }
+ break;
+ case BxImmediate_Iw:
+ case BxImmediate_IwIb:
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ if (imm_mode == BxImmediate_Iw) break;
+ iptr++;
+ if (ilen < remain) {
+ instruction->Ib2 = *iptr;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_BrOff8:
+ if (ilen < remain) {
+ Bit8s temp8s;
+ temp8s = *iptr;
+ instruction->Id = temp8s;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_BrOff16:
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Id = (Bit16s) imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ break;
+ default:
+BX_INFO(("b1 was %x\n", b1));
+ BX_PANIC(("fetchdecode: imm_mode = %u\n", imm_mode));
+ }
+ }
+
+ instruction->b1 = b1;
+ instruction->ilen = ilen;
+ //instruction->flags_in = 0; // for now
+ //instruction->flags_out = 0; // for now
+ return(1);
+}
+#if 0
+ void
+BX_CPU_C::BxError(BxInstruction_t *i)
+{
+ // extern void dump_core();
+ BX_INFO(("BxError: instruction with op1=0x%x\n", i->b1));
+ BX_INFO(("nnn was %u\n", i->nnn));
+
+ BX_INFO(("WARNING: Encountered an unknown instruction (signalling illegal instruction):\n"));
+ // dump_core();
+
+ BX_CPU_THIS_PTR UndefinedOpcode(i);
+}
+
+ void
+BX_CPU_C::BxResolveError(BxInstruction_t *i)
+{
+ BX_PANIC(("BxResolveError: instruction with op1=0x%x\n", i->b1));
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+///////////////////////////
+// prefix bytes
+// opcode bytes
+// modrm/sib
+// address displacement
+// immediate constant
+///////////////////////////
+
+
+
+// sign extended to osize:
+// 6a push ib
+// 6b imul gvevib
+// 70..7f jo..jnle
+// 83 G1 0..7 ADD..CMP Evib
+
+// is 6b imul_gvevib sign extended? don't think
+// I'm sign extending it properly in old decode/execute
+
+//check all the groups. Make sure to add duplicates rather
+// than error.
+
+// mark instructions as changing control transfer, then
+// don't always load from fetch_ptr, etc.
+
+// cant use immediate as another because of Group3 where
+// some have immediate and some don't, and those won't
+// be picked up by logic until indirection.
+
+// get attr and execute ptr at same time
+
+// maybe move 16bit only i's like MOV_EwSw, MOV_SwEw
+// to 32 bit modules.
+
+// use 0F as a prefix too?
+
+
+
+
+void BxResolveError(BxInstruction_t *);
+
+#if BX_DYNAMIC_TRANSLATION
+// For 16-bit address mode, this matrix describes the registers
+// used to formulate the offset, indexed by the RM field.
+// This info is needed by the dynamic translation code for dataflow.
+static unsigned BxMemRegsUsed16[8] = {
+ (1<<3) | (1<<6), // BX + SI
+ (1<<3) | (1<<7), // BX + DI
+ (1<<5) | (1<<6), // BP + SI
+ (1<<5) | (1<<7), // BP + DI
+ (1<<6), // SI
+ (1<<7), // DI
+ (1<<5), // BP
+ (1<<3) // BX
+ };
+#endif
+
+static BxExecutePtr_t BxResolve16Mod0[8] = {
+ &BX_CPU_C::Resolve16Mod0Rm0,
+ &BX_CPU_C::Resolve16Mod0Rm1,
+ &BX_CPU_C::Resolve16Mod0Rm2,
+ &BX_CPU_C::Resolve16Mod0Rm3,
+ &BX_CPU_C::Resolve16Mod0Rm4,
+ &BX_CPU_C::Resolve16Mod0Rm5,
+ NULL, // d16, no registers used
+ &BX_CPU_C::Resolve16Mod0Rm7
+ };
+
+static BxExecutePtr_t BxResolve16Mod1or2[8] = {
+ &BX_CPU_C::Resolve16Mod1or2Rm0,
+ &BX_CPU_C::Resolve16Mod1or2Rm1,
+ &BX_CPU_C::Resolve16Mod1or2Rm2,
+ &BX_CPU_C::Resolve16Mod1or2Rm3,
+ &BX_CPU_C::Resolve16Mod1or2Rm4,
+ &BX_CPU_C::Resolve16Mod1or2Rm5,
+ &BX_CPU_C::Resolve16Mod1or2Rm6,
+ &BX_CPU_C::Resolve16Mod1or2Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod0[8] = {
+ &BX_CPU_C::Resolve32Mod0Rm0,
+ &BX_CPU_C::Resolve32Mod0Rm1,
+ &BX_CPU_C::Resolve32Mod0Rm2,
+ &BX_CPU_C::Resolve32Mod0Rm3,
+ NULL, // escape to 2-byte
+ NULL, // d32, no registers used
+ &BX_CPU_C::Resolve32Mod0Rm6,
+ &BX_CPU_C::Resolve32Mod0Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod1or2[8] = {
+ &BX_CPU_C::Resolve32Mod1or2Rm0,
+ &BX_CPU_C::Resolve32Mod1or2Rm1,
+ &BX_CPU_C::Resolve32Mod1or2Rm2,
+ &BX_CPU_C::Resolve32Mod1or2Rm3,
+ NULL, // escape to 2-byte
+ &BX_CPU_C::Resolve32Mod1or2Rm5,
+ &BX_CPU_C::Resolve32Mod1or2Rm6,
+ &BX_CPU_C::Resolve32Mod1or2Rm7
+ };
+
+static BxExecutePtr_t BxResolve32Mod0Base[8] = {
+ &BX_CPU_C::Resolve32Mod0Base0,
+ &BX_CPU_C::Resolve32Mod0Base1,
+ &BX_CPU_C::Resolve32Mod0Base2,
+ &BX_CPU_C::Resolve32Mod0Base3,
+ &BX_CPU_C::Resolve32Mod0Base4,
+ &BX_CPU_C::Resolve32Mod0Base5,
+ &BX_CPU_C::Resolve32Mod0Base6,
+ &BX_CPU_C::Resolve32Mod0Base7,
+ };
+
+static BxExecutePtr_t BxResolve32Mod1or2Base[8] = {
+ &BX_CPU_C::Resolve32Mod1or2Base0,
+ &BX_CPU_C::Resolve32Mod1or2Base1,
+ &BX_CPU_C::Resolve32Mod1or2Base2,
+ &BX_CPU_C::Resolve32Mod1or2Base3,
+ &BX_CPU_C::Resolve32Mod1or2Base4,
+ &BX_CPU_C::Resolve32Mod1or2Base5,
+ &BX_CPU_C::Resolve32Mod1or2Base6,
+ &BX_CPU_C::Resolve32Mod1or2Base7,
+ };
+
+typedef struct BxOpcodeInfo_t {
+ Bit16u Attr;
+ BxExecutePtr_t ExecutePtr;
+ struct BxOpcodeInfo_t *AnotherArray;
+} BxOpcodeInfo_t;
+
+static BxOpcodeInfo_t BxOpcodeInfoG1EbIb[8] = {
+ /* 0 */ { BxImmediate_Ib, &BX_CPU_C::ADD_EbIb },
+ /* 1 */ { BxImmediate_Ib, &BX_CPU_C::OR_EbIb },
+ /* 2 */ { BxImmediate_Ib, &BX_CPU_C::ADC_EbIb },
+ /* 3 */ { BxImmediate_Ib, &BX_CPU_C::SBB_EbIb },
+ /* 4 */ { BxImmediate_Ib, &BX_CPU_C::AND_EbIb },
+ /* 5 */ { BxImmediate_Ib, &BX_CPU_C::SUB_EbIb },
+ /* 6 */ { BxImmediate_Ib, &BX_CPU_C::XOR_EbIb },
+ /* 7 */ { BxImmediate_Ib, &BX_CPU_C::CMP_EbIb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ew[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ADD_EwIw },
+ /* 1 */ { 0, &BX_CPU_C::OR_EwIw },
+ /* 2 */ { 0, &BX_CPU_C::ADC_EwIw },
+ /* 3 */ { 0, &BX_CPU_C::SBB_EwIw },
+ /* 4 */ { 0, &BX_CPU_C::AND_EwIw },
+ /* 5 */ { 0, &BX_CPU_C::SUB_EwIw },
+ /* 6 */ { 0, &BX_CPU_C::XOR_EwIw },
+ /* 7 */ { 0, &BX_CPU_C::CMP_EwIw }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG1Ed[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ADD_EdId },
+ /* 1 */ { 0, &BX_CPU_C::OR_EdId },
+ /* 2 */ { 0, &BX_CPU_C::ADC_EdId },
+ /* 3 */ { 0, &BX_CPU_C::SBB_EdId },
+ /* 4 */ { 0, &BX_CPU_C::AND_EdId },
+ /* 5 */ { 0, &BX_CPU_C::SUB_EdId },
+ /* 6 */ { 0, &BX_CPU_C::XOR_EdId },
+ /* 7 */ { 0, &BX_CPU_C::CMP_EdId }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Eb[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Eb },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Eb },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Eb },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Eb },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Eb },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Eb },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Eb },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Eb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ew[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Ew },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Ew },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Ew },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Ew },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Ew },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Ew },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Ew },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Ew }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG2Ed[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::ROL_Ed },
+ /* 1 */ { 0, &BX_CPU_C::ROR_Ed },
+ /* 2 */ { 0, &BX_CPU_C::RCL_Ed },
+ /* 3 */ { 0, &BX_CPU_C::RCR_Ed },
+ /* 4 */ { 0, &BX_CPU_C::SHL_Ed },
+ /* 5 */ { 0, &BX_CPU_C::SHR_Ed },
+ /* 6 */ { 0, &BX_CPU_C::SHL_Ed },
+ /* 7 */ { 0, &BX_CPU_C::SAR_Ed }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Eb[8] = {
+ /* 0 */ { BxImmediate_Ib, &BX_CPU_C::TEST_EbIb },
+ /* 1 */ { BxImmediate_Ib, &BX_CPU_C::TEST_EbIb },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Eb },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Eb },
+ /* 4 */ { 0, &BX_CPU_C::MUL_ALEb },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_ALEb },
+ /* 6 */ { 0, &BX_CPU_C::DIV_ALEb },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_ALEb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ew[8] = {
+ /* 0 */ { BxImmediate_Iw, &BX_CPU_C::TEST_EwIw },
+ /* 1 */ { BxImmediate_Iw, &BX_CPU_C::TEST_EwIw },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Ew },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Ew },
+ /* 4 */ { 0, &BX_CPU_C::MUL_AXEw },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_AXEw },
+ /* 6 */ { 0, &BX_CPU_C::DIV_AXEw },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_AXEw }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG3Ed[8] = {
+ /* 0 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EdId },
+ /* 1 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EdId },
+ /* 2 */ { 0, &BX_CPU_C::NOT_Ed },
+ /* 3 */ { 0, &BX_CPU_C::NEG_Ed },
+ /* 4 */ { 0, &BX_CPU_C::MUL_EAXEd },
+ /* 5 */ { 0, &BX_CPU_C::IMUL_EAXEd },
+ /* 6 */ { 0, &BX_CPU_C::DIV_EAXEd },
+ /* 7 */ { 0, &BX_CPU_C::IDIV_EAXEd }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG4[8] = {
+ /* 0 */ { 0, &BX_CPU_C::INC_Eb },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Eb },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { 0, &BX_CPU_C::BxError },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG5w[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::INC_Ew },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Ew },
+ /* 2 */ { 0, &BX_CPU_C::CALL_Ew },
+ /* 3 */ { 0, &BX_CPU_C::CALL16_Ep },
+ /* 4 */ { 0, &BX_CPU_C::JMP_Ew },
+ /* 5 */ { 0, &BX_CPU_C::JMP16_Ep },
+ /* 6 */ { 0, &BX_CPU_C::PUSH_Ew },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG5d[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::INC_Ed },
+ /* 1 */ { 0, &BX_CPU_C::DEC_Ed },
+ /* 2 */ { 0, &BX_CPU_C::CALL_Ed },
+ /* 3 */ { 0, &BX_CPU_C::CALL32_Ep },
+ /* 4 */ { 0, &BX_CPU_C::JMP_Ed },
+ /* 5 */ { 0, &BX_CPU_C::JMP32_Ep },
+ /* 6 */ { 0, &BX_CPU_C::PUSH_Ed },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG6[8] = {
+ // attributes defined in main area
+ /* 0 */ { 0, &BX_CPU_C::SLDT_Ew },
+ /* 1 */ { 0, &BX_CPU_C::STR_Ew },
+ /* 2 */ { 0, &BX_CPU_C::LLDT_Ew },
+ /* 3 */ { 0, &BX_CPU_C::LTR_Ew },
+ /* 4 */ { 0, &BX_CPU_C::VERR_Ew },
+ /* 5 */ { 0, &BX_CPU_C::VERW_Ew },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG7[8] = {
+ /* 0 */ { 0, &BX_CPU_C::SGDT_Ms },
+ /* 1 */ { 0, &BX_CPU_C::SIDT_Ms },
+ /* 2 */ { 0, &BX_CPU_C::LGDT_Ms },
+ /* 3 */ { 0, &BX_CPU_C::LIDT_Ms },
+ /* 4 */ { 0, &BX_CPU_C::SMSW_Ew },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::LMSW_Ew },
+ /* 7 */ { 0, &BX_CPU_C::INVLPG }
+ };
+
+
+static BxOpcodeInfo_t BxOpcodeInfoG8EvIb[8] = {
+ /* 0 */ { 0, &BX_CPU_C::BxError },
+ /* 1 */ { 0, &BX_CPU_C::BxError },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { BxImmediate_Ib, &BX_CPU_C::BT_EvIb },
+ /* 5 */ { BxImmediate_Ib, &BX_CPU_C::BTS_EvIb },
+ /* 6 */ { BxImmediate_Ib, &BX_CPU_C::BTR_EvIb },
+ /* 7 */ { BxImmediate_Ib, &BX_CPU_C::BTC_EvIb }
+ };
+
+static BxOpcodeInfo_t BxOpcodeInfoG9[8] = {
+ /* 0 */ { 0, &BX_CPU_C::BxError },
+ /* 1 */ { 0, &BX_CPU_C::CMPXCHG8B },
+ /* 2 */ { 0, &BX_CPU_C::BxError },
+ /* 3 */ { 0, &BX_CPU_C::BxError },
+ /* 4 */ { 0, &BX_CPU_C::BxError },
+ /* 5 */ { 0, &BX_CPU_C::BxError },
+ /* 6 */ { 0, &BX_CPU_C::BxError },
+ /* 7 */ { 0, &BX_CPU_C::BxError }
+ };
+
+
+// 512 entries for 16bit mode
+// 512 entries for 32bit mode
+
+static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
+ // 512 entries for 16bit mode
+ /* 00 */ { BxAnother, &BX_CPU_C::ADD_EbGb },
+ /* 01 */ { BxAnother, &BX_CPU_C::ADD_EwGw },
+ /* 02 */ { BxAnother, &BX_CPU_C::ADD_GbEb },
+ /* 03 */ { BxAnother, &BX_CPU_C::ADD_GwEw },
+ /* 04 */ { BxImmediate_Ib, &BX_CPU_C::ADD_ALIb },
+ /* 05 */ { BxImmediate_Iv, &BX_CPU_C::ADD_AXIw },
+ /* 06 */ { 0, &BX_CPU_C::PUSH_ES },
+ /* 07 */ { 0, &BX_CPU_C::POP_ES },
+ /* 08 */ { BxAnother, &BX_CPU_C::OR_EbGb },
+ /* 09 */ { BxAnother, &BX_CPU_C::OR_EwGw },
+ /* 0A */ { BxAnother, &BX_CPU_C::OR_GbEb },
+ /* 0B */ { BxAnother, &BX_CPU_C::OR_GwEw },
+ /* 0C */ { BxImmediate_Ib, &BX_CPU_C::OR_ALIb },
+ /* 0D */ { BxImmediate_Iv, &BX_CPU_C::OR_AXIw },
+ /* 0E */ { 0, &BX_CPU_C::PUSH_CS },
+ /* 0F */ { BxAnother, &BX_CPU_C::BxError }, // 2-byte escape
+ /* 10 */ { BxAnother, &BX_CPU_C::ADC_EbGb },
+ /* 11 */ { BxAnother, &BX_CPU_C::ADC_EwGw },
+ /* 12 */ { BxAnother, &BX_CPU_C::ADC_GbEb },
+ /* 13 */ { BxAnother, &BX_CPU_C::ADC_GwEw },
+ /* 14 */ { BxImmediate_Ib, &BX_CPU_C::ADC_ALIb },
+ /* 15 */ { BxImmediate_Iv, &BX_CPU_C::ADC_AXIw },
+ /* 16 */ { 0, &BX_CPU_C::PUSH_SS },
+ /* 17 */ { 0, &BX_CPU_C::POP_SS },
+ /* 18 */ { BxAnother, &BX_CPU_C::SBB_EbGb },
+ /* 19 */ { BxAnother, &BX_CPU_C::SBB_EwGw },
+ /* 1A */ { BxAnother, &BX_CPU_C::SBB_GbEb },
+ /* 1B */ { BxAnother, &BX_CPU_C::SBB_GwEw },
+ /* 1C */ { BxImmediate_Ib, &BX_CPU_C::SBB_ALIb },
+ /* 1D */ { BxImmediate_Iv, &BX_CPU_C::SBB_AXIw },
+ /* 1E */ { 0, &BX_CPU_C::PUSH_DS },
+ /* 1F */ { 0, &BX_CPU_C::POP_DS },
+ /* 20 */ { BxAnother, &BX_CPU_C::AND_EbGb },
+ /* 21 */ { BxAnother, &BX_CPU_C::AND_EwGw },
+ /* 22 */ { BxAnother, &BX_CPU_C::AND_GbEb },
+ /* 23 */ { BxAnother, &BX_CPU_C::AND_GwEw },
+ /* 24 */ { BxImmediate_Ib, &BX_CPU_C::AND_ALIb },
+ /* 25 */ { BxImmediate_Iv, &BX_CPU_C::AND_AXIw },
+ /* 26 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // ES:
+ /* 27 */ { 0, &BX_CPU_C::DAA },
+ /* 28 */ { BxAnother, &BX_CPU_C::SUB_EbGb },
+ /* 29 */ { BxAnother, &BX_CPU_C::SUB_EwGw },
+ /* 2A */ { BxAnother, &BX_CPU_C::SUB_GbEb },
+ /* 2B */ { BxAnother, &BX_CPU_C::SUB_GwEw },
+ /* 2C */ { BxImmediate_Ib, &BX_CPU_C::SUB_ALIb },
+ /* 2D */ { BxImmediate_Iv, &BX_CPU_C::SUB_AXIw },
+ /* 2E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // CS:
+ /* 2F */ { 0, &BX_CPU_C::DAS },
+ /* 30 */ { BxAnother, &BX_CPU_C::XOR_EbGb },
+ /* 31 */ { BxAnother, &BX_CPU_C::XOR_EwGw },
+ /* 32 */ { BxAnother, &BX_CPU_C::XOR_GbEb },
+ /* 33 */ { BxAnother, &BX_CPU_C::XOR_GwEw },
+ /* 34 */ { BxImmediate_Ib, &BX_CPU_C::XOR_ALIb },
+ /* 35 */ { BxImmediate_Iv, &BX_CPU_C::XOR_AXIw },
+ /* 36 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // SS:
+ /* 37 */ { 0, &BX_CPU_C::AAA },
+ /* 38 */ { BxAnother, &BX_CPU_C::CMP_EbGb },
+ /* 39 */ { BxAnother, &BX_CPU_C::CMP_EwGw },
+ /* 3A */ { BxAnother, &BX_CPU_C::CMP_GbEb },
+ /* 3B */ { BxAnother, &BX_CPU_C::CMP_GwEw },
+ /* 3C */ { BxImmediate_Ib, &BX_CPU_C::CMP_ALIb },
+ /* 3D */ { BxImmediate_Iv, &BX_CPU_C::CMP_AXIw },
+ /* 3E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // DS:
+ /* 3F */ { 0, &BX_CPU_C::AAS },
+ /* 40 */ { 0, &BX_CPU_C::INC_RX },
+ /* 41 */ { 0, &BX_CPU_C::INC_RX },
+ /* 42 */ { 0, &BX_CPU_C::INC_RX },
+ /* 43 */ { 0, &BX_CPU_C::INC_RX },
+ /* 44 */ { 0, &BX_CPU_C::INC_RX },
+ /* 45 */ { 0, &BX_CPU_C::INC_RX },
+ /* 46 */ { 0, &BX_CPU_C::INC_RX },
+ /* 47 */ { 0, &BX_CPU_C::INC_RX },
+ /* 48 */ { 0, &BX_CPU_C::DEC_RX },
+ /* 49 */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4A */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4B */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4C */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4D */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4E */ { 0, &BX_CPU_C::DEC_RX },
+ /* 4F */ { 0, &BX_CPU_C::DEC_RX },
+ /* 50 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 51 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 52 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 53 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 54 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 55 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 56 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 57 */ { 0, &BX_CPU_C::PUSH_RX },
+ /* 58 */ { 0, &BX_CPU_C::POP_RX },
+ /* 59 */ { 0, &BX_CPU_C::POP_RX },
+ /* 5A */ { 0, &BX_CPU_C::POP_RX },
+ /* 5B */ { 0, &BX_CPU_C::POP_RX },
+ /* 5C */ { 0, &BX_CPU_C::POP_RX },
+ /* 5D */ { 0, &BX_CPU_C::POP_RX },
+ /* 5E */ { 0, &BX_CPU_C::POP_RX },
+ /* 5F */ { 0, &BX_CPU_C::POP_RX },
+ /* 60 */ { 0, &BX_CPU_C::PUSHAD16 },
+ /* 61 */ { 0, &BX_CPU_C::POPAD16 },
+ /* 62 */ { BxAnother, &BX_CPU_C::BOUND_GvMa },
+ /* 63 */ { BxAnother, &BX_CPU_C::ARPL_EwGw },
+ /* 64 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // FS:
+ /* 65 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // GS:
+ /* 66 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // OS:
+ /* 67 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // AS:
+ /* 68 */ { BxImmediate_Iv, &BX_CPU_C::PUSH_Iw },
+ /* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GwEwIw },
+ /* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Iw },
+ /* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GwEwIw },
+ /* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
+ /* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YvDX },
+ /* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
+ /* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXv },
+ /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jw },
+ /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ew },
+ /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 83 */ { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ew },
+ /* 84 */ { BxAnother, &BX_CPU_C::TEST_EbGb },
+ /* 85 */ { BxAnother, &BX_CPU_C::TEST_EwGw },
+ /* 86 */ { BxAnother, &BX_CPU_C::XCHG_EbGb },
+ /* 87 */ { BxAnother, &BX_CPU_C::XCHG_EwGw },
+ /* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
+ /* 89 */ { BxAnother, &BX_CPU_C::MOV_EwGw },
+ /* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
+ /* 8B */ { BxAnother, &BX_CPU_C::MOV_GwEw },
+ /* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
+ /* 8D */ { BxAnother, &BX_CPU_C::LEA_GwM },
+ /* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
+ /* 8F */ { BxAnother, &BX_CPU_C::POP_Ew },
+ /* 90 */ { 0, &BX_CPU_C::NOP },
+ /* 91 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 92 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 93 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 94 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 95 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 96 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 97 */ { 0, &BX_CPU_C::XCHG_RXAX },
+ /* 98 */ { 0, &BX_CPU_C::CBW },
+ /* 99 */ { 0, &BX_CPU_C::CWD },
+ /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL16_Ap },
+ /* 9B */ { 0, &BX_CPU_C::FWAIT },
+ /* 9C */ { 0, &BX_CPU_C::PUSHF_Fv },
+ /* 9D */ { 0, &BX_CPU_C::POPF_Fv },
+ /* 9E */ { 0, &BX_CPU_C::SAHF },
+ /* 9F */ { 0, &BX_CPU_C::LAHF },
+ /* A0 */ { BxImmediate_O, &BX_CPU_C::MOV_ALOb },
+ /* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_AXOw },
+ /* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
+ /* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OwAX },
+ /* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
+ /* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XvYv },
+ /* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
+ /* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XvYv },
+ /* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
+ /* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_AXIw },
+ /* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
+ /* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YveAX },
+ /* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
+ /* AD */ { BxRepeatable, &BX_CPU_C::LODSW_eAXXv },
+ /* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
+ /* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_eAXXv },
+ /* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B3 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B4 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B5 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B6 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B7 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B8 */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* B9 */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BA */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BB */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BC */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BD */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BE */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_RXIw },
+ /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+ /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ew },
+ /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear16_Iw },
+ /* C3 */ { 0, &BX_CPU_C::RETnear16 },
+ /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp },
+ /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp },
+ /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb },
+ /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EwIw },
+ /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb },
+ /* C9 */ { 0, &BX_CPU_C::LEAVE },
+ /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar16_Iw },
+ /* CB */ { 0, &BX_CPU_C::RETfar16 },
+ /* CC */ { 0, &BX_CPU_C::INT3 },
+ /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib },
+ /* CE */ { 0, &BX_CPU_C::INTO },
+ /* CF */ { 0, &BX_CPU_C::IRET16 },
+ /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ew },
+ /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D3 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ew },
+ /* D4 */ { BxImmediate_Ib, &BX_CPU_C::AAM },
+ /* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
+ /* D6 */ { 0, &BX_CPU_C::SALC },
+ /* D7 */ { 0, &BX_CPU_C::XLAT },
+ /* D8 */ { BxAnother, &BX_CPU_C::ESC0 },
+ /* D9 */ { BxAnother, &BX_CPU_C::ESC1 },
+ /* DA */ { BxAnother, &BX_CPU_C::ESC2 },
+ /* DB */ { BxAnother, &BX_CPU_C::ESC3 },
+ /* DC */ { BxAnother, &BX_CPU_C::ESC4 },
+ /* DD */ { BxAnother, &BX_CPU_C::ESC5 },
+ /* DE */ { BxAnother, &BX_CPU_C::ESC6 },
+ /* DF */ { BxAnother, &BX_CPU_C::ESC7 },
+ /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
+ /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
+ /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
+ /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb },
+ /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb },
+ /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_eAXIb },
+ /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL },
+ /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbeAX },
+ /* E8 */ { BxImmediate_BrOff16, &BX_CPU_C::CALL_Aw },
+ /* E9 */ { BxImmediate_BrOff16, &BX_CPU_C::JMP_Jw },
+ /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap },
+ /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jw },
+ /* EC */ { 0, &BX_CPU_C::IN_ALDX },
+ /* ED */ { 0, &BX_CPU_C::IN_eAXDX },
+ /* EE */ { 0, &BX_CPU_C::OUT_DXAL },
+ /* EF */ { 0, &BX_CPU_C::OUT_DXeAX },
+ /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK
+ /* F1 */ { 0, &BX_CPU_C::INT1 },
+ /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ
+ /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP, REPE/REPZ
+ /* F4 */ { 0, &BX_CPU_C::HLT },
+ /* F5 */ { 0, &BX_CPU_C::CMC },
+ /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb },
+ /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ew },
+ /* F8 */ { 0, &BX_CPU_C::CLC },
+ /* F9 */ { 0, &BX_CPU_C::STC },
+ /* FA */ { 0, &BX_CPU_C::CLI },
+ /* FB */ { 0, &BX_CPU_C::STI },
+ /* FC */ { 0, &BX_CPU_C::CLD },
+ /* FD */ { 0, &BX_CPU_C::STD },
+ /* FE */ { BxAnother | BxGroup4, NULL, BxOpcodeInfoG4 },
+ /* FF */ { BxAnother | BxGroup5, NULL, BxOpcodeInfoG5w },
+
+ /* 0F 00 */ { BxAnother | BxGroup6, NULL, BxOpcodeInfoG6 },
+ /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
+ /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw },
+ /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw },
+ /* 0F 04 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 05 */ { 0, &BX_CPU_C::LOADALL },
+ /* 0F 06 */ { 0, &BX_CPU_C::CLTS },
+ /* 0F 07 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 08 */ { 0, &BX_CPU_C::INVD },
+ /* 0F 09 */ { 0, &BX_CPU_C::WBINVD },
+ /* 0F 0A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 10 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 11 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 12 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 13 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 14 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 15 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 16 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 17 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 18 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 19 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
+ /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
+ /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
+ /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd },
+ /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd },
+ /* 0F 25 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd },
+ /* 0F 27 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 28 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 29 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 30 */ { 0, &BX_CPU_C::WRMSR },
+ /* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
+ /* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
+ /* 0F 33 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 34 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 36 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 37 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 38 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 39 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 40 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 41 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 42 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 43 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 44 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 45 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 46 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 47 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 48 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 49 */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4A */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4B */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4C */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4D */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4E */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 4F */ { BxAnother, &BX_CPU_C::CMOV_GwEw },
+ /* 0F 50 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 51 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 52 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 53 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 54 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 55 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 56 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 57 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 58 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 59 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 60 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 61 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 62 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 63 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 64 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 65 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 66 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 67 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 68 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 69 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 70 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 71 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 72 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 73 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 74 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 75 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 76 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 77 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 78 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 79 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 80 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 81 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 82 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 83 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 84 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 85 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 86 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 87 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 88 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 89 */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8A */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8B */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8C */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8D */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8E */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 8F */ { BxImmediate_BrOff16, &BX_CPU_C::JCC_Jw },
+ /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb },
+ /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb },
+ /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb },
+ /* 0F 93 */ { BxAnother, &BX_CPU_C::SETNB_Eb },
+ /* 0F 94 */ { BxAnother, &BX_CPU_C::SETZ_Eb },
+ /* 0F 95 */ { BxAnother, &BX_CPU_C::SETNZ_Eb },
+ /* 0F 96 */ { BxAnother, &BX_CPU_C::SETBE_Eb },
+ /* 0F 97 */ { BxAnother, &BX_CPU_C::SETNBE_Eb },
+ /* 0F 98 */ { BxAnother, &BX_CPU_C::SETS_Eb },
+ /* 0F 99 */ { BxAnother, &BX_CPU_C::SETNS_Eb },
+ /* 0F 9A */ { BxAnother, &BX_CPU_C::SETP_Eb },
+ /* 0F 9B */ { BxAnother, &BX_CPU_C::SETNP_Eb },
+ /* 0F 9C */ { BxAnother, &BX_CPU_C::SETL_Eb },
+ /* 0F 9D */ { BxAnother, &BX_CPU_C::SETNL_Eb },
+ /* 0F 9E */ { BxAnother, &BX_CPU_C::SETLE_Eb },
+ /* 0F 9F */ { BxAnother, &BX_CPU_C::SETNLE_Eb },
+ /* 0F A0 */ { 0, &BX_CPU_C::PUSH_FS },
+ /* 0F A1 */ { 0, &BX_CPU_C::POP_FS },
+ /* 0F A2 */ { 0, &BX_CPU_C::CPUID },
+ /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EvGv },
+ /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EwGw },
+ /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EwGw },
+ /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS },
+ /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS },
+ /* 0F A8 */ { 0, &BX_CPU_C::PUSH_GS },
+ /* 0F A9 */ { 0, &BX_CPU_C::POP_GS },
+ /* 0F AA */ { 0, &BX_CPU_C::RSM },
+ /* 0F AB */ { BxAnother, &BX_CPU_C::BTS_EvGv },
+ /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EwGw },
+ /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EwGw },
+ /* 0F AE */ { 0, &BX_CPU_C::BxError },
+ /* 0F AF */ { BxAnother, &BX_CPU_C::IMUL_GwEw },
+ /* 0F B0 */ { BxAnother, &BX_CPU_C::CMPXCHG_EbGb },
+ /* 0F B1 */ { BxAnother, &BX_CPU_C::CMPXCHG_EwGw },
+ /* 0F B2 */ { BxAnother, &BX_CPU_C::LSS_GvMp },
+ /* 0F B3 */ { BxAnother, &BX_CPU_C::BTR_EvGv },
+ /* 0F B4 */ { BxAnother, &BX_CPU_C::LFS_GvMp },
+ /* 0F B5 */ { BxAnother, &BX_CPU_C::LGS_GvMp },
+ /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GwEb },
+ /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GwEw },
+ /* 0F B8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F B9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+ /* 0F BB */ { BxAnother, &BX_CPU_C::BTC_EvGv },
+ /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GvEv },
+ /* 0F BD */ { BxAnother, &BX_CPU_C::BSR_GvEv },
+ /* 0F BE */ { BxAnother, &BX_CPU_C::MOVSX_GwEb },
+ /* 0F BF */ { BxAnother, &BX_CPU_C::MOVSX_GwEw },
+ /* 0F C0 */ { BxAnother, &BX_CPU_C::XADD_EbGb },
+ /* 0F C1 */ { BxAnother, &BX_CPU_C::XADD_EwGw },
+ /* 0F C2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C7 */ { BxAnother | BxGroup9, NULL, BxOpcodeInfoG9 },
+ /* 0F C8 */ { 0, &BX_CPU_C::BSWAP_EAX },
+ /* 0F C9 */ { 0, &BX_CPU_C::BSWAP_ECX },
+ /* 0F CA */ { 0, &BX_CPU_C::BSWAP_EDX },
+ /* 0F CB */ { 0, &BX_CPU_C::BSWAP_EBX },
+ /* 0F CC */ { 0, &BX_CPU_C::BSWAP_ESP },
+ /* 0F CD */ { 0, &BX_CPU_C::BSWAP_EBP },
+ /* 0F CE */ { 0, &BX_CPU_C::BSWAP_ESI },
+ /* 0F CF */ { 0, &BX_CPU_C::BSWAP_EDI },
+ /* 0F D0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F DA */ { 0, &BX_CPU_C::BxError },
+ /* 0F DB */ { 0, &BX_CPU_C::BxError },
+ /* 0F DC */ { 0, &BX_CPU_C::BxError },
+ /* 0F DD */ { 0, &BX_CPU_C::BxError },
+ /* 0F DE */ { 0, &BX_CPU_C::BxError },
+ /* 0F DF */ { 0, &BX_CPU_C::BxError },
+ /* 0F E0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F EA */ { 0, &BX_CPU_C::BxError },
+ /* 0F EB */ { 0, &BX_CPU_C::BxError },
+ /* 0F EC */ { 0, &BX_CPU_C::BxError },
+ /* 0F ED */ { 0, &BX_CPU_C::BxError },
+ /* 0F EE */ { 0, &BX_CPU_C::BxError },
+ /* 0F EF */ { 0, &BX_CPU_C::BxError },
+ /* 0F F0 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F1 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F2 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F3 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F4 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F5 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F6 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F7 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F8 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F9 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FA */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FB */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FC */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FD */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FE */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FF */ { 0, &BX_CPU_C::UndefinedOpcode },
+
+ // 512 entries for 32bit mod
+ /* 00 */ { BxAnother, &BX_CPU_C::ADD_EbGb },
+ /* 01 */ { BxAnother, &BX_CPU_C::ADD_EdGd },
+ /* 02 */ { BxAnother, &BX_CPU_C::ADD_GbEb },
+ /* 03 */ { BxAnother, &BX_CPU_C::ADD_GdEd },
+ /* 04 */ { BxImmediate_Ib, &BX_CPU_C::ADD_ALIb },
+ /* 05 */ { BxImmediate_Iv, &BX_CPU_C::ADD_EAXId },
+ /* 06 */ { 0, &BX_CPU_C::PUSH_ES },
+ /* 07 */ { 0, &BX_CPU_C::POP_ES },
+ /* 08 */ { BxAnother, &BX_CPU_C::OR_EbGb },
+ /* 09 */ { BxAnother, &BX_CPU_C::OR_EdGd },
+ /* 0A */ { BxAnother, &BX_CPU_C::OR_GbEb },
+ /* 0B */ { BxAnother, &BX_CPU_C::OR_GdEd },
+ /* 0C */ { BxImmediate_Ib, &BX_CPU_C::OR_ALIb },
+ /* 0D */ { BxImmediate_Iv, &BX_CPU_C::OR_EAXId },
+ /* 0E */ { 0, &BX_CPU_C::PUSH_CS },
+ /* 0F */ { BxAnother, &BX_CPU_C::BxError }, // 2-byte escape
+ /* 10 */ { BxAnother, &BX_CPU_C::ADC_EbGb },
+ /* 11 */ { BxAnother, &BX_CPU_C::ADC_EdGd },
+ /* 12 */ { BxAnother, &BX_CPU_C::ADC_GbEb },
+ /* 13 */ { BxAnother, &BX_CPU_C::ADC_GdEd },
+ /* 14 */ { BxImmediate_Ib, &BX_CPU_C::ADC_ALIb },
+ /* 15 */ { BxImmediate_Iv, &BX_CPU_C::ADC_EAXId },
+ /* 16 */ { 0, &BX_CPU_C::PUSH_SS },
+ /* 17 */ { 0, &BX_CPU_C::POP_SS },
+ /* 18 */ { BxAnother, &BX_CPU_C::SBB_EbGb },
+ /* 19 */ { BxAnother, &BX_CPU_C::SBB_EdGd },
+ /* 1A */ { BxAnother, &BX_CPU_C::SBB_GbEb },
+ /* 1B */ { BxAnother, &BX_CPU_C::SBB_GdEd },
+ /* 1C */ { BxImmediate_Ib, &BX_CPU_C::SBB_ALIb },
+ /* 1D */ { BxImmediate_Iv, &BX_CPU_C::SBB_EAXId },
+ /* 1E */ { 0, &BX_CPU_C::PUSH_DS },
+ /* 1F */ { 0, &BX_CPU_C::POP_DS },
+ /* 20 */ { BxAnother, &BX_CPU_C::AND_EbGb },
+ /* 21 */ { BxAnother, &BX_CPU_C::AND_EdGd },
+ /* 22 */ { BxAnother, &BX_CPU_C::AND_GbEb },
+ /* 23 */ { BxAnother, &BX_CPU_C::AND_GdEd },
+ /* 24 */ { BxImmediate_Ib, &BX_CPU_C::AND_ALIb },
+ /* 25 */ { BxImmediate_Iv, &BX_CPU_C::AND_EAXId },
+ /* 26 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // ES:
+ /* 27 */ { 0, &BX_CPU_C::DAA },
+ /* 28 */ { BxAnother, &BX_CPU_C::SUB_EbGb },
+ /* 29 */ { BxAnother, &BX_CPU_C::SUB_EdGd },
+ /* 2A */ { BxAnother, &BX_CPU_C::SUB_GbEb },
+ /* 2B */ { BxAnother, &BX_CPU_C::SUB_GdEd },
+ /* 2C */ { BxImmediate_Ib, &BX_CPU_C::SUB_ALIb },
+ /* 2D */ { BxImmediate_Iv, &BX_CPU_C::SUB_EAXId },
+ /* 2E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // CS:
+ /* 2F */ { 0, &BX_CPU_C::DAS },
+ /* 30 */ { BxAnother, &BX_CPU_C::XOR_EbGb },
+ /* 31 */ { BxAnother, &BX_CPU_C::XOR_EdGd },
+ /* 32 */ { BxAnother, &BX_CPU_C::XOR_GbEb },
+ /* 33 */ { BxAnother, &BX_CPU_C::XOR_GdEd },
+ /* 34 */ { BxImmediate_Ib, &BX_CPU_C::XOR_ALIb },
+ /* 35 */ { BxImmediate_Iv, &BX_CPU_C::XOR_EAXId },
+ /* 36 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // SS:
+ /* 37 */ { 0, &BX_CPU_C::AAA },
+ /* 38 */ { BxAnother, &BX_CPU_C::CMP_EbGb },
+ /* 39 */ { BxAnother, &BX_CPU_C::CMP_EdGd },
+ /* 3A */ { BxAnother, &BX_CPU_C::CMP_GbEb },
+ /* 3B */ { BxAnother, &BX_CPU_C::CMP_GdEd },
+ /* 3C */ { BxImmediate_Ib, &BX_CPU_C::CMP_ALIb },
+ /* 3D */ { BxImmediate_Iv, &BX_CPU_C::CMP_EAXId },
+ /* 3E */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // DS:
+ /* 3F */ { 0, &BX_CPU_C::AAS },
+ /* 40 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 41 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 42 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 43 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 44 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 45 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 46 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 47 */ { 0, &BX_CPU_C::INC_ERX },
+ /* 48 */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 49 */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4A */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4B */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4C */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4D */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4E */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 4F */ { 0, &BX_CPU_C::DEC_ERX },
+ /* 50 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 51 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 52 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 53 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 54 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 55 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 56 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 57 */ { 0, &BX_CPU_C::PUSH_ERX },
+ /* 58 */ { 0, &BX_CPU_C::POP_ERX },
+ /* 59 */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5A */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5B */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5C */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5D */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5E */ { 0, &BX_CPU_C::POP_ERX },
+ /* 5F */ { 0, &BX_CPU_C::POP_ERX },
+ /* 60 */ { 0, &BX_CPU_C::PUSHAD32 },
+ /* 61 */ { 0, &BX_CPU_C::POPAD32 },
+ /* 62 */ { BxAnother, &BX_CPU_C::BOUND_GvMa },
+ /* 63 */ { BxAnother, &BX_CPU_C::ARPL_EwGw },
+ /* 64 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // FS:
+ /* 65 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // GS:
+ /* 66 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // OS:
+ /* 67 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // AS:
+ /* 68 */ { BxImmediate_Iv, &BX_CPU_C::PUSH_Id },
+ /* 69 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::IMUL_GdEdId },
+ /* 6A */ { BxImmediate_Ib_SE, &BX_CPU_C::PUSH_Id },
+ /* 6B */ { BxAnother | BxImmediate_Ib_SE, &BX_CPU_C::IMUL_GdEdId },
+ /* 6C */ { BxRepeatable, &BX_CPU_C::INSB_YbDX },
+ /* 6D */ { BxRepeatable, &BX_CPU_C::INSW_YvDX },
+ /* 6E */ { BxRepeatable, &BX_CPU_C::OUTSB_DXXb },
+ /* 6F */ { BxRepeatable, &BX_CPU_C::OUTSW_DXXv },
+ /* 70 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 71 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 72 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 73 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 74 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 75 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 76 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 77 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 78 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 79 */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7A */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7B */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7C */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7D */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7E */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 7F */ { BxImmediate_BrOff8, &BX_CPU_C::JCC_Jd },
+ /* 80 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 81 */ { BxAnother | BxGroup1 | BxImmediate_Iv, NULL, BxOpcodeInfoG1Ed },
+ /* 82 */ { BxAnother | BxGroup1, NULL, BxOpcodeInfoG1EbIb },
+ /* 83 */ { BxAnother | BxGroup1 | BxImmediate_Ib_SE, NULL, BxOpcodeInfoG1Ed },
+ /* 84 */ { BxAnother, &BX_CPU_C::TEST_EbGb },
+ /* 85 */ { BxAnother, &BX_CPU_C::TEST_EdGd },
+ /* 86 */ { BxAnother, &BX_CPU_C::XCHG_EbGb },
+ /* 87 */ { BxAnother, &BX_CPU_C::XCHG_EdGd },
+ /* 88 */ { BxAnother, &BX_CPU_C::MOV_EbGb },
+ /* 89 */ { BxAnother, &BX_CPU_C::MOV_EdGd },
+ /* 8A */ { BxAnother, &BX_CPU_C::MOV_GbEb },
+ /* 8B */ { BxAnother, &BX_CPU_C::MOV_GdEd },
+ /* 8C */ { BxAnother, &BX_CPU_C::MOV_EwSw },
+ /* 8D */ { BxAnother, &BX_CPU_C::LEA_GdM },
+ /* 8E */ { BxAnother, &BX_CPU_C::MOV_SwEw },
+ /* 8F */ { BxAnother, &BX_CPU_C::POP_Ed },
+ /* 90 */ { 0, &BX_CPU_C::NOP },
+ /* 91 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 92 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 93 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 94 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 95 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 96 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 97 */ { 0, &BX_CPU_C::XCHG_ERXEAX },
+ /* 98 */ { 0, &BX_CPU_C::CWDE },
+ /* 99 */ { 0, &BX_CPU_C::CDQ },
+ /* 9A */ { BxImmediate_IvIw, &BX_CPU_C::CALL32_Ap },
+ /* 9B */ { 0, &BX_CPU_C::FWAIT },
+ /* 9C */ { 0, &BX_CPU_C::PUSHF_Fv },
+ /* 9D */ { 0, &BX_CPU_C::POPF_Fv },
+ /* 9E */ { 0, &BX_CPU_C::SAHF },
+ /* 9F */ { 0, &BX_CPU_C::LAHF },
+ /* A0 */ { BxImmediate_O, &BX_CPU_C::MOV_ALOb },
+ /* A1 */ { BxImmediate_O, &BX_CPU_C::MOV_EAXOd },
+ /* A2 */ { BxImmediate_O, &BX_CPU_C::MOV_ObAL },
+ /* A3 */ { BxImmediate_O, &BX_CPU_C::MOV_OdEAX },
+ /* A4 */ { BxRepeatable, &BX_CPU_C::MOVSB_XbYb },
+ /* A5 */ { BxRepeatable, &BX_CPU_C::MOVSW_XvYv },
+ /* A6 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSB_XbYb },
+ /* A7 */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::CMPSW_XvYv },
+ /* A8 */ { BxImmediate_Ib, &BX_CPU_C::TEST_ALIb },
+ /* A9 */ { BxImmediate_Iv, &BX_CPU_C::TEST_EAXId },
+ /* AA */ { BxRepeatable, &BX_CPU_C::STOSB_YbAL },
+ /* AB */ { BxRepeatable, &BX_CPU_C::STOSW_YveAX },
+ /* AC */ { BxRepeatable, &BX_CPU_C::LODSB_ALXb },
+ /* AD */ { BxRepeatable, &BX_CPU_C::LODSW_eAXXv },
+ /* AE */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASB_ALXb },
+ /* AF */ { BxRepeatable | BxRepeatableZF, &BX_CPU_C::SCASW_eAXXv },
+ /* B0 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B1 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B2 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B3 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RLIb },
+ /* B4 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B5 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B6 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B7 */ { BxImmediate_Ib, &BX_CPU_C::MOV_RHIb },
+ /* B8 */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* B9 */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BA */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BB */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BC */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BD */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BE */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* BF */ { BxImmediate_Iv, &BX_CPU_C::MOV_ERXId },
+ /* C0 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Eb },
+ /* C1 */ { BxAnother | BxGroup2 | BxImmediate_Ib, NULL, BxOpcodeInfoG2Ed },
+ /* C2 */ { BxImmediate_Iw, &BX_CPU_C::RETnear32_Iw },
+ /* C3 */ { 0, &BX_CPU_C::RETnear32 },
+ /* C4 */ { BxAnother, &BX_CPU_C::LES_GvMp },
+ /* C5 */ { BxAnother, &BX_CPU_C::LDS_GvMp },
+ /* C6 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::MOV_EbIb },
+ /* C7 */ { BxAnother | BxImmediate_Iv, &BX_CPU_C::MOV_EdId },
+ /* C8 */ { BxImmediate_IwIb, &BX_CPU_C::ENTER_IwIb },
+ /* C9 */ { 0, &BX_CPU_C::LEAVE },
+ /* CA */ { BxImmediate_Iw, &BX_CPU_C::RETfar32_Iw },
+ /* CB */ { 0, &BX_CPU_C::RETfar32 },
+ /* CC */ { 0, &BX_CPU_C::INT3 },
+ /* CD */ { BxImmediate_Ib, &BX_CPU_C::INT_Ib },
+ /* CE */ { 0, &BX_CPU_C::INTO },
+ /* CF */ { 0, &BX_CPU_C::IRET32 },
+ /* D0 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D1 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ed },
+ /* D2 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Eb },
+ /* D3 */ { BxAnother | BxGroup2, NULL, BxOpcodeInfoG2Ed },
+ /* D4 */ { BxImmediate_Ib, &BX_CPU_C::AAM },
+ /* D5 */ { BxImmediate_Ib, &BX_CPU_C::AAD },
+ /* D6 */ { 0, &BX_CPU_C::SALC },
+ /* D7 */ { 0, &BX_CPU_C::XLAT },
+ /* D8 */ { BxAnother, &BX_CPU_C::ESC0 },
+ /* D9 */ { BxAnother, &BX_CPU_C::ESC1 },
+ /* DA */ { BxAnother, &BX_CPU_C::ESC2 },
+ /* DB */ { BxAnother, &BX_CPU_C::ESC3 },
+ /* DC */ { BxAnother, &BX_CPU_C::ESC4 },
+ /* DD */ { BxAnother, &BX_CPU_C::ESC5 },
+ /* DE */ { BxAnother, &BX_CPU_C::ESC6 },
+ /* DF */ { BxAnother, &BX_CPU_C::ESC7 },
+ /* E0 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPNE_Jb },
+ /* E1 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOPE_Jb },
+ /* E2 */ { BxImmediate_BrOff8, &BX_CPU_C::LOOP_Jb },
+ /* E3 */ { BxImmediate_BrOff8, &BX_CPU_C::JCXZ_Jb },
+ /* E4 */ { BxImmediate_Ib, &BX_CPU_C::IN_ALIb },
+ /* E5 */ { BxImmediate_Ib, &BX_CPU_C::IN_eAXIb },
+ /* E6 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbAL },
+ /* E7 */ { BxImmediate_Ib, &BX_CPU_C::OUT_IbeAX },
+ /* E8 */ { BxImmediate_BrOff32, &BX_CPU_C::CALL_Ad },
+ /* E9 */ { BxImmediate_BrOff32, &BX_CPU_C::JMP_Jd },
+ /* EA */ { BxImmediate_IvIw, &BX_CPU_C::JMP_Ap },
+ /* EB */ { BxImmediate_BrOff8, &BX_CPU_C::JMP_Jd },
+ /* EC */ { 0, &BX_CPU_C::IN_ALDX },
+ /* ED */ { 0, &BX_CPU_C::IN_eAXDX },
+ /* EE */ { 0, &BX_CPU_C::OUT_DXAL },
+ /* EF */ { 0, &BX_CPU_C::OUT_DXeAX },
+ /* F0 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // LOCK:
+ /* F1 */ { 0, &BX_CPU_C::INT1 },
+ /* F2 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REPNE/REPNZ
+ /* F3 */ { BxPrefix | BxAnother, &BX_CPU_C::BxError }, // REP,REPE/REPZ
+ /* F4 */ { 0, &BX_CPU_C::HLT },
+ /* F5 */ { 0, &BX_CPU_C::CMC },
+ /* F6 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Eb },
+ /* F7 */ { BxAnother | BxGroup3, NULL, BxOpcodeInfoG3Ed },
+ /* F8 */ { 0, &BX_CPU_C::CLC },
+ /* F9 */ { 0, &BX_CPU_C::STC },
+ /* FA */ { 0, &BX_CPU_C::CLI },
+ /* FB */ { 0, &BX_CPU_C::STI },
+ /* FC */ { 0, &BX_CPU_C::CLD },
+ /* FD */ { 0, &BX_CPU_C::STD },
+ /* FE */ { BxAnother | BxGroup4, NULL, BxOpcodeInfoG4 },
+ /* FF */ { BxAnother | BxGroup5, NULL, BxOpcodeInfoG5d },
+
+ /* 0F 00 */ { BxAnother | BxGroup6, NULL, BxOpcodeInfoG6 },
+ /* 0F 01 */ { BxAnother | BxGroup7, NULL, BxOpcodeInfoG7 },
+ /* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw },
+ /* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw },
+ /* 0F 04 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 05 */ { 0, &BX_CPU_C::LOADALL },
+ /* 0F 06 */ { 0, &BX_CPU_C::CLTS },
+ /* 0F 07 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 08 */ { 0, &BX_CPU_C::INVD },
+ /* 0F 09 */ { 0, &BX_CPU_C::WBINVD },
+ /* 0F 0A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 0F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 10 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 11 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 12 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 13 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 14 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 15 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 16 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 17 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 18 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 19 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 1F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 20 */ { BxAnother, &BX_CPU_C::MOV_RdCd },
+ /* 0F 21 */ { BxAnother, &BX_CPU_C::MOV_RdDd },
+ /* 0F 22 */ { BxAnother, &BX_CPU_C::MOV_CdRd },
+ /* 0F 23 */ { BxAnother, &BX_CPU_C::MOV_DdRd },
+ /* 0F 24 */ { BxAnother, &BX_CPU_C::MOV_RdTd },
+ /* 0F 25 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 26 */ { BxAnother, &BX_CPU_C::MOV_TdRd },
+ /* 0F 27 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 28 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 29 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 2F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 30 */ { 0, &BX_CPU_C::WRMSR },
+ /* 0F 31 */ { 0, &BX_CPU_C::RDTSC },
+ /* 0F 32 */ { 0, &BX_CPU_C::RDMSR },
+ /* 0F 33 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 34 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 35 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 36 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 37 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 38 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 39 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 3F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 40 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 41 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 42 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 43 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 44 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 45 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 46 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 47 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 48 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 49 */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4A */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4B */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4C */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4D */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4E */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 4F */ { BxAnother, &BX_CPU_C::CMOV_GdEd },
+ /* 0F 50 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 51 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 52 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 53 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 54 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 55 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 56 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 57 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 58 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 59 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 5F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 60 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 61 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 62 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 63 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 64 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 65 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 66 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 67 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 68 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 69 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 6F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 70 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 71 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 72 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 73 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 74 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 75 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 76 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 77 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 78 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 79 */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7A */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7B */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7C */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7D */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7E */ { 0, &BX_CPU_C::BxError },
+ /* 0F 7F */ { 0, &BX_CPU_C::BxError },
+ /* 0F 80 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 81 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 82 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 83 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 84 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 85 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 86 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 87 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 88 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 89 */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8A */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8B */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8C */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8D */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8E */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 8F */ { BxImmediate_BrOff32, &BX_CPU_C::JCC_Jd },
+ /* 0F 90 */ { BxAnother, &BX_CPU_C::SETO_Eb },
+ /* 0F 91 */ { BxAnother, &BX_CPU_C::SETNO_Eb },
+ /* 0F 92 */ { BxAnother, &BX_CPU_C::SETB_Eb },
+ /* 0F 93 */ { BxAnother, &BX_CPU_C::SETNB_Eb },
+ /* 0F 94 */ { BxAnother, &BX_CPU_C::SETZ_Eb },
+ /* 0F 95 */ { BxAnother, &BX_CPU_C::SETNZ_Eb },
+ /* 0F 96 */ { BxAnother, &BX_CPU_C::SETBE_Eb },
+ /* 0F 97 */ { BxAnother, &BX_CPU_C::SETNBE_Eb },
+ /* 0F 98 */ { BxAnother, &BX_CPU_C::SETS_Eb },
+ /* 0F 99 */ { BxAnother, &BX_CPU_C::SETNS_Eb },
+ /* 0F 9A */ { BxAnother, &BX_CPU_C::SETP_Eb },
+ /* 0F 9B */ { BxAnother, &BX_CPU_C::SETNP_Eb },
+ /* 0F 9C */ { BxAnother, &BX_CPU_C::SETL_Eb },
+ /* 0F 9D */ { BxAnother, &BX_CPU_C::SETNL_Eb },
+ /* 0F 9E */ { BxAnother, &BX_CPU_C::SETLE_Eb },
+ /* 0F 9F */ { BxAnother, &BX_CPU_C::SETNLE_Eb },
+ /* 0F A0 */ { 0, &BX_CPU_C::PUSH_FS },
+ /* 0F A1 */ { 0, &BX_CPU_C::POP_FS },
+ /* 0F A2 */ { 0, &BX_CPU_C::CPUID },
+ /* 0F A3 */ { BxAnother, &BX_CPU_C::BT_EvGv },
+ /* 0F A4 */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHLD_EdGd },
+ /* 0F A5 */ { BxAnother, &BX_CPU_C::SHLD_EdGd },
+ /* 0F A6 */ { 0, &BX_CPU_C::CMPXCHG_XBTS },
+ /* 0F A7 */ { 0, &BX_CPU_C::CMPXCHG_IBTS },
+ /* 0F A8 */ { 0, &BX_CPU_C::PUSH_GS },
+ /* 0F A9 */ { 0, &BX_CPU_C::POP_GS },
+ /* 0F AA */ { 0, &BX_CPU_C::RSM },
+ /* 0F AB */ { BxAnother, &BX_CPU_C::BTS_EvGv },
+ /* 0F AC */ { BxAnother | BxImmediate_Ib, &BX_CPU_C::SHRD_EdGd },
+ /* 0F AD */ { BxAnother, &BX_CPU_C::SHRD_EdGd },
+ /* 0F AE */ { 0, &BX_CPU_C::BxError },
+ /* 0F AF */ { BxAnother, &BX_CPU_C::IMUL_GdEd },
+ /* 0F B0 */ { BxAnother, &BX_CPU_C::CMPXCHG_EbGb },
+ /* 0F B1 */ { BxAnother, &BX_CPU_C::CMPXCHG_EdGd },
+ /* 0F B2 */ { BxAnother, &BX_CPU_C::LSS_GvMp },
+ /* 0F B3 */ { BxAnother, &BX_CPU_C::BTR_EvGv },
+ /* 0F B4 */ { BxAnother, &BX_CPU_C::LFS_GvMp },
+ /* 0F B5 */ { BxAnother, &BX_CPU_C::LGS_GvMp },
+ /* 0F B6 */ { BxAnother, &BX_CPU_C::MOVZX_GdEb },
+ /* 0F B7 */ { BxAnother, &BX_CPU_C::MOVZX_GdEw },
+ /* 0F B8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F B9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F BA */ { BxAnother | BxGroup8, NULL, BxOpcodeInfoG8EvIb },
+ /* 0F BB */ { BxAnother, &BX_CPU_C::BTC_EvGv },
+ /* 0F BC */ { BxAnother, &BX_CPU_C::BSF_GvEv },
+ /* 0F BD */ { BxAnother, &BX_CPU_C::BSR_GvEv },
+ /* 0F BE */ { BxAnother, &BX_CPU_C::MOVSX_GdEb },
+ /* 0F BF */ { BxAnother, &BX_CPU_C::MOVSX_GdEw },
+ /* 0F C0 */ { BxAnother, &BX_CPU_C::XADD_EbGb },
+ /* 0F C1 */ { BxAnother, &BX_CPU_C::XADD_EdGd },
+ /* 0F C2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F C7 */ { BxAnother | BxGroup9, NULL, BxOpcodeInfoG9 },
+ /* 0F C8 */ { 0, &BX_CPU_C::BSWAP_EAX },
+ /* 0F C9 */ { 0, &BX_CPU_C::BSWAP_ECX },
+ /* 0F CA */ { 0, &BX_CPU_C::BSWAP_EDX },
+ /* 0F CB */ { 0, &BX_CPU_C::BSWAP_EBX },
+ /* 0F CC */ { 0, &BX_CPU_C::BSWAP_ESP },
+ /* 0F CD */ { 0, &BX_CPU_C::BSWAP_EBP },
+ /* 0F CE */ { 0, &BX_CPU_C::BSWAP_ESI },
+ /* 0F CF */ { 0, &BX_CPU_C::BSWAP_EDI },
+ /* 0F D0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F D9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F DA */ { 0, &BX_CPU_C::BxError },
+ /* 0F DB */ { 0, &BX_CPU_C::BxError },
+ /* 0F DC */ { 0, &BX_CPU_C::BxError },
+ /* 0F DD */ { 0, &BX_CPU_C::BxError },
+ /* 0F DE */ { 0, &BX_CPU_C::BxError },
+ /* 0F DF */ { 0, &BX_CPU_C::BxError },
+ /* 0F E0 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E1 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E2 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E3 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E4 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E5 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E6 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E7 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E8 */ { 0, &BX_CPU_C::BxError },
+ /* 0F E9 */ { 0, &BX_CPU_C::BxError },
+ /* 0F EA */ { 0, &BX_CPU_C::BxError },
+ /* 0F EB */ { 0, &BX_CPU_C::BxError },
+ /* 0F EC */ { 0, &BX_CPU_C::BxError },
+ /* 0F ED */ { 0, &BX_CPU_C::BxError },
+ /* 0F EE */ { 0, &BX_CPU_C::BxError },
+ /* 0F EF */ { 0, &BX_CPU_C::BxError },
+ /* 0F F0 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F1 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F2 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F3 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F4 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F5 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F6 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F7 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F8 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F F9 */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FA */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FB */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FC */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FD */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FE */ { 0, &BX_CPU_C::UndefinedOpcode },
+ /* 0F FF */ { 0, &BX_CPU_C::UndefinedOpcode },
+ };
+
+
+
+
+ unsigned
+BX_CPU_C::FetchDecode(Bit8u *iptr, BxInstruction_t *instruction,
+ unsigned remain, Boolean is_32)
+{
+ // remain must be at least 1
+
+ unsigned b1, b2, ilen=1, attr;
+ unsigned imm_mode, offset;
+
+ instruction->os_32 = instruction->as_32 = is_32;
+ instruction->ResolveModrm = NULL;
+ instruction->seg = BX_SEG_REG_NULL;
+ instruction->rep_used = 0;
+
+
+fetch_b1:
+ b1 = *iptr++;
+
+another_byte:
+ offset = instruction->os_32 << 9; // * 512
+ instruction->attr = attr = BxOpcodeInfo[b1+offset].Attr;
+
+ if (attr & BxAnother) {
+ if (attr & BxPrefix) {
+ switch (b1) {
+ case 0x66: // OpSize
+ instruction->os_32 = !is_32;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+
+ case 0x67: // AddrSize
+ instruction->as_32 = !is_32;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+
+ case 0xf2: // REPNE/REPNZ
+ case 0xf3: // REP/REPE/REPZ
+ instruction->rep_used = b1;
+ if (ilen < remain) {
+ ilen++;
+ goto fetch_b1;
+ }
+ return(0);
+ break;
+
+ case 0x2e: // CS:
+ instruction->seg = BX_SEG_REG_CS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x26: // ES:
+ instruction->seg = BX_SEG_REG_ES;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x36: // SS:
+ instruction->seg = BX_SEG_REG_SS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x3e: // DS:
+ instruction->seg = BX_SEG_REG_DS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x64: // FS:
+ instruction->seg = BX_SEG_REG_FS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0x65: // GS:
+ instruction->seg = BX_SEG_REG_GS;
+ ilen++; goto fetch_b1;
+ break;
+ case 0xf0: // LOCK:
+ ilen++; goto fetch_b1;
+ break;
+
+ default:
+BX_PANIC(("fetch_decode: prefix default = 0x%02x\n", b1));
+ }
+ }
+ // opcode requires another byte
+ if (ilen < remain) {
+ ilen++;
+ b2 = *iptr++;
+ if (b1 == 0x0f) {
+ // 2-byte prefix
+ b1 = 0x100 | b2;
+ goto another_byte;
+ }
+ }
+ else
+ return(0);
+
+ // Parse mod-nnn-rm and related bytes
+ unsigned rm;
+ instruction->modrm = b2;
+ rm =
+ instruction->rm = b2 & 0x07;
+ instruction->mod = b2 & 0xc0; // leave unshifted
+ instruction->nnn = (b2 >> 3) & 0x07;
+ if (instruction->mod == 0xc0) { // mod == 11b
+ goto modrm_done;
+ }
+ if (instruction->as_32) {
+ // 32-bit addressing modes; note that mod==11b handled above
+ if (rm != 4) { // no s-i-b byte
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = 1<<rm; // except for mod=00b rm=100b
+#endif
+ if (instruction->mod == 0x00) { // mod == 00b
+ instruction->ResolveModrm = BxResolve32Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_SEG_REG_DS;
+ if (rm == 5) {
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr++) << 24;
+ instruction->rm_addr = imm32u;
+ ilen += 4;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = 0;
+#endif
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod==00b, rm!=4, rm!=5
+ goto modrm_done;
+ }
+ if (instruction->mod == 0x40) { // mod == 01b
+ instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm32[rm];
+get_8bit_displ:
+ if (ilen < remain) {
+ // 8 sign extended to 32
+ instruction->displ32u = (Bit8s) *iptr++;
+ ilen++;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // (mod == 0x80) mod == 10b
+ instruction->ResolveModrm = BxResolve32Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm32[rm];
+get_32bit_displ:
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr++) << 24;
+ instruction->displ32u = imm32u;
+ ilen += 4;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ else { // mod!=11b, rm==4, s-i-b byte follows
+ unsigned sib, base;
+ if (ilen < remain) {
+ sib = *iptr++;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ instruction->sib = sib;
+ base =
+ instruction->base = sib & 0x07; sib >>= 3;
+ instruction->index = sib & 0x07; sib >>= 3;
+ instruction->scale = sib;
+#if BX_DYNAMIC_TRANSLATION
+ if (instruction->index == 0x04) // 100b
+ instruction->DTMemRegsUsed = 0;
+ else
+ instruction->DTMemRegsUsed = 1<<instruction->index;
+#endif
+ if (instruction->mod == 0x00) { // mod==00b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod0Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod0Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod0_base32[base];
+ if (instruction->base == 0x05) {
+ goto get_32bit_displ;
+ }
+ // mod==00b, rm==4, base!=5
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed |= 1<<base;
+#endif
+ goto modrm_done;
+ }
+#if BX_DYNAMIC_TRANSLATION
+ // for remaining 32bit cases
+ instruction->DTMemRegsUsed |= 1<<base;
+#endif
+ if (instruction->mod == 0x40) { // mod==01b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+ goto get_8bit_displ;
+ }
+ // (instruction->mod == 0x80), mod==10b, rm==4
+ instruction->ResolveModrm = BxResolve32Mod1or2Base[base];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve32Mod1or2Base[base];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod1or2_base32[base];
+ goto get_32bit_displ;
+ }
+ }
+ else {
+ // 16-bit addressing modes, mod==11b handled above
+ if (instruction->mod == 0x40) { // mod == 01b
+ instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod01_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ if (ilen < remain) {
+ // 8 sign extended to 16
+ instruction->displ16u = (Bit8s) *iptr++;
+ ilen++;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ if (instruction->mod == 0x80) { // mod == 10b
+ instruction->ResolveModrm = BxResolve16Mod1or2[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod1or2[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod10_rm16[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ if ((ilen+1) < remain) {
+ Bit16u displ16u;
+ displ16u = *iptr++;
+ displ16u |= (*iptr++) << 8;
+ instruction->displ16u = displ16u;
+ ilen += 2;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod must be 00b at this point
+ instruction->ResolveModrm = BxResolve16Mod0[rm];
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTResolveModrm = (BxVoidFPtr_t) BxDTResolve16Mod0[rm];
+#endif
+ if (BX_NULL_SEG_REG(instruction->seg))
+ instruction->seg = BX_CPU_THIS_PTR sreg_mod00_rm16[rm];
+ if (rm == 0x06) {
+ if ((ilen+1) < remain) {
+ Bit16u displ16u;
+ displ16u = *iptr++;
+ displ16u |= (*iptr++) << 8;
+ instruction->rm_addr = displ16u;
+ ilen += 2;
+ goto modrm_done;
+ }
+ else {
+ return(0);
+ }
+ }
+ // mod=00b rm!=6
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTMemRegsUsed = BxMemRegsUsed16[rm];
+#endif
+ }
+
+modrm_done:
+ if (attr & BxGroupN) {
+ BxOpcodeInfo_t *OpcodeInfoPtr;
+
+ OpcodeInfoPtr = BxOpcodeInfo[b1+offset].AnotherArray;
+ instruction->execute = OpcodeInfoPtr[instruction->nnn].ExecutePtr;
+ // get additional attributes from group table
+ attr |= OpcodeInfoPtr[instruction->nnn].Attr;
+ instruction->attr = attr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = 0; // for now
+#endif
+ }
+ else {
+ instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+ instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+ }
+ }
+ else {
+ // Opcode does not require a MODRM byte.
+ // Note that a 2-byte opcode (0F XX) will jump to before
+ // the if() above after fetching the 2nd byte, so this path is
+ // taken in all cases if a modrm byte is NOT required.
+ instruction->execute = BxOpcodeInfo[b1+offset].ExecutePtr;
+#if BX_DYNAMIC_TRANSLATION
+ instruction->DTAttr = BxDTOpcodeInfo[b1+offset].DTAttr;
+ instruction->DTFPtr = BxDTOpcodeInfo[b1+offset].DTASFPtr;
+#endif
+ }
+
+
+ imm_mode = attr & BxImmediate;
+
+ if (imm_mode) {
+ switch (imm_mode) {
+ case BxImmediate_Ib:
+ if (ilen < remain) {
+ instruction->Ib = *iptr;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_Ib_SE: // Sign extend to OS size
+ if (ilen < remain) {
+ Bit8s temp8s;
+ temp8s = *iptr;
+ if (instruction->os_32)
+ instruction->Id = (Bit32s) temp8s;
+ else
+ instruction->Iw = (Bit16s) temp8s;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_Iv: // same as BxImmediate_BrOff32
+ case BxImmediate_IvIw: // CALL_Ap
+ if (instruction->os_32) {
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr) << 24;
+ instruction->Id = imm32u;
+ ilen += 4;
+ }
+ else {
+ return(0);
+ }
+ }
+ else {
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ }
+ if (imm_mode != BxImmediate_IvIw)
+ break;
+ iptr++;
+ // Get Iw for BxImmediate_IvIw
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw2 = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_O:
+ if (instruction->as_32) {
+ // fetch 32bit address into Id
+ if ((ilen+3) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr++) << 8;
+ imm32u |= (*iptr++) << 16;
+ imm32u |= (*iptr) << 24;
+ instruction->Id = imm32u;
+ ilen += 4;
+ }
+ else {
+ return(0);
+ }
+ }
+ else {
+ // fetch 16bit address into Id
+ if ((ilen+1) < remain) {
+ Bit32u imm32u;
+ imm32u = *iptr++;
+ imm32u |= (*iptr) << 8;
+ instruction->Id = imm32u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ }
+ break;
+ case BxImmediate_Iw:
+ case BxImmediate_IwIb:
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Iw = imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ if (imm_mode == BxImmediate_Iw) break;
+ iptr++;
+ if (ilen < remain) {
+ instruction->Ib2 = *iptr;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_BrOff8:
+ if (ilen < remain) {
+ Bit8s temp8s;
+ temp8s = *iptr;
+ instruction->Id = temp8s;
+ ilen++;
+ }
+ else {
+ return(0);
+ }
+ break;
+ case BxImmediate_BrOff16:
+ if ((ilen+1) < remain) {
+ Bit16u imm16u;
+ imm16u = *iptr++;
+ imm16u |= (*iptr) << 8;
+ instruction->Id = (Bit16s) imm16u;
+ ilen += 2;
+ }
+ else {
+ return(0);
+ }
+ break;
+ default:
+BX_INFO(("b1 was %x\n", b1));
+ BX_PANIC(("fetchdecode: imm_mode = %u\n", imm_mode));
+ }
+ }
+
+
+ instruction->b1 = b1;
+ instruction->ilen = ilen;
+ //instruction->flags_in = 0; // for now
+ //instruction->flags_out = 0; // for now
+ return(1);
+}
+
+ void
+BX_CPU_C::BxError(BxInstruction_t *i)
+{
+ // extern void dump_core();
+ BX_INFO(("BxError: instruction with op1=0x%x\n", i->b1));
+ BX_INFO(("nnn was %u\n", i->nnn));
+
+ BX_INFO(("WARNING: Encountered an unknown instruction (signalling illegal instruction):\n"));
+ // dump_core();
+
+ BX_CPU_THIS_PTR UndefinedOpcode(i);
+}
+
+ void
+BX_CPU_C::BxResolveError(BxInstruction_t *i)
+{
+ BX_PANIC(("BxResolveError: instruction with op1=0x%x\n", i->b1));
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::SAHF(BxInstruction_t *i)
+{
+ set_SF((AH & 0x80) >> 7);
+ set_ZF((AH & 0x40) >> 6);
+ set_AF((AH & 0x10) >> 4);
+ set_CF(AH & 0x01);
+ set_PF((AH & 0x04) >> 2);
+}
+
+ void
+BX_CPU_C::LAHF(BxInstruction_t *i)
+{
+ AH = (get_SF() ? 0x80 : 0) |
+ (get_ZF() ? 0x40 : 0) |
+ (get_AF() ? 0x10 : 0) |
+ (get_PF() ? 0x04 : 0) |
+ (0x02) |
+ (get_CF() ? 0x01 : 0);
+}
+
+ void
+BX_CPU_C::CLC(BxInstruction_t *i)
+{
+ set_CF(0);
+}
+
+ void
+BX_CPU_C::STC(BxInstruction_t *i)
+{
+ set_CF(1);
+}
+
+ void
+BX_CPU_C::CLI(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (CPL > IOPL) {
+ //BX_INFO(("CLI: CPL > IOPL\n")); /* ??? */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+#if BX_CPU_LEVEL >= 3
+ else if (v8086_mode()) {
+ if (IOPL != 3) {
+ //BX_INFO(("CLI: IOPL != 3\n")); /* ??? */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+#endif
+#endif
+
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+}
+
+ void
+BX_CPU_C::STI(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (CPL > IOPL) {
+ //BX_INFO(("STI: CPL > IOPL\n")); /* ??? */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+#if BX_CPU_LEVEL >= 3
+ else if (v8086_mode()) {
+ if (IOPL != 3) {
+ //BX_INFO(("STI: IOPL != 3\n")); /* ??? */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+#endif
+#endif
+
+ if (!BX_CPU_THIS_PTR eflags.if_) {
+ BX_CPU_THIS_PTR eflags.if_ = 1;
+ BX_CPU_THIS_PTR inhibit_mask |= BX_INHIBIT_INTERRUPTS;
+ BX_CPU_THIS_PTR async_event = 1;
+ }
+}
+
+ void
+BX_CPU_C::CLD(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR eflags.df = 0;
+}
+
+ void
+BX_CPU_C::STD(BxInstruction_t *i)
+{
+ BX_CPU_THIS_PTR eflags.df = 1;
+}
+
+ void
+BX_CPU_C::CMC(BxInstruction_t *i)
+{
+ set_CF( !get_CF() );
+}
+
+ void
+BX_CPU_C::PUSHF_Fv(BxInstruction_t *i)
+{
+ if (v8086_mode() && (IOPL<3)) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ push_32(read_eflags() & 0x00fcffff);
+ }
+ else
+#endif
+ {
+ push_16(read_flags());
+ }
+}
+
+
+ void
+BX_CPU_C::POPF_Fv(BxInstruction_t *i)
+{
+
+#if BX_CPU_LEVEL >= 3
+ if (v8086_mode()) {
+ if (IOPL < 3) {
+ //BX_INFO(("popf_fv: IOPL < 3\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ if (i->os_32) {
+ BX_PANIC(("POPFD(): not supported in virtual mode\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ if (i->os_32) {
+ Bit32u eflags;
+
+ pop_32(&eflags);
+
+ eflags &= 0x00277fd7;
+ if (!real_mode()) {
+ write_eflags(eflags, /* change IOPL? */ CPL==0, /* change IF? */ CPL<=IOPL, 0, 0);
+ }
+ else { /* real mode */
+ write_eflags(eflags, /* change IOPL? */ 1, /* change IF? */ 1, 0, 0);
+ }
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize */
+ Bit16u flags;
+
+ pop_16(&flags);
+
+ if (!real_mode()) {
+ write_flags(flags, /* change IOPL? */ CPL==0, /* change IF? */ CPL<=IOPL);
+ }
+ else { /* real mode */
+ write_flags(flags, /* change IOPL? */ 1, /* change IF? */ 1);
+ }
+ }
+}
+
+
+ void
+BX_CPU_C::SALC(BxInstruction_t *i)
+{
+ if ( get_CF() ) {
+ AL = 0xff;
+ }
+ else {
+ AL = 0x00;
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+ void
+BX_CPU_C::write_flags(Bit16u flags, Boolean change_IOPL, Boolean change_IF)
+{
+ BX_CPU_THIS_PTR set_CF(flags & 0x01);
+ BX_CPU_THIS_PTR set_PF((flags >> 2) & 0x01);
+ BX_CPU_THIS_PTR set_AF((flags >> 4) & 0x01);
+ BX_CPU_THIS_PTR set_ZF((flags >> 6) & 0x01);
+ BX_CPU_THIS_PTR set_SF((flags >> 7) & 0x01);
+
+#if 0
+// +++
+if (BX_CPU_THIS_PTR eflags.tf==0 && (flags&0x0100))
+ BX_DEBUG(( "TF 0->1\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && !(flags&0x0100))
+ BX_DEBUG(( "TF 1->0\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && (flags&0x0100))
+ BX_DEBUG(( "TF 1->1\n" ));
+#endif
+
+ BX_CPU_THIS_PTR eflags.tf = (flags >> 8) & 0x01;
+ if (BX_CPU_THIS_PTR eflags.tf) {
+ BX_CPU_THIS_PTR async_event = 1;
+ }
+
+ if (change_IF)
+ BX_CPU_THIS_PTR eflags.if_ = (flags >> 9) & 0x01;
+
+ BX_CPU_THIS_PTR eflags.df = (flags >> 10) & 0x01;
+ BX_CPU_THIS_PTR set_OF((flags >> 11) & 0x01);
+
+
+#if BX_CPU_LEVEL == 2
+ BX_CPU_THIS_PTR eflags.iopl = 0;
+ BX_CPU_THIS_PTR eflags.nt = 0;
+#else
+ if (change_IOPL)
+ BX_CPU_THIS_PTR eflags.iopl = (flags >> 12) & 0x03;
+ BX_CPU_THIS_PTR eflags.nt = (flags >> 14) & 0x01;
+#endif
+}
+
+
+#if BX_CPU_LEVEL >= 3
+ void
+BX_CPU_C::write_eflags(Bit32u eflags_raw, Boolean change_IOPL, Boolean change_IF,
+ Boolean change_VM, Boolean change_RF)
+{
+ BX_CPU_THIS_PTR set_CF(eflags_raw & 0x01);
+ BX_CPU_THIS_PTR set_PF((eflags_raw >> 2) & 0x01);
+ BX_CPU_THIS_PTR set_AF((eflags_raw >> 4) & 0x01);
+ BX_CPU_THIS_PTR set_ZF((eflags_raw >> 6) & 0x01);
+ BX_CPU_THIS_PTR set_SF((eflags_raw >> 7) & 0x01);
+
+#if 0
+// +++
+if (BX_CPU_THIS_PTR eflags.tf==0 && (eflags_raw&0x0100))
+ BX_DEBUG(( "TF 0->1\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && !(eflags_raw&0x0100))
+ BX_DEBUG(( "TF 1->0\n" ));
+else if (BX_CPU_THIS_PTR eflags.tf && (eflags_raw&0x0100))
+ BX_DEBUG(( "TF 1->1\n" ));
+#endif
+
+ BX_CPU_THIS_PTR eflags.tf = (eflags_raw >> 8) & 0x01;
+ if (BX_CPU_THIS_PTR eflags.tf) {
+ BX_CPU_THIS_PTR async_event = 1;
+ }
+
+ if (change_IF)
+ BX_CPU_THIS_PTR eflags.if_ = (eflags_raw >> 9) & 0x01;
+
+ BX_CPU_THIS_PTR eflags.df = (eflags_raw >> 10) & 0x01;
+ BX_CPU_THIS_PTR set_OF((eflags_raw >> 11) & 0x01);
+
+ if (change_IOPL)
+ BX_CPU_THIS_PTR eflags.iopl = (eflags_raw >> 12) & 0x03;
+ BX_CPU_THIS_PTR eflags.nt = (eflags_raw >> 14) & 0x01;
+
+ if (change_VM) {
+ BX_CPU_THIS_PTR eflags.vm = (eflags_raw >> 17) & 0x01;
+#if BX_SUPPORT_V8086_MODE == 0
+ if (BX_CPU_THIS_PTR eflags.vm)
+ BX_PANIC(("write_eflags: VM bit set: BX_SUPPORT_V8086_MODE==0\n"));
+#endif
+ }
+ if (change_RF) {
+ BX_CPU_THIS_PTR eflags.rf = (eflags_raw >> 16) & 0x01;
+ }
+
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR eflags.ac = (eflags_raw >> 18) & 0x01;
+ BX_CPU_THIS_PTR eflags.id = (eflags_raw >> 21) & 0x01;
+#endif
+
+}
+#endif /* BX_CPU_LEVEL >= 3 */
+
+
+ Bit16u
+BX_CPU_C::read_flags(void)
+{
+ Bit16u flags;
+
+ flags = (get_CF()) |
+ (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+ ((get_PF()) << 2) |
+ (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+ ((get_AF()>0) << 4) |
+ (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+ ((get_ZF()>0) << 6) |
+ ((get_SF()>0) << 7) |
+ (BX_CPU_THIS_PTR eflags.tf << 8) |
+ (BX_CPU_THIS_PTR eflags.if_ << 9) |
+ (BX_CPU_THIS_PTR eflags.df << 10) |
+ ((get_OF()>0) << 11) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.bit15 << 15);
+
+ /* 8086: bits 12-15 always set to 1.
+ * 286: in real mode, bits 12-15 always cleared.
+ * 386+: real-mode: bit15 cleared, bits 14..12 are last loaded value
+ * protected-mode: bit 15 clear, bit 14 = last loaded, IOPL?
+ */
+#if BX_CPU_LEVEL < 2
+ flags |= 0xF000; /* 8086 nature */
+#elif BX_CPU_LEVEL == 2
+ if (real_mode()) {
+ flags &= 0x0FFF; /* 80286 in real mode nature */
+ }
+#else /* 386+ */
+#endif
+
+ return(flags);
+}
+
+
+#if BX_CPU_LEVEL >= 3
+ Bit32u
+BX_CPU_C::read_eflags(void)
+{
+ Bit32u eflags_raw;
+
+ eflags_raw =
+ (get_CF()) |
+ (BX_CPU_THIS_PTR eflags.bit1 << 1) |
+ ((get_PF()) << 2) |
+ (BX_CPU_THIS_PTR eflags.bit3 << 3) |
+ ((get_AF()>0) << 4) |
+ (BX_CPU_THIS_PTR eflags.bit5 << 5) |
+ ((get_ZF()>0) << 6) |
+ ((get_SF()>0) << 7) |
+ (BX_CPU_THIS_PTR eflags.tf << 8) |
+ (BX_CPU_THIS_PTR eflags.if_ << 9) |
+ (BX_CPU_THIS_PTR eflags.df << 10) |
+ ((get_OF()>0) << 11) |
+ (BX_CPU_THIS_PTR eflags.iopl << 12) |
+ (BX_CPU_THIS_PTR eflags.nt << 14) |
+ (BX_CPU_THIS_PTR eflags.bit15 << 15) |
+ (BX_CPU_THIS_PTR eflags.rf << 16) |
+ (BX_CPU_THIS_PTR eflags.vm << 17)
+#if BX_CPU_LEVEL >= 4
+ | (BX_CPU_THIS_PTR eflags.ac << 18)
+ | (BX_CPU_THIS_PTR eflags.id << 21)
+#endif
+ ;
+
+#if 0
+ /*
+ * 386+: real-mode: bit15 cleared, bits 14..12 are last loaded value
+ * protected-mode: bit 15 clear, bit 14 = last loaded, IOPL?
+ */
+#endif
+
+ return(eflags_raw);
+}
+#endif /* BX_CPU_LEVEL >= 3 */
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+ // sid_cpu_c constructor
+void sid_cpu_c::init(sid_mem_c *addrspace)
+{
+ // To deal with initialization order problems inherent in C++, use
+ // the macros SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog"
+ // in all constructors or functions called by constructors. The macros
+ // test for NULL and create the object if necessary, then return it.
+ // Ensure that io and genlog get created, by making one reference to
+ // each macro right here. All other code can call them directly.
+ SAFE_GET_IOFUNC();
+ SAFE_GET_GENLOG();
+
+ BX_CPU_THIS_PTR set_INTR (0);
+#if BX_SUPPORT_APIC
+ local_apic.init ();
+#endif
+ setprefix("[CPU ]");
+ // in SMP mode, the prefix of the CPU will be changed to [CPUn] in
+ // bx_local_apic_c::set_id as soon as the apic ID is assigned.
+
+ /* hack for the following fields. Its easier to decode mod-rm bytes if
+ you can assume there's always a base & index register used. For
+ modes which don't really use them, point to an empty (zeroed) register.
+ */
+ empty_register = 0;
+
+ // 16bit address mode base register, used for mod-rm decoding
+
+ _16bit_base_reg[0] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+ _16bit_base_reg[1] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+ _16bit_base_reg[2] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[3] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[4] = (Bit16u*) &empty_register;
+ _16bit_base_reg[5] = (Bit16u*) &empty_register;
+ _16bit_base_reg[6] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[7] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+
+ // 16bit address mode index register, used for mod-rm decoding
+ _16bit_index_reg[0] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[1] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[2] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[3] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[4] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[5] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[6] = (Bit16u*) &empty_register;
+ _16bit_index_reg[7] = (Bit16u*) &empty_register;
+
+ // for decoding instructions: access to seg reg's via index number
+ sreg_mod00_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod00_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod00_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[6] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[7] = BX_SEG_REG_DS;
+
+ sreg_mod01_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[6] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[7] = BX_SEG_REG_DS;
+
+ sreg_mod10_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[6] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a one-byte modrm with mod==01b
+ // and rm==i
+ //
+ sreg_mod01_rm32[0] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[1] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[2] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[3] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[4] = BX_SEG_REG_NULL;
+ // this entry should never be accessed
+ // (escape to 2-byte)
+ sreg_mod01_rm32[5] = BX_SEG_REG_SS;
+ sreg_mod01_rm32[6] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a one-byte modrm with mod==10b
+ // and rm==i
+ //
+ sreg_mod10_rm32[0] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[1] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[2] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[3] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[4] = BX_SEG_REG_NULL;
+ // this entry should never be accessed
+ // (escape to 2-byte)
+ sreg_mod10_rm32[5] = BX_SEG_REG_SS;
+ sreg_mod10_rm32[6] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[7] = BX_SEG_REG_DS;
+
+
+ // the default segment to use for a two-byte modrm with mod==00b
+ // and base==i
+ //
+ sreg_mod0_base32[0] = BX_SEG_REG_DS;
+ sreg_mod0_base32[1] = BX_SEG_REG_DS;
+ sreg_mod0_base32[2] = BX_SEG_REG_DS;
+ sreg_mod0_base32[3] = BX_SEG_REG_DS;
+ sreg_mod0_base32[4] = BX_SEG_REG_SS;
+ sreg_mod0_base32[5] = BX_SEG_REG_DS;
+ sreg_mod0_base32[6] = BX_SEG_REG_DS;
+ sreg_mod0_base32[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a two-byte modrm with
+ // mod==01b or mod==10b and base==i
+ sreg_mod1or2_base32[0] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[1] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[2] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[3] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[4] = BX_SEG_REG_SS;
+ sreg_mod1or2_base32[5] = BX_SEG_REG_SS;
+ sreg_mod1or2_base32[6] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[7] = BX_SEG_REG_DS;
+
+#if BX_DYNAMIC_TRANSLATION
+ DTWrite8vShim = NULL;
+ DTWrite16vShim = NULL;
+ DTWrite32vShim = NULL;
+ DTRead8vShim = NULL;
+ DTRead16vShim = NULL;
+ DTRead32vShim = NULL;
+ DTReadRMW8vShim = (BxDTShim_t) DTASReadRMW8vShim;
+ BX_DEBUG(( "DTReadRMW8vShim is %x\n", (unsigned) DTReadRMW8vShim ));
+ BX_DEBUG(( "&DTReadRMW8vShim is %x\n", (unsigned) &DTReadRMW8vShim ));
+ DTReadRMW16vShim = NULL;
+ DTReadRMW32vShim = NULL;
+ DTWriteRMW8vShim = (BxDTShim_t) DTASWriteRMW8vShim;
+ DTWriteRMW16vShim = NULL;
+ DTWriteRMW32vShim = NULL;
+ DTSetFlagsOSZAPCPtr = (BxDTShim_t) DTASSetFlagsOSZAPC;
+ DTIndBrHandler = (BxDTShim_t) DTASIndBrHandler;
+ DTDirBrHandler = (BxDTShim_t) DTASDirBrHandler;
+#endif
+
+ mem = addrspace;
+ sprintf (name, "CPU %p", this);
+
+ BX_INSTR_INIT();
+ BX_DEBUG(( "Init.\n"));
+}
+
+ void
+sid_cpu_c::set_INTR(Boolean value)
+{
+ BX_CPU_THIS_PTR INTR = value;
+ BX_CPU_THIS_PTR async_event = 0;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+/* the device id and stepping id are loaded into DH & DL upon processor
+ startup. for device id: 3 = 80386, 4 = 80486. just make up a
+ number for the stepping (revision) id. */
+#define BX_DEVICE_ID 3
+#define BX_STEPPING_ID 0
+
+BX_CPU_C::BX_CPU_C()
+#if BX_SUPPORT_APIC
+ : local_apic (this)
+#endif
+{
+ // in case of SMF, you cannot reference any member data
+ // in the constructor because the only access to it is via
+ // global variables which aren't initialized quite yet.
+}
+
+#if BX_SUPPORT_SID
+void BX_CPU_C::init(sid_mem_c *addrspace)
+#else
+void BX_CPU_C::init(BX_MEM_C *addrspace)
+#endif
+{
+ // BX_CPU_C constructor
+ BX_CPU_THIS_PTR set_INTR (0);
+#if BX_SUPPORT_APIC
+ local_apic.init ();
+#endif
+ setprefix("[CPU ]");
+ // in SMP mode, the prefix of the CPU will be changed to [CPUn] in
+ // bx_local_apic_c::set_id as soon as the apic ID is assigned.
+
+ /* hack for the following fields. Its easier to decode mod-rm bytes if
+ you can assume there's always a base & index register used. For
+ modes which don't really use them, point to an empty (zeroed) register.
+ */
+ empty_register = 0;
+
+ // 16bit address mode base register, used for mod-rm decoding
+
+ _16bit_base_reg[0] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+ _16bit_base_reg[1] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+ _16bit_base_reg[2] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[3] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[4] = (Bit16u*) &empty_register;
+ _16bit_base_reg[5] = (Bit16u*) &empty_register;
+ _16bit_base_reg[6] = &gen_reg[BX_16BIT_REG_BP].word.rx;
+ _16bit_base_reg[7] = &gen_reg[BX_16BIT_REG_BX].word.rx;
+
+ // 16bit address mode index register, used for mod-rm decoding
+ _16bit_index_reg[0] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[1] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[2] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[3] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[4] = &gen_reg[BX_16BIT_REG_SI].word.rx;
+ _16bit_index_reg[5] = &gen_reg[BX_16BIT_REG_DI].word.rx;
+ _16bit_index_reg[6] = (Bit16u*) &empty_register;
+ _16bit_index_reg[7] = (Bit16u*) &empty_register;
+
+ // for decoding instructions: access to seg reg's via index number
+ sreg_mod00_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod00_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod00_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[6] = BX_SEG_REG_DS;
+ sreg_mod00_rm16[7] = BX_SEG_REG_DS;
+
+ sreg_mod01_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod01_rm16[6] = BX_SEG_REG_SS;
+ sreg_mod01_rm16[7] = BX_SEG_REG_DS;
+
+ sreg_mod10_rm16[0] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[1] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[2] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[3] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[4] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[5] = BX_SEG_REG_DS;
+ sreg_mod10_rm16[6] = BX_SEG_REG_SS;
+ sreg_mod10_rm16[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a one-byte modrm with mod==01b
+ // and rm==i
+ //
+ sreg_mod01_rm32[0] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[1] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[2] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[3] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[4] = BX_SEG_REG_NULL;
+ // this entry should never be accessed
+ // (escape to 2-byte)
+ sreg_mod01_rm32[5] = BX_SEG_REG_SS;
+ sreg_mod01_rm32[6] = BX_SEG_REG_DS;
+ sreg_mod01_rm32[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a one-byte modrm with mod==10b
+ // and rm==i
+ //
+ sreg_mod10_rm32[0] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[1] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[2] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[3] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[4] = BX_SEG_REG_NULL;
+ // this entry should never be accessed
+ // (escape to 2-byte)
+ sreg_mod10_rm32[5] = BX_SEG_REG_SS;
+ sreg_mod10_rm32[6] = BX_SEG_REG_DS;
+ sreg_mod10_rm32[7] = BX_SEG_REG_DS;
+
+
+ // the default segment to use for a two-byte modrm with mod==00b
+ // and base==i
+ //
+ sreg_mod0_base32[0] = BX_SEG_REG_DS;
+ sreg_mod0_base32[1] = BX_SEG_REG_DS;
+ sreg_mod0_base32[2] = BX_SEG_REG_DS;
+ sreg_mod0_base32[3] = BX_SEG_REG_DS;
+ sreg_mod0_base32[4] = BX_SEG_REG_SS;
+ sreg_mod0_base32[5] = BX_SEG_REG_DS;
+ sreg_mod0_base32[6] = BX_SEG_REG_DS;
+ sreg_mod0_base32[7] = BX_SEG_REG_DS;
+
+ // the default segment to use for a two-byte modrm with
+ // mod==01b or mod==10b and base==i
+ sreg_mod1or2_base32[0] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[1] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[2] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[3] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[4] = BX_SEG_REG_SS;
+ sreg_mod1or2_base32[5] = BX_SEG_REG_SS;
+ sreg_mod1or2_base32[6] = BX_SEG_REG_DS;
+ sreg_mod1or2_base32[7] = BX_SEG_REG_DS;
+
+#if BX_DYNAMIC_TRANSLATION
+ DTWrite8vShim = NULL;
+ DTWrite16vShim = NULL;
+ DTWrite32vShim = NULL;
+ DTRead8vShim = NULL;
+ DTRead16vShim = NULL;
+ DTRead32vShim = NULL;
+ DTReadRMW8vShim = (BxDTShim_t) DTASReadRMW8vShim;
+ BX_DEBUG(( "DTReadRMW8vShim is %x\n", (unsigned) DTReadRMW8vShim ));
+ BX_DEBUG(( "&DTReadRMW8vShim is %x\n", (unsigned) &DTReadRMW8vShim ));
+ DTReadRMW16vShim = NULL;
+ DTReadRMW32vShim = NULL;
+ DTWriteRMW8vShim = (BxDTShim_t) DTASWriteRMW8vShim;
+ DTWriteRMW16vShim = NULL;
+ DTWriteRMW32vShim = NULL;
+ DTSetFlagsOSZAPCPtr = (BxDTShim_t) DTASSetFlagsOSZAPC;
+ DTIndBrHandler = (BxDTShim_t) DTASIndBrHandler;
+ DTDirBrHandler = (BxDTShim_t) DTASDirBrHandler;
+#endif
+
+ mem = addrspace;
+ sprintf (name, "CPU %p", this);
+
+ BX_INSTR_INIT();
+ BX_DEBUG(( "Init.\n"));
+}
+
+
+BX_CPU_C::~BX_CPU_C(void)
+{
+ BX_INSTR_SHUTDOWN();
+ BX_DEBUG(( "Exit.\n"));
+}
+
+
+
+ void
+BX_CPU_C::reset(unsigned source)
+{
+ UNUSED(source); // either BX_RESET_HARDWARE or BX_RESET_SOFTWARE
+
+ // general registers
+ EAX = 0; // processor passed test :-)
+ EBX = 0; // undefined
+ ECX = 0; // undefined
+ EDX = (BX_DEVICE_ID << 8) | BX_STEPPING_ID; // ???
+ EBP = 0; // undefined
+ ESI = 0; // undefined
+ EDI = 0; // undefined
+ ESP = 0; // undefined
+
+ // all status flags at known values, use BX_CPU_THIS_PTR eflags structure
+ BX_CPU_THIS_PTR lf_flags_status = 0x000000;
+ BX_CPU_THIS_PTR lf_pf = 0;
+
+ // status and control flags register set
+ BX_CPU_THIS_PTR set_CF(0);
+ BX_CPU_THIS_PTR eflags.bit1 = 1;
+ BX_CPU_THIS_PTR set_PF(0);
+ BX_CPU_THIS_PTR eflags.bit3 = 0;
+ BX_CPU_THIS_PTR set_AF(0);
+ BX_CPU_THIS_PTR eflags.bit5 = 0;
+ BX_CPU_THIS_PTR set_ZF(0);
+ BX_CPU_THIS_PTR set_SF(0);
+ BX_CPU_THIS_PTR eflags.tf = 0;
+ BX_CPU_THIS_PTR eflags.if_ = 0;
+ BX_CPU_THIS_PTR eflags.df = 0;
+ BX_CPU_THIS_PTR set_OF(0);
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR eflags.iopl = 0;
+ BX_CPU_THIS_PTR eflags.nt = 0;
+#endif
+ BX_CPU_THIS_PTR eflags.bit15 = 0;
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR eflags.rf = 0;
+ BX_CPU_THIS_PTR eflags.vm = 0;
+#endif
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR eflags.ac = 0;
+#endif
+
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+ BX_CPU_THIS_PTR debug_trap = 0;
+
+ /* instruction pointer */
+#if BX_CPU_LEVEL < 2
+ BX_CPU_THIS_PTR prev_eip =
+ BX_CPU_THIS_PTR eip = 0x00000000;
+#else /* from 286 up */
+ BX_CPU_THIS_PTR prev_eip =
+ BX_CPU_THIS_PTR eip = 0x0000FFF0;
+#endif
+
+
+ /* CS (Code Segment) and descriptor cache */
+ /* Note: on a real cpu, CS initially points to upper memory. After
+ * the 1st jump, the descriptor base is zero'd out. Since I'm just
+ * going to jump to my BIOS, I don't need to do this.
+ * For future reference:
+ * processor cs.selector cs.base cs.limit EIP
+ * 8086 FFFF FFFF0 FFFF 0000
+ * 286 F000 FF0000 FFFF FFF0
+ * 386+ F000 FFFF0000 FFFF FFF0
+ */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = 0xf000;
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x000F0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* SS (Stack Segment) and descriptor cache */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = 0x0000;
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = 0x00000000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* DS (Data Segment) and descriptor cache */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = 0x0000;
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = 0; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* ES (Extra Segment) and descriptor cache */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0x0000;
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = 0; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = 0x00000000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled = 0xFFFF;
+#endif
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+
+ /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = 0; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base = 0x00000000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.index = 0x0000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.ti = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = 0; /* data/stack segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = 0; /* normal expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base = 0x00000000;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled = 0xFFFF;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 0; /* 16bit default size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR gdtr.base = 0x00000000; /* undefined */
+ BX_CPU_THIS_PTR gdtr.limit = 0x0000; /* undefined */
+ /* ??? AR=Present, Read/Write */
+#endif
+
+ /* IDTR (Interrupt Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR idtr.base = 0x00000000;
+ BX_CPU_THIS_PTR idtr.limit = 0x03FF; /* always byte granular */ /* ??? */
+ /* ??? AR=Present, Read/Write */
+#endif
+
+ /* LDTR (Local Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+ BX_CPU_THIS_PTR ldtr.selector.value = 0x0000;
+ BX_CPU_THIS_PTR ldtr.selector.index = 0x0000;
+ BX_CPU_THIS_PTR ldtr.selector.ti = 0;
+ BX_CPU_THIS_PTR ldtr.selector.rpl = 0;
+
+ BX_CPU_THIS_PTR ldtr.cache.valid = 0; /* not valid */
+ BX_CPU_THIS_PTR ldtr.cache.p = 0; /* not present */
+ BX_CPU_THIS_PTR ldtr.cache.dpl = 0; /* field not used */
+ BX_CPU_THIS_PTR ldtr.cache.segment = 0; /* system segment */
+ BX_CPU_THIS_PTR ldtr.cache.type = 2; /* LDT descriptor */
+
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = 0x00000000;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0xFFFF;
+#endif
+
+ /* TR (Task Register) */
+#if BX_CPU_LEVEL >= 2
+ /* ??? I don't know what state the TR comes up in */
+ BX_CPU_THIS_PTR tr.selector.value = 0x0000;
+ BX_CPU_THIS_PTR tr.selector.index = 0x0000; /* undefined */
+ BX_CPU_THIS_PTR tr.selector.ti = 0;
+ BX_CPU_THIS_PTR tr.selector.rpl = 0;
+
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ BX_CPU_THIS_PTR tr.cache.p = 0;
+ BX_CPU_THIS_PTR tr.cache.dpl = 0; /* field not used */
+ BX_CPU_THIS_PTR tr.cache.segment = 0;
+ BX_CPU_THIS_PTR tr.cache.type = 0; /* invalid */
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base = 0x00000000; /* undefined */
+ BX_CPU_THIS_PTR tr.cache.u.tss286.limit = 0x0000; /* undefined */
+#endif
+
+ // DR0 - DR7 (Debug Registers)
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR dr0 = 0; /* undefined */
+ BX_CPU_THIS_PTR dr1 = 0; /* undefined */
+ BX_CPU_THIS_PTR dr2 = 0; /* undefined */
+ BX_CPU_THIS_PTR dr3 = 0; /* undefined */
+#endif
+#if BX_CPU_LEVEL == 3
+ BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
+ BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 4
+ BX_CPU_THIS_PTR dr6 = 0xFFFF1FF0;
+ BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 5
+ BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
+ BX_CPU_THIS_PTR dr7 = 0x00000400;
+#elif BX_CPU_LEVEL == 6
+ BX_CPU_THIS_PTR dr6 = 0xFFFF0FF0;
+ BX_CPU_THIS_PTR dr7 = 0x00000400;
+#else
+# error "DR6,7: CPU > 6"
+#endif
+
+#if 0
+ /* test registers 3-7 (unimplemented) */
+ BX_CPU_THIS_PTR tr3 = 0; /* undefined */
+ BX_CPU_THIS_PTR tr4 = 0; /* undefined */
+ BX_CPU_THIS_PTR tr5 = 0; /* undefined */
+ BX_CPU_THIS_PTR tr6 = 0; /* undefined */
+ BX_CPU_THIS_PTR tr7 = 0; /* undefined */
+#endif
+
+#if BX_CPU_LEVEL >= 2
+ // MSW (Machine Status Word), so called on 286
+ // CR0 (Control Register 0), so called on 386+
+ BX_CPU_THIS_PTR cr0.ts = 0; // no task switch
+ BX_CPU_THIS_PTR cr0.em = 0; // emulate math coprocessor
+ BX_CPU_THIS_PTR cr0.mp = 0; // wait instructions not trapped
+ BX_CPU_THIS_PTR cr0.pe = 0; // real mode
+ BX_CPU_THIS_PTR cr0.val32 = 0;
+
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR cr0.pg = 0; // paging disabled
+ // no change to cr0.val32
+#endif
+
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR cr0.cd = 1; // caching disabled
+ BX_CPU_THIS_PTR cr0.nw = 1; // not write-through
+ BX_CPU_THIS_PTR cr0.am = 0; // disable alignment check
+ BX_CPU_THIS_PTR cr0.wp = 0; // disable write-protect
+ BX_CPU_THIS_PTR cr0.ne = 0; // ndp exceptions through int 13H, DOS compat
+ BX_CPU_THIS_PTR cr0.val32 |= 0x60000000;
+#endif
+
+ // handle reserved bits
+#if BX_CPU_LEVEL == 3
+ // reserved bits all set to 1 on 386
+ BX_CPU_THIS_PTR cr0.val32 |= 0x7ffffff0;
+#elif BX_CPU_LEVEL >= 4
+ // bit 4 is hardwired to 1 on all x86
+ BX_CPU_THIS_PTR cr0.val32 |= 0x00000010;
+#endif
+#endif // CPU >= 2
+
+
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR cr2 = 0;
+ BX_CPU_THIS_PTR cr3 = 0;
+#endif
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR cr4 = 0;
+#endif
+
+
+
+ BX_CPU_THIS_PTR EXT = 0;
+ //BX_INTR = 0;
+
+#if BX_SUPPORT_PAGING
+#if BX_USE_TLB
+ TLB_init();
+#endif
+#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;
+
+#if BX_DEBUGGER
+#ifdef MAGIC_BREAKPOINT
+ BX_CPU_THIS_PTR magic_break = 0;
+#endif
+ BX_CPU_THIS_PTR stop_reason = STOP_NO_REASON;
+ BX_CPU_THIS_PTR trace = 0;
+#endif
+
+ // Init the Floating Point Unit
+ fpu_init();
+
+#if BX_DYNAMIC_TRANSLATION
+ dynamic_init();
+#endif
+
+#if (BX_SMP_PROCESSORS > 1)
+ // notice if I'm the bootstrap processor. If not, do the equivalent of
+ // a HALT instruction.
+ int apic_id = local_apic.get_id ();
+ if (BX_BOOTSTRAP_PROCESSOR == apic_id)
+ {
+ // boot normally
+ BX_INFO(("CPU[%d] is the bootstrap processor\n", apic_id));
+ } else {
+ // it's an application processor, halt until IPI is heard.
+ BX_INFO(("CPU[%d] is an application processor. Halting until IPI.\n", apic_id));
+ debug_trap |= 0x80000000;
+ async_event = 1;
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::sanity_checks(void)
+{
+ Bit8u al, cl, dl, bl, ah, ch, dh, bh;
+ Bit16u ax, cx, dx, bx, sp, bp, si, di;
+ Bit32u eax, ecx, edx, ebx, esp, ebp, esi, edi;
+
+ EAX = 0xFFEEDDCC;
+ ECX = 0xBBAA9988;
+ EDX = 0x77665544;
+ EBX = 0x332211FF;
+ ESP = 0xEEDDCCBB;
+ EBP = 0xAA998877;
+ ESI = 0x66554433;
+ EDI = 0x2211FFEE;
+
+ al = AL;
+ cl = CL;
+ dl = DL;
+ bl = BL;
+ ah = AH;
+ ch = CH;
+ dh = DH;
+ bh = BH;
+
+ if ( al != (EAX & 0xFF) ||
+ cl != (ECX & 0xFF) ||
+ dl != (EDX & 0xFF) ||
+ bl != (EBX & 0xFF) ||
+ ah != ((EAX >> 8) & 0xFF) ||
+ ch != ((ECX >> 8) & 0xFF) ||
+ dh != ((EDX >> 8) & 0xFF) ||
+ bh != ((EBX >> 8) & 0xFF) ) {
+ BX_PANIC(("problems using BX_READ_8BIT_REG()!\n"));
+ }
+
+ ax = AX;
+ cx = CX;
+ dx = DX;
+ bx = BX;
+ sp = SP;
+ bp = BP;
+ si = SI;
+ di = DI;
+
+ if ( ax != (EAX & 0xFFFF) ||
+ cx != (ECX & 0xFFFF) ||
+ dx != (EDX & 0xFFFF) ||
+ bx != (EBX & 0xFFFF) ||
+ sp != (ESP & 0xFFFF) ||
+ bp != (EBP & 0xFFFF) ||
+ si != (ESI & 0xFFFF) ||
+ di != (EDI & 0xFFFF) ) {
+ BX_PANIC(("problems using BX_READ_16BIT_REG()!\n"));
+ }
+
+
+ eax = EAX;
+ ecx = ECX;
+ edx = EDX;
+ ebx = EBX;
+ esp = ESP;
+ ebp = EBP;
+ esi = ESI;
+ edi = EDI;
+
+
+ if (sizeof(Bit8u) != 1 || sizeof(Bit8s) != 1)
+ BX_PANIC(("data type Bit8u or Bit8s is not of length 1 byte!\n"));
+ if (sizeof(Bit16u) != 2 || sizeof(Bit16s) != 2)
+ BX_PANIC(("data type Bit16u or Bit16s is not of length 2 bytes!\n"));
+ if (sizeof(Bit32u) != 4 || sizeof(Bit32s) != 4)
+ BX_PANIC(("data type Bit32u or Bit32s is not of length 4 bytes!\n"));
+
+ BX_DEBUG(( "#(%u)all sanity checks passed!\n", BX_SIM_ID ));
+}
+
+
+ void
+BX_CPU_C::set_INTR(Boolean value)
+{
+ BX_CPU_THIS_PTR INTR = value;
+ BX_CPU_THIS_PTR async_event = 1;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::INSB_YbDX(BxInstruction_t *i)
+{
+#if 0
+ Bit8u value8=0;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ if (i->as_32) {
+ // Write a zero to memory, to trigger any segment or page
+ // faults before reading from IO port.
+ write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
+
+ value8 = BX_INP(DX, 1);
+
+ /* no seg override possible */
+ write_virtual_byte(BX_SEG_REG_ES, EDI, &value8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ EDI = EDI - 1;
+ }
+ else {
+ EDI = EDI + 1;
+ }
+ }
+ else {
+ // Write a zero to memory, to trigger any segment or page
+ // faults before reading from IO port.
+ write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
+
+ value8 = BX_INP(DX, 1);
+
+ /* no seg override possible */
+ write_virtual_byte(BX_SEG_REG_ES, DI, &value8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ DI = DI - 1;
+ }
+ else {
+ DI = DI + 1;
+ }
+ }
+#endif
+}
+
+ void
+BX_CPU_C::INSW_YvDX(BxInstruction_t *i)
+ // input word/doubleword from port to string
+{
+#if 0
+ Bit32u edi;
+ unsigned int incr;
+
+ if (i->as_32)
+ edi = EDI;
+ else
+ edi = DI;
+
+ if (i->os_32) {
+ Bit32u value32=0;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ // Write a zero to memory, to trigger any segment or page
+ // faults before reading from IO port.
+ write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
+
+ value32 = BX_INP(DX, 4);
+
+ /* no seg override allowed */
+ write_virtual_dword(BX_SEG_REG_ES, edi, &value32);
+ incr = 4;
+ }
+ else {
+ Bit16u value16=0;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ // Write a zero to memory, to trigger any segment or page
+ // faults before reading from IO port.
+ write_virtual_word(BX_SEG_REG_ES, edi, &value16);
+
+ value16 = BX_INP(DX, 2);
+
+ /* no seg override allowed */
+ write_virtual_word(BX_SEG_REG_ES, edi, &value16);
+ incr = 2;
+ }
+
+ if (i->as_32) {
+ if (BX_CPU_THIS_PTR eflags.df)
+ EDI = EDI - incr;
+ else
+ EDI = EDI + incr;
+ }
+ else {
+ if (BX_CPU_THIS_PTR eflags.df)
+ DI = DI - incr;
+ else
+ DI = DI + incr;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::OUTSB_DXXb(BxInstruction_t *i)
+{
+#if 0
+ unsigned seg;
+ Bit8u value8;
+ Bit32u esi;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 1) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+ if (i->as_32)
+ esi = ESI;
+ else
+ esi = SI;
+
+ read_virtual_byte(seg, esi, &value8);
+
+ BX_OUTP(DX, value8, 1);
+
+ if (i->as_32) {
+ if (BX_CPU_THIS_PTR eflags.df)
+ ESI -= 1;
+ else
+ ESI += 1;
+ }
+ else {
+ if (BX_CPU_THIS_PTR eflags.df)
+ SI -= 1;
+ else
+ SI += 1;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::OUTSW_DXXv(BxInstruction_t *i)
+ // output word/doubleword string to port
+{
+#if 0
+ unsigned seg;
+ Bit32u esi;
+ unsigned int incr;
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+ if (i->as_32)
+ esi = ESI;
+ else
+ esi = SI;
+
+ if (i->os_32) {
+ Bit32u value32;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 4) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ read_virtual_dword(seg, esi, &value32);
+
+ BX_OUTP(DX, value32, 4);
+ incr = 4;
+ }
+ else {
+ Bit16u value16;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(DX, 2) ) {
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+ read_virtual_word(seg, esi, &value16);
+
+ BX_OUTP(DX, value16, 2);
+ incr = 2;
+ }
+
+ if (i->as_32) {
+ if (BX_CPU_THIS_PTR eflags.df)
+ ESI = ESI - incr;
+ else
+ ESI = ESI + incr;
+ }
+ else {
+ if (BX_CPU_THIS_PTR eflags.df)
+ SI = SI - incr;
+ else
+ SI = SI + incr;
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::IN_ALIb(BxInstruction_t *i)
+{
+ Bit8u al, imm8;
+
+ imm8 = i->Ib;
+
+ al = BX_CPU_THIS_PTR inp8(imm8);
+
+ AL = al;
+}
+
+ void
+BX_CPU_C::IN_eAXIb(BxInstruction_t *i)
+{
+ Bit8u imm8;
+
+
+ imm8 = i->Ib;
+
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ Bit32u eax;
+
+ eax = BX_CPU_THIS_PTR inp32(imm8);
+ EAX = eax;
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ {
+ Bit16u ax;
+
+ ax = BX_CPU_THIS_PTR inp16(imm8);
+ AX = ax;
+ }
+}
+
+ void
+BX_CPU_C::OUT_IbAL(BxInstruction_t *i)
+{
+ Bit8u al, imm8;
+
+ imm8 = i->Ib;
+
+ al = AL;
+
+ BX_CPU_THIS_PTR outp8(imm8, al);
+}
+
+ void
+BX_CPU_C::OUT_IbeAX(BxInstruction_t *i)
+{
+ Bit8u imm8;
+
+ imm8 = i->Ib;
+
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ BX_CPU_THIS_PTR outp32(imm8, EAX);
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ {
+ BX_CPU_THIS_PTR outp16(imm8, AX);
+ }
+}
+
+ void
+BX_CPU_C::IN_ALDX(BxInstruction_t *i)
+{
+ Bit8u al;
+
+ al = BX_CPU_THIS_PTR inp8(DX);
+
+ AL = al;
+}
+
+ void
+BX_CPU_C::IN_eAXDX(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ Bit32u eax;
+
+ eax = BX_CPU_THIS_PTR inp32(DX);
+ EAX = eax;
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ {
+ Bit16u ax;
+
+ ax = BX_CPU_THIS_PTR inp16(DX);
+ AX = ax;
+ }
+}
+
+ void
+BX_CPU_C::OUT_DXAL(BxInstruction_t *i)
+{
+ Bit16u dx;
+ Bit8u al;
+
+ dx = DX;
+ al = AL;
+
+ BX_CPU_THIS_PTR outp8(dx, al);
+}
+
+ void
+BX_CPU_C::OUT_DXeAX(BxInstruction_t *i)
+{
+ Bit16u dx;
+
+ dx = DX;
+
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ BX_CPU_THIS_PTR outp32(dx, EAX);
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ {
+ BX_CPU_THIS_PTR outp16(dx, AX);
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ Bit16u
+BX_CPU_C::inp16(Bit16u addr)
+{
+#if 0
+ Bit16u ret16;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
+ // BX_INFO(("cpu_inp16: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return(0);
+ }
+ }
+
+ ret16 = BX_INP(addr, 2);
+ return( ret16 );
+#endif
+ return 0;
+}
+
+ void
+BX_CPU_C::outp16(Bit16u addr, Bit16u value)
+{
+#if 0
+ /* If CPL <= IOPL, then all IO addresses are accessible.
+ * Otherwise, must check the IO permission map on >286.
+ * On the 286, there is no IO permissions map */
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 2) ) {
+ // BX_INFO(("cpu_outp16: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ BX_OUTP(addr, value, 2);
+#endif
+}
+
+ Bit32u
+BX_CPU_C::inp32(Bit16u addr)
+{
+#if 0
+ Bit32u ret32;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
+ // BX_INFO(("cpu_inp32: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return(0);
+ }
+ }
+
+ ret32 = BX_INP(addr, 4);
+ return( ret32 );
+#endif
+ return 0;
+}
+
+ void
+BX_CPU_C::outp32(Bit16u addr, Bit32u value)
+{
+#if 0
+ /* If CPL <= IOPL, then all IO addresses are accessible.
+ * Otherwise, must check the IO permission map on >286.
+ * On the 286, there is no IO permissions map */
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 4) ) {
+ // BX_INFO(("cpu_outp32: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ BX_OUTP(addr, value, 4);
+#endif
+}
+
+ Bit8u
+BX_CPU_C::inp8(Bit16u addr)
+{
+#if 0
+ Bit8u ret8;
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
+ // BX_INFO(("cpu_inp8: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return(0);
+ }
+ }
+
+ ret8 = BX_INP(addr, 1);
+ return( ret8 );
+#endif
+ return 0;
+}
+
+
+ void
+BX_CPU_C::outp8(Bit16u addr, Bit8u value)
+{
+#if 0
+ /* If CPL <= IOPL, then all IO addresses are accessible.
+ * Otherwise, must check the IO permission map on >286.
+ * On the 286, there is no IO permissions map */
+
+ if (BX_CPU_THIS_PTR cr0.pe && (BX_CPU_THIS_PTR eflags.vm || (CPL>IOPL))) {
+ if ( !BX_CPU_THIS_PTR allow_io(addr, 1) ) {
+ // BX_INFO(("cpu_outp8: GP0()!\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ BX_OUTP(addr, value, 1);
+#endif
+}
+
+
+ Boolean
+BX_CPU_C::allow_io(Bit16u addr, unsigned len)
+{
+#if 0
+ Bit16u io_base, permission16;
+ unsigned bit_index, i;
+
+ if (BX_CPU_THIS_PTR tr.cache.valid==0 || BX_CPU_THIS_PTR tr.cache.type!=9) {
+ BX_INFO(("allow_io(): TR doesn't point to a valid 32bit TSS\n"));
+ return(0);
+ }
+
+ if (BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled < 103) {
+ BX_PANIC(("allow_io(): TR.limit < 103\n"));
+ }
+
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + 102, 2, 0, BX_READ,
+ &io_base);
+ if (io_base <= 103) {
+BX_INFO(("PE is %u\n", BX_CPU_THIS_PTR cr0.pe));
+BX_INFO(("VM is %u\n", BX_CPU_THIS_PTR eflags.vm));
+BX_INFO(("CPL is %u\n", CPL));
+BX_INFO(("IOPL is %u\n", IOPL));
+BX_INFO(("addr is %u\n", addr));
+BX_INFO(("len is %u\n", len));
+ BX_PANIC(("allow_io(): TR:io_base <= 103\n"));
+ }
+
+ if (io_base > BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled) {
+ BX_INFO(("allow_io(): CPL > IOPL: no IO bitmap defined #GP(0)\n"));
+ return(0);
+ }
+
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base + io_base + addr/8,
+ 2, 0, BX_READ, &permission16);
+
+ bit_index = addr & 0x07;
+ permission16 >>= bit_index;
+ for (i=0; i<len; i++) {
+ if (permission16 & 0x01)
+ return(0);
+ permission16 >>= 1;
+ }
+#endif
+
+ return(1);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+
+ Boolean
+BX_CPU_C::get_CF(void)
+{
+ switch ( BX_CPU_THIS_PTR lf_flags_status & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR eflags.cf);
+
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_XADD8:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_8 <
+ BX_CPU_THIS_PTR oszapc.op1_8);
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_XADD16:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_16 <
+ BX_CPU_THIS_PTR oszapc.op1_16);
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_XADD32:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.result_32 <
+ BX_CPU_THIS_PTR oszapc.op1_32);
+ break;
+ case BX_INSTR_ADC8:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.result_8 <
+ BX_CPU_THIS_PTR oszapc.op1_8) ||
+ (BX_CPU_THIS_PTR oszapc.prev_CF &&
+ BX_CPU_THIS_PTR oszapc.result_8 ==
+ BX_CPU_THIS_PTR oszapc.op1_8);
+ break;
+ case BX_INSTR_ADC16:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.result_16 <
+ BX_CPU_THIS_PTR oszapc.op1_16) ||
+ (BX_CPU_THIS_PTR oszapc.prev_CF &&
+ BX_CPU_THIS_PTR oszapc.result_16 ==
+ BX_CPU_THIS_PTR oszapc.op1_16);
+ break;
+ case BX_INSTR_ADC32:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.result_32 <
+ BX_CPU_THIS_PTR oszapc.op1_32) ||
+ (BX_CPU_THIS_PTR oszapc.prev_CF &&
+ BX_CPU_THIS_PTR oszapc.result_32 ==
+ BX_CPU_THIS_PTR oszapc.op1_32);
+ break;
+ case BX_INSTR_SUB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_8 <
+ BX_CPU_THIS_PTR oszapc.op2_8);
+ break;
+ case BX_INSTR_SUB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_16 <
+ BX_CPU_THIS_PTR oszapc.op2_16);
+ break;
+ case BX_INSTR_SUB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ BX_CPU_THIS_PTR eflags.cf = (BX_CPU_THIS_PTR oszapc.op1_32 <
+ BX_CPU_THIS_PTR oszapc.op2_32);
+ break;
+ case BX_INSTR_SBB8:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_8 <
+ BX_CPU_THIS_PTR oszapc.result_8) ||
+ ((BX_CPU_THIS_PTR oszapc.op2_8==0xff) &&
+ BX_CPU_THIS_PTR oszapc.prev_CF);
+ break;
+ case BX_INSTR_SBB16:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_16 <
+ BX_CPU_THIS_PTR oszapc.result_16) ||
+ ((BX_CPU_THIS_PTR oszapc.op2_16==0xffff) &&
+ BX_CPU_THIS_PTR oszapc.prev_CF);
+ break;
+ case BX_INSTR_SBB32:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_32 <
+ BX_CPU_THIS_PTR oszapc.result_32) ||
+ ((BX_CPU_THIS_PTR oszapc.op2_32==0xffffffff) &&
+ BX_CPU_THIS_PTR oszapc.prev_CF);
+ break;
+ case BX_INSTR_NEG8:
+ BX_CPU_THIS_PTR eflags.cf =
+ BX_CPU_THIS_PTR oszapc.op1_8 != 0;
+ break;
+ case BX_INSTR_NEG16:
+ BX_CPU_THIS_PTR eflags.cf =
+ BX_CPU_THIS_PTR oszapc.op1_16 != 0;
+ break;
+ case BX_INSTR_NEG32:
+ BX_CPU_THIS_PTR eflags.cf =
+ BX_CPU_THIS_PTR oszapc.op1_32 != 0;
+ break;
+ case BX_INSTR_OR8:
+ case BX_INSTR_OR16:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND8:
+ case BX_INSTR_AND16:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_XOR32:
+ BX_CPU_THIS_PTR eflags.cf = 0;
+ break;
+ case BX_INSTR_SHR8:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_8 >>
+ (BX_CPU_THIS_PTR oszapc.op2_8 - 1)) & 0x01;
+ break;
+ case BX_INSTR_SHR16:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_16 >>
+ (BX_CPU_THIS_PTR oszapc.op2_16 - 1)) & 0x01;
+ break;
+ case BX_INSTR_SHR32:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_32 >>
+ (BX_CPU_THIS_PTR oszapc.op2_32 - 1)) & 0x01;
+ break;
+ case BX_INSTR_SHL8:
+ if (BX_CPU_THIS_PTR oszapc.op2_8 <= 8) {
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_8 >>
+ (8 - BX_CPU_THIS_PTR oszapc.op2_8)) & 0x01;
+ }
+ else {
+ BX_CPU_THIS_PTR eflags.cf = 0;
+ }
+ break;
+ case BX_INSTR_SHL16:
+ if (BX_CPU_THIS_PTR oszapc.op2_16 <= 16) {
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_16 >>
+ (16 - BX_CPU_THIS_PTR oszapc.op2_16)) & 0x01;
+ }
+ else {
+ BX_CPU_THIS_PTR eflags.cf = 0;
+ }
+ break;
+ case BX_INSTR_SHL32:
+ BX_CPU_THIS_PTR eflags.cf =
+ (BX_CPU_THIS_PTR oszapc.op1_32 >>
+ (32 - BX_CPU_THIS_PTR oszapc.op2_32)) & 0x01;
+ break;
+ default:
+ BX_PANIC(("get_CF: OSZAPC: unknown instr %u\n",
+ (unsigned) BX_CPU_THIS_PTR oszapc.instr));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xfffff0;
+ return(BX_CPU_THIS_PTR eflags.cf);
+
+ default:
+ BX_PANIC(("get_CF: unknown case\n"));
+ return(0);
+ }
+}
+
+
+ Boolean
+BX_CPU_C::get_AF(void)
+{
+ switch ( (BX_CPU_THIS_PTR lf_flags_status>>8) & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR eflags.af);
+
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_ADC8:
+ case BX_INSTR_SUB8:
+ case BX_INSTR_SBB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_XADD8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ BX_CPU_THIS_PTR eflags.af =
+ ((BX_CPU_THIS_PTR oszapc.op1_8 ^
+ BX_CPU_THIS_PTR oszapc.op2_8) ^
+ BX_CPU_THIS_PTR oszapc.result_8) & 0x10;
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_ADC16:
+ case BX_INSTR_SUB16:
+ case BX_INSTR_SBB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_XADD16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ BX_CPU_THIS_PTR eflags.af =
+ ((BX_CPU_THIS_PTR oszapc.op1_16 ^
+ BX_CPU_THIS_PTR oszapc.op2_16) ^
+ BX_CPU_THIS_PTR oszapc.result_16) & 0x10;
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_ADC32:
+ case BX_INSTR_SUB32:
+ case BX_INSTR_SBB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_XADD32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ BX_CPU_THIS_PTR eflags.af =
+ ((BX_CPU_THIS_PTR oszapc.op1_32 ^
+ BX_CPU_THIS_PTR oszapc.op2_32) ^
+ BX_CPU_THIS_PTR oszapc.result_32) & 0x10;
+ break;
+ case BX_INSTR_NEG8:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszapc.op1_8 & 0x0f) > 0;
+ break;
+ case BX_INSTR_NEG16:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszapc.op1_16 & 0x0f) > 0;
+ break;
+ case BX_INSTR_NEG32:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszapc.op1_32 & 0x0f) > 0;
+ break;
+ case BX_INSTR_OR8:
+ case BX_INSTR_OR16:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND8:
+ case BX_INSTR_AND16:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_XOR32:
+ case BX_INSTR_SHR8:
+ case BX_INSTR_SHR16:
+ case BX_INSTR_SHR32:
+ case BX_INSTR_SHL8:
+ case BX_INSTR_SHL16:
+ case BX_INSTR_SHL32:
+ BX_CPU_THIS_PTR eflags.af = 0;
+ /* undefined */
+ break;
+ default:
+ BX_PANIC(("get_AF: OSZAPC: unknown instr %u\n",
+ (unsigned) BX_CPU_THIS_PTR oszapc.instr));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+ return(BX_CPU_THIS_PTR eflags.af);
+
+ case BX_LF_INDEX_OSZAP:
+ switch (BX_CPU_THIS_PTR oszap.instr) {
+ case BX_INSTR_INC8:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_8 & 0x0f) == 0;
+ break;
+ case BX_INSTR_INC16:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_16 & 0x0f) == 0;
+ break;
+ case BX_INSTR_INC32:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_32 & 0x0f) == 0;
+ break;
+ case BX_INSTR_DEC8:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_8 & 0x0f) == 0x0f;
+ break;
+ case BX_INSTR_DEC16:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_16 & 0x0f) == 0x0f;
+ break;
+ case BX_INSTR_DEC32:
+ BX_CPU_THIS_PTR eflags.af =
+ (BX_CPU_THIS_PTR oszap.result_32 & 0x0f) == 0x0f;
+ break;
+ default:
+ BX_PANIC(("get_AF: OSZAP: unknown instr %u\n",
+ (unsigned) BX_CPU_THIS_PTR oszap.instr));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xfff0ff;
+ return(BX_CPU_THIS_PTR eflags.af);
+
+ default:
+ BX_PANIC(("get_AF: unknown case\n"));
+ return(0);
+ }
+}
+
+
+ Boolean
+BX_CPU_C::get_ZF(void)
+{
+ switch ( (BX_CPU_THIS_PTR lf_flags_status>>12) & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR eflags.zf);
+
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_ADC8:
+ case BX_INSTR_SUB8:
+ case BX_INSTR_SBB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_NEG8:
+ case BX_INSTR_XADD8:
+ case BX_INSTR_OR8:
+ case BX_INSTR_AND8:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ case BX_INSTR_SHR8:
+ case BX_INSTR_SHL8:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_8 == 0);
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_ADC16:
+ case BX_INSTR_SUB16:
+ case BX_INSTR_SBB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_NEG16:
+ case BX_INSTR_XADD16:
+ case BX_INSTR_OR16:
+ case BX_INSTR_AND16:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ case BX_INSTR_SHR16:
+ case BX_INSTR_SHL16:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_16 == 0);
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_ADC32:
+ case BX_INSTR_SUB32:
+ case BX_INSTR_SBB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_NEG32:
+ case BX_INSTR_XADD32:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ case BX_INSTR_SHR32:
+ case BX_INSTR_SHL32:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszapc.result_32 == 0);
+ break;
+ default:
+ BX_PANIC(("get_ZF: OSZAPC: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+ return(BX_CPU_THIS_PTR eflags.zf);
+
+ case BX_LF_INDEX_OSZAP:
+ switch (BX_CPU_THIS_PTR oszap.instr) {
+ case BX_INSTR_INC8:
+ case BX_INSTR_DEC8:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_8 == 0);
+ break;
+ case BX_INSTR_INC16:
+ case BX_INSTR_DEC16:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_16 == 0);
+ break;
+ case BX_INSTR_INC32:
+ case BX_INSTR_DEC32:
+ BX_CPU_THIS_PTR eflags.zf = (BX_CPU_THIS_PTR oszap.result_32 == 0);
+ break;
+ default:
+ BX_PANIC(("get_ZF: OSZAP: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xff0fff;
+ return(BX_CPU_THIS_PTR eflags.zf);
+
+ default:
+ BX_PANIC(("get_ZF: unknown case\n"));
+ return(0);
+ }
+}
+
+
+ Boolean
+BX_CPU_C::get_SF(void)
+{
+ switch ( (BX_CPU_THIS_PTR lf_flags_status>>16) & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR eflags.sf);
+
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_ADC8:
+ case BX_INSTR_SUB8:
+ case BX_INSTR_SBB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_NEG8:
+ case BX_INSTR_XADD8:
+ case BX_INSTR_OR8:
+ case BX_INSTR_AND8:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ case BX_INSTR_SHR8:
+ case BX_INSTR_SHL8:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszapc.result_8 >= 0x80);
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_ADC16:
+ case BX_INSTR_SUB16:
+ case BX_INSTR_SBB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_NEG16:
+ case BX_INSTR_XADD16:
+ case BX_INSTR_OR16:
+ case BX_INSTR_AND16:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ case BX_INSTR_SHR16:
+ case BX_INSTR_SHL16:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszapc.result_16 >= 0x8000);
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_ADC32:
+ case BX_INSTR_SUB32:
+ case BX_INSTR_SBB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_NEG32:
+ case BX_INSTR_XADD32:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ case BX_INSTR_SHR32:
+ case BX_INSTR_SHL32:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszapc.result_32 >= 0x80000000);
+ break;
+ default:
+ BX_PANIC(("get_SF: OSZAPC: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+ return(BX_CPU_THIS_PTR eflags.sf);
+
+ case BX_LF_INDEX_OSZAP:
+ switch (BX_CPU_THIS_PTR oszap.instr) {
+ case BX_INSTR_INC8:
+ case BX_INSTR_DEC8:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszap.result_8 >= 0x80);
+ break;
+ case BX_INSTR_INC16:
+ case BX_INSTR_DEC16:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszap.result_16 >= 0x8000);
+ break;
+ case BX_INSTR_INC32:
+ case BX_INSTR_DEC32:
+ BX_CPU_THIS_PTR eflags.sf =
+ (BX_CPU_THIS_PTR oszap.result_32 >= 0x80000000);
+ break;
+ default:
+ BX_PANIC(("get_SF: OSZAP: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xf0ffff;
+ return(BX_CPU_THIS_PTR eflags.sf);
+
+ default:
+ BX_PANIC(("get_SF: unknown case\n"));
+ return(0);
+ }
+}
+
+ Boolean
+BX_CPU_C::get_OF(void)
+{
+ Bit8u op1_b7, op2_b7, result_b7;
+ Bit16u op1_b15, op2_b15, result_b15;
+ Bit32u op1_b31, op2_b31, result_b31;
+
+ switch ( (BX_CPU_THIS_PTR lf_flags_status>>20) & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR eflags.of);
+
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_ADC8:
+ case BX_INSTR_XADD8:
+ op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
+ op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
+ result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b7 == op2_b7) && (result_b7 ^ op2_b7);
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_ADC16:
+ case BX_INSTR_XADD16:
+ op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
+ op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
+ result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b15 == op2_b15) && (result_b15 ^ op2_b15);
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_ADC32:
+ case BX_INSTR_XADD32:
+ op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
+ op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
+ result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b31 == op2_b31) && (result_b31 ^ op2_b31);
+ break;
+ case BX_INSTR_SUB8:
+ case BX_INSTR_SBB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ op1_b7 = BX_CPU_THIS_PTR oszapc.op1_8 & 0x80;
+ op2_b7 = BX_CPU_THIS_PTR oszapc.op2_8 & 0x80;
+ result_b7 = BX_CPU_THIS_PTR oszapc.result_8 & 0x80;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b7 ^ op2_b7) && (op1_b7 ^ result_b7);
+ break;
+ case BX_INSTR_SUB16:
+ case BX_INSTR_SBB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ op1_b15 = BX_CPU_THIS_PTR oszapc.op1_16 & 0x8000;
+ op2_b15 = BX_CPU_THIS_PTR oszapc.op2_16 & 0x8000;
+ result_b15 = BX_CPU_THIS_PTR oszapc.result_16 & 0x8000;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b15 ^ op2_b15) && (op1_b15 ^ result_b15);
+ break;
+ case BX_INSTR_SUB32:
+ case BX_INSTR_SBB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ op1_b31 = BX_CPU_THIS_PTR oszapc.op1_32 & 0x80000000;
+ op2_b31 = BX_CPU_THIS_PTR oszapc.op2_32 & 0x80000000;
+ result_b31 = BX_CPU_THIS_PTR oszapc.result_32 & 0x80000000;
+
+ BX_CPU_THIS_PTR eflags.of = (op1_b31 ^ op2_b31) && (op1_b31 ^ result_b31);
+ break;
+ case BX_INSTR_NEG8:
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_8 == 0x80);
+ break;
+ case BX_INSTR_NEG16:
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_16 == 0x8000);
+ break;
+ case BX_INSTR_NEG32:
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_32 == 0x80000000);
+ break;
+ case BX_INSTR_OR8:
+ case BX_INSTR_OR16:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND8:
+ case BX_INSTR_AND16:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_XOR32:
+ BX_CPU_THIS_PTR eflags.of = 0;
+ break;
+ case BX_INSTR_SHR8:
+ if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_8 >= 0x80);
+ break;
+ case BX_INSTR_SHR16:
+ if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_16 >= 0x8000);
+ break;
+ case BX_INSTR_SHR32:
+ if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ (BX_CPU_THIS_PTR oszapc.op1_32 >= 0x80000000);
+ break;
+ case BX_INSTR_SHL8:
+ if (BX_CPU_THIS_PTR oszapc.op2_8 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ ((BX_CPU_THIS_PTR oszapc.op1_8 ^
+ BX_CPU_THIS_PTR oszapc.result_8) & 0x80) > 0;
+ break;
+ case BX_INSTR_SHL16:
+ if (BX_CPU_THIS_PTR oszapc.op2_16 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ ((BX_CPU_THIS_PTR oszapc.op1_16 ^
+ BX_CPU_THIS_PTR oszapc.result_16) & 0x8000) > 0;
+ break;
+ case BX_INSTR_SHL32:
+ if (BX_CPU_THIS_PTR oszapc.op2_32 == 1)
+ BX_CPU_THIS_PTR eflags.of =
+ ((BX_CPU_THIS_PTR oszapc.op1_32 ^
+ BX_CPU_THIS_PTR oszapc.result_32) & 0x80000000) > 0;
+ break;
+ default:
+ BX_PANIC(("get_OF: OSZAPC: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+ return(BX_CPU_THIS_PTR eflags.of);
+
+ case BX_LF_INDEX_OSZAP:
+ switch (BX_CPU_THIS_PTR oszap.instr) {
+ case BX_INSTR_INC8:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_8 == 0x80;
+ break;
+ case BX_INSTR_INC16:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_16 == 0x8000;
+ break;
+ case BX_INSTR_INC32:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_32 == 0x80000000;
+ break;
+ case BX_INSTR_DEC8:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_8 == 0x7F;
+ break;
+ case BX_INSTR_DEC16:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_16 == 0x7FFF;
+ break;
+ case BX_INSTR_DEC32:
+ BX_CPU_THIS_PTR eflags.of =
+ BX_CPU_THIS_PTR oszap.result_32 == 0x7FFFFFFF;
+ break;
+ default:
+ BX_PANIC(("get_OF: OSZAP: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0x0fffff;
+ return(BX_CPU_THIS_PTR eflags.of);
+
+ default:
+ BX_PANIC(("get_OF: unknown case\n"));
+ return(0);
+ }
+}
+
+ Boolean
+BX_CPU_C::get_PF(void)
+{
+ switch ( (BX_CPU_THIS_PTR lf_flags_status>>4) & 0x00000f ) {
+ case BX_LF_INDEX_KNOWN:
+ return(BX_CPU_THIS_PTR lf_pf);
+ case BX_LF_INDEX_OSZAPC:
+ switch (BX_CPU_THIS_PTR oszapc.instr) {
+ case BX_INSTR_ADD8:
+ case BX_INSTR_ADC8:
+ case BX_INSTR_SUB8:
+ case BX_INSTR_SBB8:
+ case BX_INSTR_CMP8:
+ case BX_INSTR_NEG8:
+ case BX_INSTR_XADD8:
+ case BX_INSTR_OR8:
+ case BX_INSTR_AND8:
+ case BX_INSTR_TEST8:
+ case BX_INSTR_XOR8:
+ case BX_INSTR_CMPS8:
+ case BX_INSTR_SCAS8:
+ case BX_INSTR_SHR8:
+ case BX_INSTR_SHL8:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[BX_CPU_THIS_PTR oszapc.result_8];
+ break;
+ case BX_INSTR_ADD16:
+ case BX_INSTR_ADC16:
+ case BX_INSTR_SUB16:
+ case BX_INSTR_SBB16:
+ case BX_INSTR_CMP16:
+ case BX_INSTR_NEG16:
+ case BX_INSTR_XADD16:
+ case BX_INSTR_OR16:
+ case BX_INSTR_AND16:
+ case BX_INSTR_TEST16:
+ case BX_INSTR_XOR16:
+ case BX_INSTR_CMPS16:
+ case BX_INSTR_SCAS16:
+ case BX_INSTR_SHR16:
+ case BX_INSTR_SHL16:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_16];
+ break;
+ case BX_INSTR_ADD32:
+ case BX_INSTR_ADC32:
+ case BX_INSTR_SUB32:
+ case BX_INSTR_SBB32:
+ case BX_INSTR_CMP32:
+ case BX_INSTR_NEG32:
+ case BX_INSTR_XADD32:
+ case BX_INSTR_OR32:
+ case BX_INSTR_AND32:
+ case BX_INSTR_TEST32:
+ case BX_INSTR_XOR32:
+ case BX_INSTR_CMPS32:
+ case BX_INSTR_SCAS32:
+ case BX_INSTR_SHR32:
+ case BX_INSTR_SHL32:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszapc.result_32];
+ break;
+ default:
+ BX_PANIC(("get_PF: OSZAPC: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+ return(BX_CPU_THIS_PTR lf_pf);
+
+ case BX_LF_INDEX_OSZAP:
+ switch (BX_CPU_THIS_PTR oszap.instr) {
+ case BX_INSTR_INC8:
+ case BX_INSTR_DEC8:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[BX_CPU_THIS_PTR oszap.result_8];
+ break;
+ case BX_INSTR_INC16:
+ case BX_INSTR_DEC16:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszap.result_16];
+ break;
+ case BX_INSTR_INC32:
+ case BX_INSTR_DEC32:
+ BX_CPU_THIS_PTR lf_pf =
+ bx_parity_lookup[(Bit8u) BX_CPU_THIS_PTR oszap.result_32];
+ break;
+ default:
+ BX_PANIC(("get_PF: OSZAP: unknown instr\n"));
+ }
+ BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+ return(BX_CPU_THIS_PTR lf_pf);
+
+ case BX_LF_INDEX_P:
+ BX_CPU_THIS_PTR lf_pf = bx_parity_lookup[BX_CPU_THIS_PTR eflags.pf_byte];
+ BX_CPU_THIS_PTR lf_flags_status &= 0xffff0f;
+ return(BX_CPU_THIS_PTR lf_pf);
+
+ default:
+ BX_PANIC(("get_PF: unknown case\n"));
+ return(0);
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#if BX_PROVIDE_CPU_MEMORY==1
+
+#define BX_INSTR_ADD8 1
+#define BX_INSTR_ADD16 2
+#define BX_INSTR_ADD32 3
+
+#define BX_INSTR_SUB8 4
+#define BX_INSTR_SUB16 5
+#define BX_INSTR_SUB32 6
+
+#define BX_INSTR_ADC8 7
+#define BX_INSTR_ADC16 8
+#define BX_INSTR_ADC32 9
+
+#define BX_INSTR_SBB8 10
+#define BX_INSTR_SBB16 11
+#define BX_INSTR_SBB32 12
+
+#define BX_INSTR_CMP8 13
+#define BX_INSTR_CMP16 14
+#define BX_INSTR_CMP32 15
+
+#define BX_INSTR_INC8 16
+#define BX_INSTR_INC16 17
+#define BX_INSTR_INC32 18
+
+#define BX_INSTR_DEC8 19
+#define BX_INSTR_DEC16 20
+#define BX_INSTR_DEC32 21
+
+#define BX_INSTR_NEG8 22
+#define BX_INSTR_NEG16 23
+#define BX_INSTR_NEG32 24
+
+#define BX_INSTR_XADD8 25
+#define BX_INSTR_XADD16 26
+#define BX_INSTR_XADD32 27
+
+#define BX_INSTR_OR8 28
+#define BX_INSTR_OR16 29
+#define BX_INSTR_OR32 30
+
+#define BX_INSTR_AND8 31
+#define BX_INSTR_AND16 32
+#define BX_INSTR_AND32 33
+
+#define BX_INSTR_TEST8 34
+#define BX_INSTR_TEST16 35
+#define BX_INSTR_TEST32 36
+
+#define BX_INSTR_XOR8 37
+#define BX_INSTR_XOR16 38
+#define BX_INSTR_XOR32 39
+
+#define BX_INSTR_CMPS8 40
+#define BX_INSTR_CMPS16 41
+#define BX_INSTR_CMPS32 42
+
+#define BX_INSTR_SCAS8 43
+#define BX_INSTR_SCAS16 44
+#define BX_INSTR_SCAS32 45
+
+#define BX_INSTR_SHR8 46
+#define BX_INSTR_SHR16 47
+#define BX_INSTR_SHR32 48
+
+#define BX_INSTR_SHL8 49
+#define BX_INSTR_SHL16 50
+#define BX_INSTR_SHL32 51
+
+
+
+#define BX_LF_INDEX_KNOWN 0
+#define BX_LF_INDEX_OSZAPC 1
+#define BX_LF_INDEX_OSZAP 2
+#define BX_LF_INDEX_P 3
+
+#define BX_LF_MASK_OSZAPC 0x111111
+#define BX_LF_MASK_OSZAP 0x222220
+#define BX_LF_MASK_P 0x000030
+
+
+typedef struct {
+ Bit8u op1_8;
+ Bit8u op2_8;
+ Bit8u result_8;
+
+ Bit16u op1_16;
+ Bit16u op2_16;
+ Bit16u result_16;
+
+ Bit32u op1_32;
+ Bit32u op2_32;
+ Bit32u result_32;
+
+ Boolean prev_CF;
+ unsigned instr;
+ } bx_lf_flags_entry;
+
+
+#endif /* BX_PROVIDE_CPU_MEMORY==1 */
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::XOR_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 ^ op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+ void
+BX_CPU_C::XOR_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, result_16;
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ result_16 = op1_16 ^ op2_16;
+
+ /* now write result back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+ void
+BX_CPU_C::XOR_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, sum_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ sum_16 = op1_16 ^ op2_16;
+
+ /* now write sum back to destination */
+ AX = sum_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_XOR16);
+}
+
+ void
+BX_CPU_C::XOR_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 ^ op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_XOR16);
+}
+
+
+ void
+BX_CPU_C::OR_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 | op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+ void
+BX_CPU_C::NOT_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = ~op1_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+}
+
+
+ void
+BX_CPU_C::OR_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 | op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+ void
+BX_CPU_C::OR_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, result_16;
+
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ result_16 = op1_16 | op2_16;
+
+ /* now write result back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_OR16);
+}
+
+
+ void
+BX_CPU_C::OR_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, sum_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ sum_16 = op1_16 | op2_16;
+
+ /* now write sum back to destination */
+ AX = sum_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_OR16);
+}
+
+
+
+ void
+BX_CPU_C::AND_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 & op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+ void
+BX_CPU_C::AND_GwEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, result_16;
+
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op2_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ result_16 = op1_16 & op2_16;
+
+ /* now write result back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, result_16);
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+ void
+BX_CPU_C::AND_AXIw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, sum_16;
+
+ op1_16 = AX;
+
+ op2_16 = i->Iw;
+
+ sum_16 = op1_16 & op2_16;
+
+ /* now write sum back to destination */
+ AX = sum_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, sum_16, BX_INSTR_AND16);
+}
+
+ void
+BX_CPU_C::AND_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 & op2_16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_AND16);
+}
+
+
+ void
+BX_CPU_C::TEST_EwGw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ /* op2_16 is a register, op2_addr is an index of a register */
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 & op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
+
+
+
+ void
+BX_CPU_C::TEST_AXIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+ op1_16 = AX;
+
+ /* op2_16 is imm16 */
+ op2_16 = i->Iw;
+
+ result_16 = op1_16 & op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
+
+
+ void
+BX_CPU_C::TEST_EwIw(BxInstruction_t *i)
+{
+ Bit16u op2_16, op1_16, result_16;
+
+
+ /* op2_16 is imm16 */
+ op2_16 = i->Iw;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ result_16 = op1_16 & op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, result_16, BX_INSTR_TEST16);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::XOR_EdGd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 ^ op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+ void
+BX_CPU_C::XOR_GdEd(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, result_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ result_32 = op1_32 ^ op2_32;
+
+ /* now write result back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+ void
+BX_CPU_C::XOR_EAXId(BxInstruction_t *i)
+{
+ /* for 32 bit operand size mode */
+ Bit32u op1_32, op2_32, sum_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ sum_32 = op1_32 ^ op2_32;
+
+ /* now write sum back to destination */
+ EAX = sum_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_XOR32);
+}
+
+ void
+BX_CPU_C::XOR_EdId(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 ^ op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_XOR32);
+}
+
+
+ void
+BX_CPU_C::OR_EdId(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 | op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+ void
+BX_CPU_C::NOT_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = ~op1_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+}
+
+
+ void
+BX_CPU_C::OR_EdGd(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 | op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+
+ void
+BX_CPU_C::OR_GdEd(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, result_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ result_32 = op1_32 | op2_32;
+
+ /* now write result back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_OR32);
+}
+
+
+ void
+BX_CPU_C::OR_EAXId(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, sum_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ sum_32 = op1_32 | op2_32;
+
+ /* now write sum back to destination */
+ EAX = sum_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_OR32);
+}
+
+
+
+ void
+BX_CPU_C::AND_EdGd(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 & op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+ void
+BX_CPU_C::AND_GdEd(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, result_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op2_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ result_32 = op1_32 & op2_32;
+
+ /* now write result back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, result_32);
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+ void
+BX_CPU_C::AND_EAXId(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, sum_32;
+
+ op1_32 = EAX;
+
+ op2_32 = i->Id;
+
+ sum_32 = op1_32 & op2_32;
+
+ /* now write sum back to destination */
+ EAX = sum_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, sum_32, BX_INSTR_AND32);
+}
+
+ void
+BX_CPU_C::AND_EdId(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 & op2_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_AND32);
+}
+
+
+ void
+BX_CPU_C::TEST_EdGd(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op2_32 is a register, op2_addr is an index of a register */
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 & op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
+
+
+
+ void
+BX_CPU_C::TEST_EAXId(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op1 is EAX register */
+ op1_32 = EAX;
+
+ /* op2 is imm32 */
+ op2_32 = i->Id;
+
+ result_32 = op1_32 & op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
+
+
+ void
+BX_CPU_C::TEST_EdId(BxInstruction_t *i)
+{
+ Bit32u op2_32, op1_32, result_32;
+
+ /* op2 is imm32 */
+ op2_32 = i->Id;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ result_32 = op1_32 & op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, result_32, BX_INSTR_TEST32);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+ void
+BX_CPU_C::XOR_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 ^ op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+ void
+BX_CPU_C::XOR_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, result;
+
+ op1 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ result = op1 ^ op2;
+
+ /* now write result back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, result);
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+
+ void
+BX_CPU_C::XOR_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+
+ op1 = AL;
+
+ op2 = i->Ib;
+
+ sum = op1 ^ op2;
+
+ /* now write sum back to destination, which is a register */
+ AL = sum;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_XOR8);
+}
+
+
+ void
+BX_CPU_C::XOR_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 ^ op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_XOR8);
+}
+
+
+
+ void
+BX_CPU_C::OR_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 | op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+ void
+BX_CPU_C::NOT_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ result_8 = ~op1_8;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+}
+
+
+ void
+BX_CPU_C::OR_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 | op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+ void
+BX_CPU_C::OR_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, result;
+
+
+ op1 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ result = op1 | op2;
+
+ /* now write result back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, result);
+
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_OR8);
+}
+
+
+ void
+BX_CPU_C::OR_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+
+
+ op1 = AL;
+
+ op2 = i->Ib;
+
+ sum = op1 | op2;
+
+ /* now write sum back to destination, which is a register */
+ AL = sum;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_OR8);
+}
+
+
+
+ void
+BX_CPU_C::AND_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 & op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+ void
+BX_CPU_C::AND_GbEb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, result;
+
+ op1 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ result = op1 & op2;
+
+ /* now write result back to destination, which is a register */
+ BX_WRITE_8BIT_REG(i->nnn, result);
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+ void
+BX_CPU_C::AND_ALIb(BxInstruction_t *i)
+{
+ Bit8u op1, op2, sum;
+
+
+ op1 = AL;
+
+ op2 = i->Ib;
+
+ sum = op1 & op2;
+
+ /* now write sum back to destination, which is a register */
+ AL = sum;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, sum, BX_INSTR_AND8);
+}
+
+
+
+
+ void
+BX_CPU_C::AND_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 & op2;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result);
+ }
+ else {
+ write_RMW_virtual_byte(result);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_AND8);
+}
+
+
+ void
+BX_CPU_C::TEST_EbGb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ /* op2 is a register, op2_addr is an index of a register */
+ op2 = BX_READ_8BIT_REG(i->nnn);
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 & op2;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
+
+
+ void
+BX_CPU_C::TEST_ALIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ /* op1 is the AL register */
+ op1 = AL;
+
+ /* op2 is imm8 */
+ op2 = i->Ib;
+
+ result = op1 & op2;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
+
+
+
+ void
+BX_CPU_C::TEST_EbIb(BxInstruction_t *i)
+{
+ Bit8u op2, op1, result;
+
+ op2 = i->Ib;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op1);
+ }
+
+ result = op1 & op2;
+
+ SET_FLAGS_OSZAPC_8(op1, op2, result, BX_INSTR_TEST8);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#include "bochs.h"
+#include <assert.h>
+#include "state_file.h"
+
+extern "C" {
+#include <signal.h>
+}
+
+#ifdef __MINGW32__
+void alarm(int);
+#endif
+
+
+#if BX_PROVIDE_DEVICE_MODELS==1
+// some prototypes from iodev/
+// I want to stay away from including iodev/iodev.h here
+Bit32u bx_unmapped_io_read_handler(Bit32u address, unsigned io_len);
+void bx_unmapped_io_write_handler(Bit32u address, Bit32u value,
+ unsigned io_len);
+void bx_close_harddrive(void);
+#endif
+
+
+
+void bx_init_debug(void);
+void bx_emulate_hga_dumps_timer(void);
+static char *divider = "========================================================================";
+
+
+/* typedefs */
+
+
+#if ( BX_PROVIDE_DEVICE_MODELS==1 )
+bx_pc_system_c bx_pc_system;
+class state_file state_stuff("state_file.out", "options");
+#endif
+
+bx_debug_t bx_dbg;
+
+bx_options_t bx_options = {
+ { "", BX_FLOPPY_NONE, BX_EJECTED }, // floppya
+ { "", BX_FLOPPY_NONE, BX_EJECTED }, // floppyb
+ { 0, "", 0, 0, 0 }, // diskc
+ { 0, "", 0, 0, 0 }, // diskd
+ { 0, "", 0 }, // cdromd
+ { NULL, 0 }, // rom
+ { NULL }, // vgarom
+ { BX_DEFAULT_MEM_MEGS }, // memory
+ { NULL, NULL, NULL, 0, 0, 0, 0 }, // SB16
+ "a", // boot drive
+ 300000, // vga update interval
+ 20000, // default keyboard serial path delay (usec)
+ 50000, // default floppy command delay (usec)
+ 500000, // default ips (instructions-per-second)
+ 0, // default mouse_enabled
+ 0, // default private_colormap
+ 0, // default i440FXSupport
+ {NULL, 0}, // cmos path, cmos image boolean
+ { 0, 0, 0, {0,0,0,0,0,0}, NULL, NULL }, // ne2k
+ 1, // newHardDriveSupport
+ { 0, NULL, NULL, NULL }, // load32bitOSImage hack stuff
+ {
+ ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL
+ } // ignore debugs, report infos and errors, fatal on panics.
+ };
+
+static char bochsrc_path[512];
+static char logfilename[512] = "-";
+
+
+static void parse_line_unformatted(char *line);
+static void parse_line_formatted(int num_params, char *params[]);
+static void parse_bochsrc(int argc);
+
+
+// Just for the iofunctions
+
+#define LOG_THIS this->log->
+
+int Allocio=0;
+
+void
+iofunctions::flush(void) {
+ if(logfd && magic == MAGIC_LOGNUM) {
+ fflush(logfd);
+ }
+}
+
+void
+iofunctions::init(void) {
+ // iofunctions methods must not be called before this magic
+ // number is set.
+ magic=MAGIC_LOGNUM;
+ showtick = 1;
+ n_logfn = 0;
+ init_log(stderr);
+ log = new logfunc_t(this);
+ LOG_THIS setprefix("[IO ]");
+ LOG_THIS settype(IOLOG);
+ BX_DEBUG(("Init(log file: '%s').\n",logfn));
+}
+
+void
+iofunctions::add_logfn (logfunc_t *fn)
+{
+ assert (n_logfn < MAX_LOGFNS);
+ logfn_list[n_logfn++] = fn;
+}
+
+void
+iofunctions::set_log_action (int loglevel, int action)
+{
+ for (int i=0; i<n_logfn; i++)
+ logfn_list[i]->setonoff(loglevel, action);
+}
+
+void
+iofunctions::init_log(char *fn)
+{
+ assert (magic==MAGIC_LOGNUM);
+ // use newfd/newfn so that we can log the message to the OLD log
+ // file descriptor.
+ FILE *newfd = stderr;
+ char *newfn = "/dev/stderr";
+ if( strcmp( fn, "-" ) != 0 ) {
+ newfd = fopen(fn, "w");
+ if(newfd != NULL) {
+ newfn = strdup(fn);
+ BX_DEBUG(("Opened log file '%s'.\n", fn ));
+ } else {
+ BX_DEBUG(("Log file '%s' not there?\n", fn));
+ newfd = NULL;
+ logfn = "(none)";
+ }
+ }
+ logfd = newfd;
+ logfn = newfn;
+}
+
+void
+iofunctions::init_log(FILE *fs)
+{
+ assert (magic==MAGIC_LOGNUM);
+ logfd = fs;
+
+ if(fs == stderr) {
+ logfn = "/dev/stderr";
+ } else if(fs == stdout) {
+ logfn = "/dev/stdout";
+ } else {
+ logfn = "(unknown)";
+ }
+}
+
+void
+iofunctions::init_log(int fd)
+{
+ assert (magic==MAGIC_LOGNUM);
+ FILE *tmpfd;
+ if( (tmpfd = fdopen(fd,"w")) == NULL ) {
+ BX_PANIC(("Couldn't open fd %d as a stream for writing\n", fd));
+ return;
+ }
+
+ init_log(tmpfd);
+ return;
+};
+
+// iofunctions::out( class, level, prefix, fmt, ap)
+// DO NOT nest out() from ::info() and the like.
+// fmt and ap retained for direct printinf from iofunctions only!
+
+void
+iofunctions::out(int f, int l, char *prefix, char *fmt, va_list ap)
+{
+ assert (magic==MAGIC_LOGNUM);
+ assert (this != NULL);
+ assert (logfd != NULL);
+
+#if BX_PROVIDE_DEVICE_MODELS
+ if( showtick )
+ fprintf(logfd, "%011lld ", bx_pc_system.time_ticks());
+#endif
+ if(prefix != NULL)
+ fprintf(logfd, "%s ", prefix);
+
+ if(l==LOGLEV_PANIC)
+ fprintf(logfd, ">>PANIC<< ");
+
+ vfprintf(logfd, fmt, ap);
+ fflush(logfd);
+
+ return;
+}
+
+iofunctions::iofunctions(FILE *fs)
+{
+ init();
+ init_log(fs);
+}
+
+iofunctions::iofunctions(char *fn)
+{
+ init();
+ init_log(fn);
+}
+
+iofunctions::iofunctions(int fd)
+{
+ init();
+ init_log(fd);
+}
+
+iofunctions::iofunctions(void)
+{
+ this->init();
+}
+
+iofunctions::~iofunctions(void)
+{
+ // flush before erasing magic number, or flush does nothing.
+ this->flush();
+ this->magic=0;
+}
+
+#undef LOG_THIS
+#define LOG_THIS genlog->
+
+logfunctions::logfunctions(void)
+{
+ setprefix("[ ]");
+ settype(GENLOG);
+ if(io == NULL && Allocio == 0) {
+ Allocio = 1;
+ io = new iofunc_t(stderr);
+ }
+ setio(io);
+ // BUG: unfortunately this can be called before the bochsrc is read,
+ // which means that the bochsrc has no effect on the actions.
+ for (int i=0; i<MAX_LOGLEV; i++)
+ onoff[i] = bx_options.log_actions[i];
+}
+
+logfunctions::logfunctions(iofunc_t *iofunc)
+{
+ setprefix("[ ]");
+ settype(GENLOG);
+ setio(iofunc);
+ // BUG: unfortunately this can be called before the bochsrc is read,
+ // which means that the bochsrc has no effect on the actions.
+ for (int i=0; i<MAX_LOGLEV; i++)
+ onoff[i] = bx_options.log_actions[i];
+}
+
+logfunctions::~logfunctions(void)
+{
+}
+
+void
+logfunctions::setio(iofunc_t *i)
+{
+ // add pointer to iofunction object to use
+ this->logio = i;
+ // give iofunction a pointer to me
+ i->add_logfn (this);
+}
+
+void
+logfunctions::setprefix(char *p)
+{
+ this->prefix=strdup(p);
+}
+
+void
+logfunctions::settype(int t)
+{
+ type=t;
+}
+
+void
+logfunctions::info(char *fmt, ...)
+{
+ va_list ap;
+ FILE *fs;
+
+ assert (this != NULL);
+ assert (this->logio != NULL);
+
+ if(!onoff[LOGLEV_INFO]) return;
+
+ va_start(ap, fmt);
+ this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap);
+ if (onoff[LOGLEV_INFO] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+ va_end(ap);
+
+}
+
+void
+logfunctions::error(char *fmt, ...)
+{
+ va_list ap;
+ FILE *fs;
+
+ assert (this != NULL);
+ assert (this->logio != NULL);
+
+ if(!onoff[LOGLEV_ERROR]) return;
+
+ va_start(ap, fmt);
+ this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap);
+ if (onoff[LOGLEV_ERROR] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+ va_end(ap);
+}
+
+void
+logfunctions::panic(char *fmt, ...)
+{
+ va_list ap;
+ FILE *fs;
+
+ assert (this != NULL);
+ assert (this->logio != NULL);
+
+ if(!onoff[LOGLEV_PANIC]) return;
+
+ va_start(ap, fmt);
+ this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap);
+ if (onoff[LOGLEV_PANIC] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+ va_end(ap);
+}
+
+void
+logfunctions::ldebug(char *fmt, ...)
+{
+ va_list ap;
+ FILE *fs;
+
+ assert (this != NULL);
+ assert (this->logio != NULL);
+
+ if(!onoff[LOGLEV_DEBUG]) return;
+
+ va_start(ap, fmt);
+ this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap);
+ if (onoff[LOGLEV_DEBUG] == ACT_FATAL) fatal (this->prefix, fmt, ap);
+ va_end(ap);
+}
+
+void
+logfunctions::fatal (char *prefix, char *fmt, va_list ap)
+{
+ static int fatal_reentry = 0;
+ if (fatal_reentry) return;
+ fatal_reentry++;
+ bx_atexit();
+ fprintf (stderr, "%s\n", divider);
+ fprintf (stderr, "Bochs is exiting with the following message:\n");
+ fprintf (stderr, "%s ", prefix);
+ vfprintf (stderr, fmt, ap);
+ fprintf (stderr, "%s\n", divider);
+#if 0 && defined(WIN32)
+#error disabled because it is not working yet!
+ // wait for a keypress before quitting. Depending on how bochs is
+ // installed, the console window can disappear before the user has
+ // a chance to read the final message.
+ fprintf (stderr, "\n\nPress Enter to exit...\n");
+ char buf[8];
+ fgets (buf, 8, stdin);
+#endif
+#if !BX_DEBUGGER
+ exit(1);
+#else
+ static Boolean dbg_exit_called = 0;
+ if (dbg_exit_called == 0) {
+ dbg_exit_called = 1;
+ bx_dbg_exit(1);
+ }
+#endif
+ fatal_reentry--;
+}
+
+iofunc_t *io = NULL;
+logfunc_t *genlog = NULL;
+
+void bx_center_print (FILE *file, char *line, int maxwidth)
+{
+ int imax;
+ imax = (maxwidth - strlen(line)) >> 1;
+ for (int i=0; i<imax; i++) fputc (' ', file);
+ fputs (line, file);
+}
+
+void bx_print_header ()
+{
+ fprintf (stderr, "%s\n", divider);
+ char buffer[128];
+ sprintf (buffer, "Bochs x86 Emulator %s\n", VER_STRING);
+ bx_center_print (stderr, buffer, 72);
+ if (REL_STRING[0]) {
+ sprintf (buffer, "%s\n", REL_STRING);
+ bx_center_print (stderr, buffer, 72);
+ }
+ fprintf (stderr, "%s\n", divider);
+}
+
+
+#if BX_SUPPORT_SID==0
+int
+main(int argc, char *argv[])
+{
+ // To deal with initialization order problems inherent in C++, use
+ // the macros SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog"
+ // in all constructors or functions called by constructors. The macros
+ // test for NULL and create the object if necessary, then return it.
+ // Ensure that io and genlog get created, by making one reference to
+ // each macro right here. All other code can call them directly.
+ SAFE_GET_IOFUNC();
+ SAFE_GET_GENLOG();
+
+ bx_print_header ();
+
+#if BX_DEBUGGER
+ // If using the debugger, it will take control and call
+ // bx_bochs_init() and cpu_loop()
+ bx_dbg_main(argc, argv);
+#else
+ // If not using the debugger, pass control on normally
+ bx_bochs_init(argc, argv);
+
+ if (bx_options.load32bitOSImage.whichOS) {
+ void bx_load32bitOSimagehack(void);
+ bx_load32bitOSimagehack();
+ }
+
+ if (BX_SMP_PROCESSORS == 1) {
+ // only one processor, run as fast as possible by not messing with
+ // quantums and loops.
+ BX_CPU(0)->cpu_loop(1);
+ } else {
+ // SMP simulation: do 5 instructions on each processor, then switch
+ // to another. I'm sure that increasing quantum speeds up overall
+ // performance.
+ int processor = 0;
+ int quantum = 5;
+ while (1) {
+ // do some instructions in each processor
+ BX_CPU(processor)->cpu_loop(quantum);
+ processor = (processor+1) % BX_SMP_PROCESSORS;
+ if (processor == 0)
+ BX_TICKN(quantum);
+ }
+ }
+#endif
+
+ return(0);
+}
+#endif // BX_SUPPORT_SID
+
+
+ int
+bx_bochs_init(int argc, char *argv[])
+{
+ int n;
+
+#ifdef MAGIC_BREAKPOINT
+ bx_dbg.magic_break_enabled = 0;
+#endif
+#if BX_PROVIDE_MAIN
+ /* read the .bochsrc file */
+ parse_bochsrc(argc);
+#endif
+ for (int level=0; level<MAX_LOGLEV; level++)
+ io->set_log_action (level, bx_options.log_actions[level]);
+
+//#if BX_PROVIDE_CPU_MEMORY==1
+// else if (!strcmp(argv[n-1], "-sanity-check")) {
+// BX_CPU.sanity_checks();
+// n += 1;
+// exit(0);
+// }
+//#endif
+
+ // Pass all command line options to be parsed,
+ // just like they came from the .bochsrc. Thus
+ // command line options will override .bochsrc options.
+#if BX_SUPPORT_SID==0
+ n = 2;
+ while (n <= argc) {
+ parse_line_unformatted(argv[n-1]);
+ n++;
+ }
+#endif
+#if BX_PROVIDE_DEVICE_MODELS
+ bx_pc_system.init_ips(bx_options.ips);
+#endif
+ if(logfilename[0]!='-') {
+ BX_INFO (("using log file %s\n", logfilename));
+ io->init_log(logfilename);
+ }
+
+ // set up memory and CPU objects
+#if BX_SUPPORT_APIC
+ memset(apic_index, 0, sizeof(apic_index[0]) * APIC_MAX_ID);
+#endif
+
+#if BX_SMP_PROCESSORS==1
+ BX_MEM(0)->init_memory(bx_options.memory.megs * 1024*1024);
+ BX_MEM(0)->load_ROM(bx_options.rom.path, bx_options.rom.address);
+ BX_MEM(0)->load_ROM(bx_options.vgarom.path, 0xc0000);
+ BX_CPU(0)->init (BX_MEM(0));
+ BX_CPU(0)->reset(BX_RESET_HARDWARE);
+#else
+ // SMP initialization
+ bx_mem_array[0] = new BX_MEM_C ();
+ bx_mem_array[0]->init_memory(bx_options.memory.megs * 1024*1024);
+ bx_mem_array[0]->load_ROM(bx_options.rom.path, bx_options.rom.address);
+ bx_mem_array[0]->load_ROM(bx_options.vgarom.path, 0xc0000);
+ for (int i=0; i<BX_SMP_PROCESSORS; i++) {
+ BX_CPU(i) = new BX_CPU_C ();
+ BX_CPU(i)->init (bx_mem_array[0]);
+ // assign apic ID from the index of this loop
+ // if !BX_SUPPORT_APIC, this will not compile.
+ BX_CPU(i)->local_apic.set_id (i);
+ BX_CPU(i)->reset(BX_RESET_HARDWARE);
+ }
+#endif
+
+ bx_init_debug();
+
+#if BX_DEBUGGER == 0
+#if BX_SUPPORT_SID==0
+ bx_devices.init(BX_MEM(0));
+ bx_gui.init_signal_handlers ();
+ bx_pc_system.start_timers();
+#endif
+#endif
+ BX_INFO(("bx_bochs_init is setting signal handlers\n"));
+// if not using debugger, then we can take control of SIGINT.
+// If using debugger, it needs control of this.
+#if BX_DEBUGGER==0
+ signal(SIGINT, bx_signal_handler);
+#endif
+
+#if BX_SHOW_IPS
+#ifndef __MINGW32__
+ signal(SIGALRM, bx_signal_handler);
+#endif
+ alarm( 1 );
+#endif
+
+ return(0);
+}
+
+
+
+ void
+bx_init_debug(void)
+{
+ bx_dbg.floppy = 0;
+ bx_dbg.keyboard = 0;
+ bx_dbg.video = 0;
+ bx_dbg.disk = 0;
+ bx_dbg.pit = 0;
+ bx_dbg.pic = 0;
+ bx_dbg.bios = 0;
+ bx_dbg.cmos = 0;
+ bx_dbg.a20 = 0;
+ bx_dbg.interrupts = 0;
+ bx_dbg.exceptions = 0;
+ bx_dbg.unsupported = 0;
+ bx_dbg.temp = 0;
+ bx_dbg.reset = 0;
+ bx_dbg.mouse = 0;
+ bx_dbg.io = 0;
+ bx_dbg.debugger = 0;
+ bx_dbg.xms = 0;
+ bx_dbg.v8086 = 0;
+ bx_dbg.paging = 0;
+ bx_dbg.creg = 0;
+ bx_dbg.dreg = 0;
+ bx_dbg.dma = 0;
+ bx_dbg.unsupported_io = 0;
+ bx_dbg.record_io = 0;
+ bx_dbg.serial = 0;
+ bx_dbg.cdrom = 0;
+}
+
+
+ void
+bx_atexit(void)
+{
+ static Boolean been_here = 0;
+
+
+#if BX_PROVIDE_DEVICE_MODELS==1
+ if (been_here == 0) {
+ bx_pc_system.exit();
+ }
+#endif
+
+#if BX_DEBUGGER == 0
+ for (int cpu=0; cpu<BX_SMP_PROCESSORS; cpu++)
+ if (BX_CPU(cpu)) BX_CPU(cpu)->atexit();
+#endif
+
+#if BX_PCI_SUPPORT
+ if (bx_options.i440FXSupport) {
+ bx_devices.pci->print_i440fx_state();
+ }
+#endif
+}
+
+#if (BX_PROVIDE_CPU_MEMORY==1) && (BX_EMULATE_HGA_DUMPS>0)
+ void
+bx_emulate_hga_dumps_timer(void)
+{
+ void bx_hga_set_video_memory(Bit8u *ptr);
+
+ bx_hga_set_video_memory(&bx_phy_memory[0xb0000]);
+}
+#endif
+
+
+#if BX_PROVIDE_MAIN
+ static void
+parse_bochsrc(int argc)
+{
+ FILE *fd = NULL;
+ char *ret;
+ char line[512];
+ Bit32u retry = 0, found = 0;
+
+ // try several possibilities for the bochsrc before giving up
+ while (!found) {
+ bochsrc_path[0] = 0;
+ switch (retry++) {
+ case 0: strcpy (bochsrc_path, ".bochsrc"); break;
+ case 1: strcpy (bochsrc_path, "bochsrc"); break;
+ case 2: strcpy (bochsrc_path, "bochsrc.txt"); break;
+ case 3:
+#if (!defined(WIN32) && !defined(macintosh))
+ // only try this on unix
+ {
+ char *ptr = getenv("HOME");
+ if (ptr) sprintf (bochsrc_path, "%s/.bochsrc", ptr);
+ }
+#endif
+ break;
+ default:
+ // no bochsrc used. This is still legal since they may have
+ // everything on the command line. However if they have no
+ // arguments then give them some friendly advice.
+ BX_INFO(( "could not find a bochsrc file\n"));
+ if (argc==1) {
+ fprintf (stderr, "%s\n", divider);
+ fprintf (stderr, "Before running Bochs, you should cd to a directory which contains\n");
+ fprintf (stderr, "a .bochsrc file and a disk image. If you downloaded a binary package,\n");
+ fprintf (stderr, "all the necessary files are already on your disk.\n");
+#if defined(WIN32)
+ fprintf (stderr, "\nFor Windows installations, go to the dlxlinux direectory and\n");
+ fprintf (stderr, "double-click on the start.bat script.\n");
+#elif !defined(macintosh)
+ fprintf (stderr, "\nFor UNIX installations, try running \"bochs-dlx\" for a demo. This script\n");
+ fprintf (stderr, "is basically equivalent to typing:\n");
+ fprintf (stderr, " cd /usr/local/bochs/dlxlinux\n");
+ fprintf (stderr, " bochs\n");
+#endif
+ exit(1);
+ }
+ return;
+ }
+ if (bochsrc_path[0]) {
+ BX_INFO (("looking for configuration in %s\n", bochsrc_path));
+ fd = fopen(bochsrc_path, "r");
+ if (fd) found = 1;
+ }
+ }
+ assert (fd != NULL && bochsrc_path[0] != 0);
+
+ BX_INFO(("reading configuration from %s\n", bochsrc_path));
+
+#if BX_SUPPORT_SID==0
+ do {
+ ret = fgets(line, sizeof(line)-1, fd);
+ line[sizeof(line) - 1] = '\0';
+ int len = strlen(line);
+ if (len>0)
+ line[len-1] = '\0';
+
+ if ((ret != NULL) && strlen(line)) {
+ parse_line_unformatted(line);
+ }
+ } while (!feof(fd));
+#endif
+}
+
+ static void
+parse_line_unformatted(char *line)
+{
+ char *ptr;
+ unsigned i, string_i;
+ char string[512];
+ char *params[40];
+ int num_params;
+ Boolean inquotes = 0;
+
+ if (line == NULL) return;
+
+ // if passed nothing but whitespace, just return
+ for (i=0; i<strlen(line); i++) {
+ if (!isspace(line[i])) break;
+ }
+ if (i>=strlen(line))
+ return;
+
+ num_params = 0;
+
+ ptr = strtok(line, ":");
+ while (ptr) {
+ string_i = 0;
+ for (i=0; i<strlen(ptr); i++) {
+ if (ptr[i] == '"')
+ inquotes = !inquotes;
+ else
+ if (!isspace(ptr[i]) || inquotes) {
+ string[string_i++] = ptr[i];
+ }
+ }
+ string[string_i] = '\0';
+ strcpy(ptr, string);
+ params[num_params++] = ptr;
+ ptr = strtok(NULL, ",");
+ }
+ parse_line_formatted(num_params, ¶ms[0]);
+}
+
+ static void
+parse_line_formatted(int num_params, char *params[])
+{
+ int i;
+
+ if (num_params < 1) return;
+
+ if (params[0][0] == '#') return; /* comment */
+ else if (!strcmp(params[0], "floppya")) {
+ for (i=1; i<num_params; i++) {
+ if (!strncmp(params[i], "2_88=", 5)) {
+ strcpy(bx_options.floppya.path, ¶ms[i][5]);
+ bx_options.floppya.type = BX_FLOPPY_2_88;
+ }
+ else if (!strncmp(params[i], "1_44=", 5)) {
+ strcpy(bx_options.floppya.path, ¶ms[i][5]);
+ bx_options.floppya.type = BX_FLOPPY_1_44;
+ }
+ else if (!strncmp(params[i], "1_2=", 4)) {
+ strcpy(bx_options.floppya.path, ¶ms[i][4]);
+ bx_options.floppya.type = BX_FLOPPY_1_2;
+ }
+ else if (!strncmp(params[i], "720k=", 5)) {
+ strcpy(bx_options.floppya.path, ¶ms[i][5]);
+ bx_options.floppya.type = BX_FLOPPY_720K;
+ }
+ else if (!strncmp(params[i], "status=ejected", 14)) {
+ bx_options.floppya.initial_status = BX_EJECTED;
+ }
+ else if (!strncmp(params[i], "status=inserted", 15)) {
+ bx_options.floppya.initial_status = BX_INSERTED;
+ }
+ else {
+ BX_PANIC(("%s: floppya attribute '%s' not understood.\n", bochsrc_path,
+ params[i]));
+ }
+ }
+ }
+
+ else if (!strcmp(params[0], "floppyb")) {
+ for (i=1; i<num_params; i++) {
+ if (!strncmp(params[i], "2_88=", 5)) {
+ strcpy(bx_options.floppyb.path, ¶ms[i][5]);
+ bx_options.floppyb.type = BX_FLOPPY_2_88;
+ }
+ else if (!strncmp(params[i], "1_44=", 5)) {
+ strcpy(bx_options.floppyb.path, ¶ms[i][5]);
+ bx_options.floppyb.type = BX_FLOPPY_1_44;
+ }
+ else if (!strncmp(params[i], "1_2=", 4)) {
+ strcpy(bx_options.floppyb.path, ¶ms[i][4]);
+ bx_options.floppyb.type = BX_FLOPPY_1_2;
+ }
+ else if (!strncmp(params[i], "720k=", 5)) {
+ strcpy(bx_options.floppyb.path, ¶ms[i][5]);
+ bx_options.floppyb.type = BX_FLOPPY_720K;
+ }
+ else if (!strncmp(params[i], "status=ejected", 14)) {
+ bx_options.floppyb.initial_status = BX_EJECTED;
+ }
+ else if (!strncmp(params[i], "status=inserted", 15)) {
+ bx_options.floppyb.initial_status = BX_INSERTED;
+ }
+ else {
+ BX_PANIC(("%s: floppyb attribute '%s' not understood.\n", bochsrc_path,
+ params[i]));
+ }
+ }
+ }
+
+ else if (!strcmp(params[0], "diskc")) {
+ if (num_params != 5) {
+ BX_PANIC(("%s: diskc directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "file=", 5) ||
+ strncmp(params[2], "cyl=", 4) ||
+ strncmp(params[3], "heads=", 6) ||
+ strncmp(params[4], "spt=", 4)) {
+ BX_PANIC(("%s: diskc directive malformed.\n", bochsrc_path));
+ }
+ strcpy(bx_options.diskc.path, ¶ms[1][5]);
+ bx_options.diskc.cylinders = atol( ¶ms[2][4] );
+ bx_options.diskc.heads = atol( ¶ms[3][6] );
+ bx_options.diskc.spt = atol( ¶ms[4][4] );
+ bx_options.diskc.present = 1;
+ }
+ else if (!strcmp(params[0], "diskd")) {
+ if (num_params != 5) {
+ BX_PANIC(("%s: diskd directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "file=", 5) ||
+ strncmp(params[2], "cyl=", 4) ||
+ strncmp(params[3], "heads=", 6) ||
+ strncmp(params[4], "spt=", 4)) {
+ BX_PANIC(("%s: diskd directive malformed.\n", bochsrc_path));
+ }
+ strcpy(bx_options.diskd.path, ¶ms[1][5]);
+ bx_options.diskd.cylinders = atol( ¶ms[2][4] );
+ bx_options.diskd.heads = atol( ¶ms[3][6] );
+ bx_options.diskd.spt = atol( ¶ms[4][4] );
+ bx_options.diskd.present = 1;
+ }
+
+ else if (!strcmp(params[0], "cdromd")) {
+ if (num_params != 3) {
+ BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
+ BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+ }
+ strcpy(bx_options.cdromd.dev, ¶ms[1][4]);
+ if (!strcmp(params[2], "status=inserted"))
+ bx_options.cdromd.inserted = 1;
+ else if (!strcmp(params[2], "status=ejected"))
+ bx_options.cdromd.inserted = 0;
+ else {
+ BX_PANIC(("%s: cdromd directive malformed.\n", bochsrc_path));
+ }
+ bx_options.cdromd.present = 1;
+ }
+
+ else if (!strcmp(params[0], "boot")) {
+ if (!strcmp(params[1], "a") ||
+ !strcmp(params[1], "c")) {
+ strcpy(bx_options.bootdrive, params[1]);
+ }
+ else {
+ BX_PANIC(("%s: boot directive with unknown boot device '%s'. use 'a' or 'c'.\n", bochsrc_path, params[1]));
+ }
+ }
+ else if (!strcmp(params[0], "log")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: log directive has wrong # args.\n", bochsrc_path));
+ }
+ strcpy(logfilename, params[1]);
+ }
+ else if (!strcmp(params[0], "panic")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "action=", 7)) {
+ BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+ }
+ char *action = 7 + params[1];
+ if (!strcmp(action, "fatal"))
+ bx_options.log_actions[LOGLEV_PANIC] = ACT_FATAL;
+ else if (!strcmp (action, "report"))
+ bx_options.log_actions[LOGLEV_PANIC] = ACT_REPORT;
+ else if (!strcmp (action, "ignore"))
+ bx_options.log_actions[LOGLEV_PANIC] = ACT_IGNORE;
+ else {
+ BX_PANIC(("%s: panic directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "error")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "action=", 7)) {
+ BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+ }
+ char *action = 7 + params[1];
+ if (!strcmp(action, "fatal"))
+ bx_options.log_actions[LOGLEV_ERROR] = ACT_FATAL;
+ else if (!strcmp (action, "report"))
+ bx_options.log_actions[LOGLEV_ERROR] = ACT_REPORT;
+ else if (!strcmp (action, "ignore"))
+ bx_options.log_actions[LOGLEV_ERROR] = ACT_IGNORE;
+ else {
+ BX_PANIC(("%s: error directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "info")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "action=", 7)) {
+ BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+ }
+ char *action = 7 + params[1];
+ if (!strcmp(action, "fatal"))
+ bx_options.log_actions[LOGLEV_INFO] = ACT_FATAL;
+ else if (!strcmp (action, "report"))
+ bx_options.log_actions[LOGLEV_INFO] = ACT_REPORT;
+ else if (!strcmp (action, "ignore"))
+ bx_options.log_actions[LOGLEV_INFO] = ACT_IGNORE;
+ else {
+ BX_PANIC(("%s: info directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "debug")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "action=", 7)) {
+ BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+ }
+ char *action = 7 + params[1];
+ if (!strcmp(action, "fatal"))
+ bx_options.log_actions[LOGLEV_DEBUG] = ACT_FATAL;
+ else if (!strcmp (action, "report"))
+ bx_options.log_actions[LOGLEV_DEBUG] = ACT_REPORT;
+ else if (!strcmp (action, "ignore"))
+ bx_options.log_actions[LOGLEV_DEBUG] = ACT_IGNORE;
+ else {
+ BX_PANIC(("%s: debug directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "romimage")) {
+ if (num_params != 3) {
+ BX_PANIC(("%s: romimage directive: wrong # args.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "file=", 5)) {
+ BX_PANIC(("%s: romimage directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[2], "address=", 8)) {
+ BX_PANIC(("%s: romimage directive malformed.\n", bochsrc_path));
+ }
+ bx_options.rom.path = strdup(¶ms[1][5]);
+ if ( (params[2][8] == '0') && (params[2][9] == 'x') )
+ bx_options.rom.address = strtoul(¶ms[2][8], NULL, 16);
+ else
+ bx_options.rom.address = strtoul(¶ms[2][8], NULL, 10);
+ }
+ else if (!strcmp(params[0], "vgaromimage")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: vgaromimage directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.vgarom.path = strdup(params[1]);
+ }
+ else if (!strcmp(params[0], "vga_update_interval")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: vga_update_interval directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.vga_update_interval = atol(params[1]);
+ if (bx_options.vga_update_interval < 50000) {
+ BX_INFO(("%s: vga_update_interval not big enough!\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "keyboard_serial_delay")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: keyboard_serial_delay directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.keyboard_serial_delay = atol(params[1]);
+ if (bx_options.keyboard_serial_delay < 5) {
+ BX_PANIC(("%s: keyboard_serial_delay not big enough!\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "megs")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: megs directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.memory.megs = atol(params[1]);
+ }
+ else if (!strcmp(params[0], "floppy_command_delay")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: floppy_command_delay directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.floppy_command_delay = atol(params[1]);
+ if (bx_options.floppy_command_delay < 100) {
+ BX_PANIC(("%s: floppy_command_delay not big enough!\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "ips")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: ips directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.ips = atol(params[1]);
+ if (bx_options.ips < 200000) {
+ BX_INFO(("%s: WARNING: ips is AWFULLY low!\n", bochsrc_path));
+ }
+ }
+
+ else if (!strcmp(params[0], "mouse")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "enabled=", 8)) {
+ BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+ }
+ if (params[1][8] == '0')
+ bx_options.mouse_enabled = 0;
+ else if (params[1][8] == '1')
+ bx_options.mouse_enabled = 1;
+ else {
+ BX_PANIC(("%s: mouse directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "private_colormap")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "enabled=", 8)) {
+ BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+ }
+ if (params[1][8] == '0')
+ bx_options.private_colormap = 0;
+ else if (params[1][8] == '1')
+ bx_options.private_colormap = 1;
+ else {
+ BX_PANIC(("%s: private_colormap directive malformed.\n", bochsrc_path));
+ }
+ }
+
+ else if (!strcmp(params[0], "sb16")) {
+ for (i=1; i<num_params; i++) {
+ if (!strncmp(params[i], "midi=", 5)) {
+ bx_options.sb16.midifile = strdup(¶ms[i][5]);
+ }
+ else if (!strncmp(params[i], "midimode=", 9)) {
+ bx_options.sb16.midimode = atol(¶ms[i][9]);
+ }
+ else if (!strncmp(params[i], "wave=", 5)) {
+ bx_options.sb16.wavefile = strdup(¶ms[i][5]);
+ }
+ else if (!strncmp(params[i], "wavemode=", 9)) {
+ bx_options.sb16.wavemode = atol(¶ms[i][9]);
+ }
+ else if (!strncmp(params[i], "log=", 4)) {
+ bx_options.sb16.logfile = strdup(¶ms[i][4]);
+ }
+ else if (!strncmp(params[i], "loglevel=", 9)) {
+ bx_options.sb16.loglevel = atol(¶ms[i][9]);
+ }
+ else if (!strncmp(params[i], "dmatimer=", 9)) {
+ bx_options.sb16.dmatimer = atol(¶ms[i][9]);
+ }
+ }
+ }
+
+ else if (!strcmp(params[0], "i440fxsupport")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "enabled=", 8)) {
+ BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+ }
+ if (params[1][8] == '0')
+ bx_options.i440FXSupport = 0;
+ else if (params[1][8] == '1')
+ bx_options.i440FXSupport = 1;
+ else {
+ BX_PANIC(("%s: i440FXSupport directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "newharddrivesupport")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "enabled=", 8)) {
+ BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+ }
+ if (params[1][8] == '0')
+ bx_options.newHardDriveSupport = 0;
+ else if (params[1][8] == '1')
+ bx_options.newHardDriveSupport = 1;
+ else {
+ BX_PANIC(("%s: newharddrivesupport directive malformed.\n", bochsrc_path));
+ }
+ }
+ else if (!strcmp(params[0], "cmosimage")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: cmosimage directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.cmos.path = strdup(params[1]);
+ bx_options.cmos.cmosImage = 1; // CMOS Image is true
+ }
+ else if (!strcmp(params[0], "time0")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: time0 directive: wrong # args.\n", bochsrc_path));
+ }
+ bx_options.cmos.time0 = atoi(params[1]);
+ }
+#ifdef MAGIC_BREAKPOINT
+ else if (!strcmp(params[0], "magic_break")) {
+ if (num_params != 2) {
+ BX_PANIC(("%s: magic_break directive: wrong # args.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "enabled=", 8)) {
+ BX_PANIC(("%s: magic_break directive malformed.\n", bochsrc_path));
+ }
+ if (params[1][8] == '0') {
+ BX_INFO(("Ignoring magic break points\n"));
+ bx_dbg.magic_break_enabled = 0;
+ }
+ else if (params[1][8] == '1') {
+ BX_INFO(("Stopping on magic break points\n"));
+ bx_dbg.magic_break_enabled = 1;
+ }
+ else {
+ BX_PANIC(("%s: magic_break directive malformed.\n", bochsrc_path));
+ }
+ }
+#endif
+ else if (!strcmp(params[0], "ne2k")) {
+ int tmp[6];
+ bx_options.ne2k.valid = 0;
+ if ((num_params < 4) || (num_params > 6)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ bx_options.ne2k.ethmod = "null";
+ if (strncmp(params[1], "ioaddr=", 7)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[2], "irq=", 4)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[3], "mac=", 4)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ bx_options.ne2k.ioaddr = strtoul(¶ms[1][7], NULL, 16);
+ bx_options.ne2k.irq = atol(¶ms[2][4]);
+ i = sscanf(¶ms[3][4], "%x:%x:%x:%x:%x:%x",
+ &tmp[0],&tmp[1],&tmp[2],&tmp[3],&tmp[4],&tmp[5]);
+ if (i != 6) {
+ BX_PANIC(("%s: ne2k mac address malformed.\n", bochsrc_path));
+ }
+ for (i=0;i<6;i++)
+ bx_options.ne2k.macaddr[i] = tmp[i];
+ if (num_params > 4) {
+ if (strncmp(params[4], "ethmod=", 7)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ bx_options.ne2k.ethmod = strdup(¶ms[4][7]);
+ if (num_params == 6) {
+ if (strncmp(params[5], "ethdev=", 7)) {
+ BX_PANIC(("%s: ne2k directive malformed.\n", bochsrc_path));
+ }
+ bx_options.ne2k.ethdev = strdup(¶ms[5][7]);
+ }
+ }
+ bx_options.ne2k.valid = 1;
+ }
+
+ else if (!strcmp(params[0], "load32bitOSImage")) {
+ if ( (num_params!=4) && (num_params!=5) ) {
+ BX_PANIC(("%s: load32bitOSImage directive: wrong # args.\n", bochsrc_path));
+ }
+ if (strncmp(params[1], "os=", 3)) {
+ BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+ }
+ if (!strcmp(¶ms[1][3], "nullkernel")) {
+ bx_options.load32bitOSImage.whichOS = Load32bitOSNullKernel;
+ }
+ else if (!strcmp(¶ms[1][3], "linux")) {
+ bx_options.load32bitOSImage.whichOS = Load32bitOSLinux;
+ }
+ else {
+ BX_PANIC(("%s: load32bitOSImage: unsupported OS.\n", bochsrc_path));
+ }
+ if (strncmp(params[2], "path=", 5)) {
+ BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+ }
+ if (strncmp(params[3], "iolog=", 6)) {
+ BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+ }
+ bx_options.load32bitOSImage.path = strdup(¶ms[2][5]);
+ bx_options.load32bitOSImage.iolog = strdup(¶ms[3][6]);
+ if (num_params == 5) {
+ if (strncmp(params[4], "initrd=", 7)) {
+ BX_PANIC(("%s: load32bitOSImage: directive malformed.\n", bochsrc_path));
+ }
+ bx_options.load32bitOSImage.initrd = strdup(¶ms[4][7]);
+ }
+ }
+
+ else {
+ BX_PANIC(( "%s: directive '%s' not understood\n", bochsrc_path, params[0]));
+ }
+
+ if (bx_options.diskd.present && bx_options.cdromd.present)
+ BX_PANIC(("At present, using both diskd and cdromd at once is not supported."));
+}
+#endif // #if BX_PROVIDE_MAIN
+
+ void
+bx_signal_handler( int signum)
+{
+#if BX_GUI_SIGHANDLER
+ // GUI signal handler gets first priority, if the mask says it's wanted
+ if ((1<<signum) & bx_gui.get_sighandler_mask ()) {
+ bx_gui.sighandler (signum);
+ return;
+ }
+#endif
+
+#if BX_SHOW_IPS
+ extern unsigned long ips_count;
+
+ if (signum == SIGALRM ) {
+ BX_INFO(("ips = %lu\n", ips_count));
+ ips_count = 0;
+#ifndef __MINGW32__
+ signal(SIGALRM, bx_signal_handler);
+ alarm( 1 );
+#endif
+ return;
+ }
+#endif
+
+#if BX_GUI_SIGHANDLER
+ if ((1<<signum) & bx_gui.get_sighandler_mask ()) {
+ bx_gui.sighandler (signum);
+ return;
+ }
+#endif
+ BX_PANIC(("SIGNAL %u caught\n", signum));
+}
+
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::MUL_AXEw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, product_16h, product_16l;
+ Bit32u product_32;
+ Boolean temp_flag;
+
+ op1_16 = AX;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ product_32 = ((Bit32u) op1_16) * ((Bit32u) op2_16);
+
+ product_16l = (product_32 & 0xFFFF);
+ product_16h = product_32 >> 16;
+
+ /* now write product back to destination */
+
+ AX = product_16l;
+ DX = product_16h;
+
+ /* set eflags:
+ * MUL affects the following flags: C,O
+ */
+
+ temp_flag = (product_16h != 0);
+ SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+}
+
+
+
+ void
+BX_CPU_C::IMUL_AXEw(BxInstruction_t *i)
+{
+ Bit16s op1_16, op2_16;
+ Bit32s product_32;
+ Bit16u product_16h, product_16l;
+
+ op1_16 = AX;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+ }
+
+ product_32 = ((Bit32s) op1_16) * ((Bit32s) op2_16);
+
+ product_16l = (product_32 & 0xFFFF);
+ product_16h = product_32 >> 16;
+
+ /* now write product back to destination */
+
+ AX = product_16l;
+ DX = product_16h;
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r/m16: condition for clearing CF & OF:
+ * DX:AX = sign-extend of AX
+ */
+
+ if ( (DX==0xffff) && (AX & 0x8000) ) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else if ( (DX==0x0000) && (AX < 0x8000) ) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+}
+
+
+ void
+BX_CPU_C::DIV_AXEw(BxInstruction_t *i)
+{
+ Bit16u op2_16, remainder_16, quotient_16l;
+ Bit32u op1_32, quotient_32;
+
+ op1_32 = (((Bit32u) DX) << 16) | ((Bit32u) AX);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op2_16);
+ }
+
+ if (op2_16 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+ quotient_32 = op1_32 / op2_16;
+ remainder_16 = op1_32 % op2_16;
+ quotient_16l = quotient_32 & 0xFFFF;
+
+ if (quotient_32 != quotient_16l) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * DIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+#if INTEL_DIV_FLAG_BUG == 1
+ set_CF(1);
+#endif
+
+ /* now write quotient back to destination */
+
+ AX = quotient_16l;
+ DX = remainder_16;
+}
+
+
+ void
+BX_CPU_C::IDIV_AXEw(BxInstruction_t *i)
+{
+ Bit16s op2_16, remainder_16, quotient_16l;
+ Bit32s op1_32, quotient_32;
+
+ op1_32 = ((((Bit32u) DX) << 16) | ((Bit32u) AX));
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+ }
+
+ if (op2_16 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+ quotient_32 = op1_32 / op2_16;
+ remainder_16 = op1_32 % op2_16;
+ quotient_16l = quotient_32 & 0xFFFF;
+
+ if (quotient_32 != quotient_16l) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * IDIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+#if INTEL_DIV_FLAG_BUG == 1
+ set_CF(1);
+#endif
+
+ /* now write quotient back to destination */
+
+ AX = quotient_16l;
+ DX = remainder_16;
+}
+
+
+ void
+BX_CPU_C::IMUL_GwEwIw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("IMUL_GvEvIv() unsupported on 8086!\n"));
+#else
+
+
+ Bit16u product_16l;
+ Bit16s op2_16, op3_16;
+ Bit32s product_32;
+
+ op3_16 = i->Iw;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+ }
+
+ product_32 = op2_16 * op3_16;
+
+ product_16l = (product_32 & 0xFFFF);
+
+ /* now write product back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, product_16l);
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+ * result exactly fits within r16
+ */
+
+ if (product_32 > -32768 && product_32 < 32767) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::IMUL_GwEw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("IMUL_GvEv() unsupported on 8086!\n"));
+#else
+
+ Bit16u product_16l;
+ Bit16s op1_16, op2_16;
+ Bit32s product_32;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &op2_16);
+ }
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ product_32 = op1_16 * op2_16;
+
+ product_16l = (product_32 & 0xFFFF);
+
+ /* now write product back to destination */
+ BX_WRITE_16BIT_REG(i->nnn, product_16l);
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+ * result exactly fits within r16
+ */
+
+ if (product_32 > -32768 && product_32 < 32767) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::MUL_EAXEd(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, product_32h, product_32l;
+ Bit64u product_64;
+ Boolean temp_flag;
+
+ op1_32 = EAX;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ product_64 = ((Bit64u) op1_32) * ((Bit64u) op2_32);
+
+ product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
+ product_32h = (Bit32u) (product_64 >> 32);
+
+ /* now write product back to destination */
+
+ EAX = product_32l;
+ EDX = product_32h;
+
+ /* set eflags:
+ * MUL affects the following flags: C,O
+ */
+
+ temp_flag = (product_32h != 0);
+ SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+}
+
+
+
+ void
+BX_CPU_C::IMUL_EAXEd(BxInstruction_t *i)
+{
+ Bit32s op1_32, op2_32;
+ Bit64s product_64;
+ Bit32u product_32h, product_32l;
+
+ op1_32 = EAX;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+ }
+
+ product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
+
+ product_32l = (Bit32u) (product_64 & 0xFFFFFFFF);
+ product_32h = (Bit32u) (product_64 >> 32);
+
+ /* now write product back to destination */
+
+ EAX = product_32l;
+ EDX = product_32h;
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r/m16: condition for clearing CF & OF:
+ * EDX:EAX = sign-extend of EAX
+ */
+
+ if ( (EDX==0xffffffff) && (EAX & 0x80000000) ) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else if ( (EDX==0x00000000) && (EAX < 0x80000000) ) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+}
+
+
+ void
+BX_CPU_C::DIV_EAXEd(BxInstruction_t *i)
+{
+ Bit32u op2_32, remainder_32, quotient_32l;
+ Bit64u op1_64, quotient_64;
+
+ op1_64 = (((Bit64u) EDX) << 32) + ((Bit64u) EAX);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op2_32);
+ }
+
+ if (op2_32 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+ quotient_64 = op1_64 / op2_32;
+ remainder_32 = (Bit32u) (op1_64 % op2_32);
+ quotient_32l = (Bit32u) (quotient_64 & 0xFFFFFFFF);
+
+ if (quotient_64 != quotient_32l) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * DIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+ /* now write quotient back to destination */
+
+ EAX = quotient_32l;
+ EDX = remainder_32;
+}
+
+
+ void
+BX_CPU_C::IDIV_EAXEd(BxInstruction_t *i)
+{
+ Bit32s op2_32, remainder_32, quotient_32l;
+ Bit64s op1_64, quotient_64;
+
+ op1_64 = (((Bit64u) EDX) << 32) | ((Bit64u) EAX);
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+ }
+
+ if (op2_32 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+ quotient_64 = op1_64 / op2_32;
+ remainder_32 = (Bit32s) (op1_64 % op2_32);
+ quotient_32l = (Bit32s) (quotient_64 & 0xFFFFFFFF);
+
+ if (quotient_64 != quotient_32l) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * IDIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+ /* now write quotient back to destination */
+
+ EAX = quotient_32l;
+ EDX = remainder_32;
+}
+
+
+ void
+BX_CPU_C::IMUL_GdEdId(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("IMUL_GdEdId() unsupported on 8086!\n"));
+#else
+
+
+ Bit32s op2_32, op3_32, product_32;
+ Bit64s product_64;
+
+ op3_32 = i->Id;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+ }
+
+ product_32 = op2_32 * op3_32;
+ product_64 = ((Bit64s) op2_32) * ((Bit64s) op3_32);
+
+ /* now write product back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, product_32);
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+ * result exactly fits within r16
+ */
+
+ if (product_64 == product_32) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::IMUL_GdEd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("IMUL_GvEv() unsupported on 8086!\n"));
+#else
+
+ Bit32s op1_32, op2_32, product_32;
+ Bit64s product_64;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &op2_32);
+ }
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ product_32 = op1_32 * op2_32;
+ product_64 = ((Bit64s) op1_32) * ((Bit64s) op2_32);
+
+ /* now write product back to destination */
+ BX_WRITE_32BIT_REG(i->nnn, product_32);
+
+ /* set eflags:
+ * IMUL affects the following flags: C,O
+ * IMUL r16,r/m16,imm16: condition for clearing CF & OF:
+ * result exactly fits within r16
+ */
+
+ if (product_64 == product_32) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+ void
+BX_CPU_C::MUL_ALEb(BxInstruction_t *i)
+{
+ Bit8u op2, op1;
+ Bit16u product_16;
+ Boolean temp_flag;
+
+ op1 = AL;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ product_16 = op1 * op2;
+
+ /* set EFLAGS:
+ * MUL affects the following flags: C,O
+ */
+
+ temp_flag = ((product_16 & 0xFF00) != 0);
+ SET_FLAGS_OxxxxC(temp_flag, temp_flag);
+
+ /* now write product back to destination */
+
+ AX = product_16;
+}
+
+
+ void
+BX_CPU_C::IMUL_ALEb(BxInstruction_t *i)
+{
+ Bit8s op2, op1;
+ Bit16s product_16;
+ Bit16u upper_bits;
+
+
+ op1 = AL;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, (Bit8u *) &op2);
+ }
+
+ product_16 = op1 * op2;
+
+ /* now write product back to destination */
+
+ AX = product_16;
+
+ /* set EFLAGS:
+ * IMUL affects the following flags: C,O
+ * IMUL r/m8: condition for clearing CF & OF:
+ * AL = sign-extend of AL to 16 bits
+ */
+ upper_bits = AX & 0xff80;
+ if (upper_bits==0xff80 || upper_bits==0x0000) {
+ SET_FLAGS_OxxxxC(0, 0);
+ }
+ else {
+ SET_FLAGS_OxxxxC(1, 1);
+ }
+}
+
+
+
+ void
+BX_CPU_C::DIV_ALEb(BxInstruction_t *i)
+{
+ Bit8u op2, quotient_8l, remainder_8;
+ Bit16u quotient_16, op1;
+
+
+ op1 = AX;
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, &op2);
+ }
+
+ if (op2 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+ quotient_16 = op1 / op2;
+ remainder_8 = op1 % op2;
+ quotient_8l = quotient_16 & 0xFF;
+
+ if (quotient_16 != quotient_8l) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * DIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+#if INTEL_DIV_FLAG_BUG == 1
+ set_CF(1);
+#endif
+
+ /* now write quotient back to destination */
+
+ AL = quotient_8l;
+ AH = remainder_8;
+}
+
+
+ void
+BX_CPU_C::IDIV_ALEb(BxInstruction_t *i)
+{
+ Bit8s op2, quotient_8l, remainder_8;
+ Bit16s quotient_16, op1;
+
+
+ op1 = AX;
+
+
+ /* op2 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op2 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_byte(i->seg, i->rm_addr, (Bit8u *) &op2);
+ }
+
+ if (op2 == 0) {
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ quotient_16 = op1 / op2;
+ remainder_8 = op1 % op2;
+ quotient_8l = quotient_16 & 0xFF;
+
+ if (quotient_16 != quotient_8l) {
+BX_INFO(("quotient_16: %04x, remainder_8: %02x, quotient_8l: %02x\n",
+ (unsigned) quotient_16, (unsigned) remainder_8, (unsigned) quotient_8l));
+AL = quotient_8l;
+AH = remainder_8;
+BX_INFO(("AH: %02x, AL: %02x\n", (unsigned) AH, (unsigned) AL));
+ exception(BX_DE_EXCEPTION, 0, 0);
+ }
+
+ /* set EFLAGS:
+ * DIV affects the following flags: O,S,Z,A,P,C are undefined
+ */
+
+#if INTEL_DIV_FLAG_BUG == 1
+ set_CF(1);
+#endif
+
+ /* now write quotient back to destination */
+
+ AL = quotient_8l;
+ AH = remainder_8;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#if 0
+ // - what should the reserved bits in the error code be ?
+ // - move CR0.wp bit in lookup table to cache. Then dump
+ // cache whenever it is changed. This eliminates the
+ // extra calculation and shifting.
+ // - change BX_READ and BX_WRITE to 0,1 ???
+#endif
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+
+
+#if 0
+// X86 Registers Which Affect Paging:
+// ==================================
+//
+// CR0:
+// bit 31: PG, Paging (386+)
+// bit 16: WP, Write Protect (486+)
+// 0: allow supervisor level writes into user level RO pages
+// 1: inhibit supervisor level writes into user level RO pages
+//
+// CR3:
+// bit 31..12: PDBR, Page Directory Base Register (386+)
+// bit 4: PCD, Page level Cache Disable (486+)
+// Controls caching of current page directory. Affects only the processor's
+// internal caches (L1 and L2).
+// This flag ignored if paging disabled (PG=0) or cache disabled (CD=1).
+// Values:
+// 0: Page Directory can be cached
+// 1: Page Directory not cached
+// bit 3: PWT, Page level Writes Transparent (486+)
+// Controls write-through or write-back caching policy of current page
+// directory. Affects only the processor's internal caches (L1 and L2).
+// This flag ignored if paging disabled (PG=0) or cache disabled (CD=1).
+// Values:
+// 0: write-back caching enabled
+// 1: write-through caching enabled
+//
+// CR4:
+// bit 4: PSE, Page Size Extension (Pentium+)
+// 0: 4KByte pages (typical)
+// 1: 4MByte or 2MByte pages
+// bit 5: PAE, Physical Address Extension (Pentium Pro+)
+// 0: 32bit physical addresses
+// 1: 36bit physical addresses
+// bit 7: PGE, Page Global Enable (Pentium Pro+)
+// The global page feature allows frequently used or shared pages
+// to be marked as global (PDE or PTE bit 8). Global pages are
+// not flushed from TLB on a task switch or write to CR3.
+// Values:
+// 0: disables global page feature
+// 1: enables global page feature
+//
+// Page size extention and physical address size extention matrix
+// ====================================================================
+// CR0.PG CR4.PAE CR4.PSE PDE.PS | page size physical address size
+// ====================================================================
+// 0 X X X | - paging disabled
+// 1 0 0 X | 4K 32bits
+// 1 0 1 0 | 4K 32bits
+// 1 0 1 1 | 4M 32bits
+// 1 1 X 0 | 4K 36bits
+// 1 1 X 1 | 2M 36bits
+
+
+\f
+// Page Directory/Table Entry format when P=0:
+// ===========================================
+//
+// 31.. 1: available
+// 0: P=0
+
+// Page Directory Entry format when P=1 (4-Kbyte Page Table):
+// ==========================================================
+//
+// 31..12: page table base address
+// 11.. 9: available
+// 8: G (Pentium Pro+), 0=reserved otherwise
+// 7: PS (Pentium+), 0=reserved otherwise
+// 6: 0=reserved
+// 5: A (386+)
+// 4: PCD (486+), 0=reserved otherwise
+// 3: PWT (486+), 0=reserved otherwise
+// 2: U/S (386+)
+// 1: R/W (386+)
+// 0: P=1 (386+)
+
+// Page Table Entry format when P=1 (4-Kbyte Page):
+// ================================================
+//
+// 31..12: page base address
+// 11.. 9: available
+// 8: G (Pentium Pro+), 0=reserved otherwise
+// 7: 0=reserved
+// 6: D (386+)
+// 5: A (386+)
+// 4: PCD (486+), 0=reserved otherwise
+// 3: PWT (486+), 0=reserved otherwise
+// 2: U/S (386+)
+// 1: R/W (386+)
+// 0: P=1 (386+)
+
+\f
+// Page Directory/Table Entry Fields Defined:
+// ==========================================
+// G: Global flag
+// Indiciates a global page when set. When a page is marked
+// global and the PGE flag in CR4 is set, the page table or
+// directory entry for the page is not invalidated in the TLB
+// when CR3 is loaded or a task switch occurs. Only software
+// clears and sets this flag. For page directory entries that
+// point to page tables, this flag is ignored and the global
+// characteristics of a page are set in the page table entries.
+//
+// PS: Page Size flag
+// Only used in page directory entries. When PS=0, the page
+// size is 4KBytes and the page directory entry points to a
+// page table. When PS=1, the page size is 4MBytes for
+// normal 32-bit addressing and 2MBytes if extended physical
+// addressing
+//
+// D: Dirty bit:
+// Processor sets the Dirty bit in the 2nd-level page table before a
+// write operation to an address mapped by that page table entry.
+// Dirty bit in directory entries is undefined.
+//
+// A: Accessed bit:
+// Processor sets the Accessed bits in both levels of page tables before
+// a read/write operation to a page.
+//
+// PCD: Page level Cache Disable
+// Controls caching of individual pages or page tables.
+// This allows a per-page based mechanism to disable caching, for
+// those pages which contained memory mapped IO, or otherwise
+// should not be cached. Processor ignores this flag if paging
+// is not used (CR0.PG=0) or the cache disable bit is set (CR0.CD=1).
+// Values:
+// 0: page or page table can be cached
+// 1: page or page table is not cached (prevented)
+//
+// PWT: Page level Write Through
+// Controls the write-through or write-back caching policy of individual
+// pages or page tables. Processor ignores this flag if paging
+// is not used (CR0.PG=0) or the cache disable bit is set (CR0.CD=1).
+// Values:
+// 0: write-back caching
+// 1: write-through caching
+//
+// U/S: User/Supervisor level
+// 0: Supervisor level - for the OS, drivers, etc.
+// 1: User level - application code and data
+//
+// R/W: Read/Write access
+// 0: read-only access
+// 1: read/write access
+//
+// P: Present
+// 0: Not present
+// 1: Present
+// ==========================================
+
+
+\f
+// Combined page directory/page table protection:
+// ==============================================
+// There is one column for the combined effect on a 386
+// and one column for the combined effect on a 486+ CPU.
+//
+// +----------------+-----------------+----------------+----------------+
+// | Page Directory| Page Table | Combined 386 | Combined 486+ |
+// |Privilege Type | Privilege Type | Privilege Type| Privilege Type|
+// |----------------+-----------------+----------------+----------------|
+// |User R | User R | User R | User R |
+// |User R | User RW | User R | User R |
+// |User RW | User R | User R | User R |
+// |User RW | User RW | User RW | User RW |
+// |User R | Supervisor R | User R | Supervisor RW |
+// |User R | Supervisor RW | User R | Supervisor RW |
+// |User RW | Supervisor R | User R | Supervisor RW |
+// |User RW | Supervisor RW | User RW | Supervisor RW |
+// |Supervisor R | User R | User R | Supervisor RW |
+// |Supervisor R | User RW | User R | Supervisor RW |
+// |Supervisor RW | User R | User R | Supervisor RW |
+// |Supervisor RW | User RW | User RW | Supervisor RW |
+// |Supervisor R | Supervisor R | Supervisor RW | Supervisor RW |
+// |Supervisor R | Supervisor RW | Supervisor RW | Supervisor RW |
+// |Supervisor RW | Supervisor R | Supervisor RW | Supervisor RW |
+// |Supervisor RW | Supervisor RW | Supervisor RW | Supervisor RW |
+// +----------------+-----------------+----------------+----------------+
+
+// Page Fault Error Code Format:
+// =============================
+//
+// bits 31..4: Reserved
+// bit 3: RSVD (Pentium Pro+)
+// 0: fault caused by reserved bits set to 1 in a page directory
+// when the PSE or PAE flags in CR4 are set to 1
+// 1: fault was not caused by reserved bit violation
+// bit 2: U/S (386+)
+// 0: fault originated when in supervior mode
+// 1: fault originated when in user mode
+// bit 1: R/W (386+)
+// 0: access causing the fault was a read
+// 1: access causing the fault was a write
+// bit 0: P (386+)
+// 0: fault caused by a nonpresent page
+// 1: fault caused by a page level protection violation
+
+
+// Some paging related notes:
+// ==========================
+//
+// - When the processor is running in supervisor level, all pages are both
+// readable and writable (write-protect ignored). When running at user
+// level, only pages which belong to the user level are accessible;
+// read/write & read-only are readable, read/write are writable.
+//
+// - If the Present bit is 0 in either level of page table, an
+// access which uses these entries will generate a page fault.
+//
+// - (A)ccess bit is used to report read or write access to a page
+// or 2nd level page table.
+//
+// - (D)irty bit is used to report write access to a page.
+//
+// - Processor running at CPL=0,1,2 maps to U/S=0
+// Processor running at CPL=3 maps to U/S=1
+//
+// - Pentium+ processors have separate TLB's for data and instruction caches
+// - Pentium Pro+ processors maintain separate 4K and 4M TLBs.
+#endif
+
+
+
+
+#if BX_SUPPORT_PAGING
+
+#define BX_INVALID_TLB_ENTRY 0xffffffff
+
+#if BX_CPU_LEVEL >= 4
+# define BX_PRIV_CHECK_SIZE 32
+#else
+# define BX_PRIV_CHECK_SIZE 16
+#endif
+
+// The 'priv_check' array is used to decide if the current access
+// has the proper paging permissions. An index is formed, based
+// on parameters such as the access type and level, the write protect
+// flag and values cached in the TLB. The format of the index into this
+// array is:
+//
+// |4 |3 |2 |1 |0 |
+// |wp|us|us|rw|rw|
+// | | | | |
+// | | | | +---> r/w of current access
+// | | +--+------> u/s,r/w combined of page dir & table (cached)
+// | +------------> u/s of current access
+// +---------------> Current CR0.wp value
+//
+// The TLB cache holds the following info, from which the above
+// fields can efficiently be extracted to facilitate a privilege check:
+//
+// |4 |3 |2 |1 |0 |
+// | | |us|rw|D |
+// | | |
+// | | +---> Dirty bit from PTE (not used for privilege check)
+// +--+------> u/s,r/w combined of page dir & table
+//
+//
+// The rest of the fields are taken from current access parameters
+// and the write-protect field:
+//
+// |4 |3 |2 |1 |0 |
+// |wp|us| | |rw|
+// | | |
+// | | +---> r/w of current access
+// | |
+// | +------------> u/s of current access
+// +---------------> Current CR0.wp value
+
+
+static unsigned priv_check[BX_PRIV_CHECK_SIZE];
+
+
+
+ void
+BX_CPU_C::enable_paging(void)
+{
+ TLB_flush();
+ if (bx_dbg.paging) BX_INFO(("enable_paging():\n"));
+//BX_DEBUG(( "enable_paging():-------------------------\n" ));
+}
+
+ void
+BX_CPU_C::disable_paging(void)
+{
+ TLB_flush();
+ if (bx_dbg.paging) BX_INFO(("disable_paging():\n"));
+}
+
+ void
+BX_CPU_C::CR3_change(Bit32u value32)
+{
+ if (bx_dbg.paging) {
+ BX_INFO(("CR3_change(): flush TLB cache\n"));
+ BX_INFO(("Page Directory Base %08x\n", (unsigned) value32));
+ }
+
+ // flush TLB even if value does not change
+ TLB_flush();
+ BX_CPU_THIS_PTR cr3 = value32;
+}
+
+ void
+BX_CPU_C::TLB_init(void)
+{
+ // Called to initialize the TLB upon startup.
+ // Unconditional initialization of all TLB entries.
+
+#if BX_USE_TLB
+ unsigned i;
+ unsigned wp, us_combined, rw_combined, us_current, rw_current;
+
+ for (i=0; i<BX_TLB_SIZE; i++) {
+ BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+ }
+
+ //
+ // Setup privilege check matrix.
+ //
+
+ for (i=0; i<BX_PRIV_CHECK_SIZE; i++) {
+ wp = (i & 0x10) >> 4;
+ us_current = (i & 0x08) >> 3;
+ us_combined = (i & 0x04) >> 2;
+ rw_combined = (i & 0x02) >> 1;
+ rw_current = (i & 0x01) >> 0;
+ if (wp) { // when write protect on
+ if (us_current > us_combined) // user access, supervisor page
+ priv_check[i] = 0;
+ else if (rw_current > rw_combined) // RW access, RO page
+ priv_check[i] = 0;
+ else
+ priv_check[i] = 1;
+ }
+ else { // when write protect off
+ if (us_current == 0) // Supervisor mode access, anything goes
+ priv_check[i] = 1;
+ else {
+ // user mode access
+ if (us_combined == 0) // user access, supervisor Page
+ priv_check[i] = 0;
+ else if (rw_current > rw_combined) // RW access, RO page
+ priv_check[i] = 0;
+ else
+ priv_check[i] = 1;
+ }
+ }
+ }
+
+#endif // #if BX_USE_TLB
+}
+
+ void
+BX_CPU_C::TLB_flush(void)
+{
+#if BX_USE_TLB
+ for (unsigned i=0; i<BX_TLB_SIZE; i++) {
+ BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+ }
+#endif // #if BX_USE_TLB
+
+ invalidate_prefetch_q();
+}
+
+ void
+BX_CPU_C::TLB_clear(void)
+{
+#if BX_USE_TLB
+ for (unsigned i=0; i<BX_TLB_SIZE; i++) {
+ BX_CPU_THIS_PTR TLB.entry[i].lpf = BX_INVALID_TLB_ENTRY;
+ }
+#endif // #if BX_USE_TLB
+}
+
+ void
+BX_CPU_C::INVLPG(BxInstruction_t* i)
+{
+#if BX_CPU_LEVEL >= 4
+ invalidate_prefetch_q();
+
+ // Operand must not be a register
+ if (i->mod == 0xc0) {
+ BX_INFO(("INVLPG: op is a register"));
+ UndefinedOpcode(i);
+ }
+ // Can not be executed in v8086 mode
+ if (v8086_mode())
+ exception(BX_GP_EXCEPTION, 0, 0);
+
+ // Protected instruction: CPL0 only
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ if (CPL!=0) {
+ BX_INFO(("INVLPG: CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+
+#if BX_USE_TLB
+ // Just clear the entire TLB, ugh!
+ TLB_clear();
+#endif // BX_USE_TLB
+ BX_INSTR_TLB_CNTRL(BX_INSTR_INVLPG, 0);
+
+#else
+ // not supported on < 486
+ UndefinedOpcode(i);
+#endif
+}
+
+
+// Translate a linear address to a physical address, for
+// a data access (D)
+
+ Bit32u
+BX_CPU_C::dtranslate_linear(Bit32u laddress, unsigned pl, unsigned rw)
+{
+ Bit32u lpf, ppf, poffset, TLB_index, error_code, paddress;
+ Bit32u pde, pde_addr;
+ Bit32u pte, pte_addr;
+ unsigned priv_index;
+ Boolean is_rw;
+ Bit32u combined_access, new_combined_access;
+
+ lpf = laddress & 0xfffff000; // linear page frame
+ poffset = laddress & 0x00000fff; // physical offset
+ TLB_index = BX_TLB_INDEX_OF(lpf);
+
+
+ is_rw = (rw>=BX_WRITE); // write or r-m-w
+
+ if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+ paddress = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+ combined_access = BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access;
+priv_check:
+ priv_index =
+#if BX_CPU_LEVEL >= 4
+ (BX_CPU_THIS_PTR cr0.wp<<4) | // bit 4
+#endif
+ (pl<<3) | // bit 3
+ (combined_access & 0x06) | // bit 2,1
+ is_rw; // bit 0
+
+ if (priv_check[priv_index]) {
+ // Operation has proper privilege.
+ // See if A/D bits need updating.
+ //BW !! a read access does not do any updates, patched load
+ new_combined_access = combined_access | is_rw;
+ if (new_combined_access == combined_access) {
+ // A/D bits already up-to-date
+ return(paddress);
+ }
+
+ // A/D bits need updating first
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = new_combined_access;
+ pte_addr = BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr;
+ BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte); // get old PTE
+ pte |= 0x20 | (is_rw << 6);
+ BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte); // write updated PTE
+ return(paddress);
+ }
+
+ // Protection violation
+ error_code = 0xfffffff9; // RSVD=1, P=1
+ goto page_fault_check;
+ }
+
+ // Get page dir entry
+ pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+ ((laddress & 0xffc00000) >> 20);
+ BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+ if ( !(pde & 0x01) ) {
+ // Page Directory Entry NOT present
+ error_code = 0xfffffff8; // RSVD=1, P=0
+ goto page_fault_not_present;
+ }
+
+ // Get page table entry
+ pte_addr = (pde & 0xfffff000) |
+ ((laddress & 0x003ff000) >> 10);
+ BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+
+ // update PDE if A bit was not set before
+ if ( !(pde & 0x20) ) {
+ pde |= 0x20;
+ BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
+ }
+
+ if ( !(pte & 0x01) ) {
+ // Page Table Entry NOT present
+ error_code = 0xfffffff8; // RSVD=1, P=0
+ goto page_fault_not_present;
+ }
+
+ //BW added: update PTE if A bit was not set before
+ if ( !(pte & 0x20) ) {
+ pte |= 0x20;
+ BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
+ }
+
+ // 386 and 486+ have different bahaviour for combining
+ // privilege from PDE and PTE.
+#if BX_CPU_LEVEL == 3
+ combined_access = (pde | pte) & 0x04; // U/S
+ combined_access |= (pde & pte) & 0x02; // R/W
+#else // 486+
+ combined_access = (pde & pte) & 0x06; // U/S and R/W
+#endif
+
+ ppf = pte & 0xfffff000;
+ paddress = ppf | poffset;
+
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = lpf;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf = ppf;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr = pte_addr;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = combined_access;
+ goto priv_check;
+
+
+page_fault_check:
+// (mch) Define RMW_WRITES for old behavior
+#if !defined(RMW_WRITES)
+ /* (mch) Ok, so we know it's a page fault. It the access is a
+ read-modify-write access we check if the read faults, if it
+ does then we (optionally) do not set the write bit */
+ if (rw == BX_RW) {
+ priv_index =
+#if BX_CPU_LEVEL >= 4
+ (BX_CPU_THIS_PTR cr0.wp<<4) | // bit 4
+#endif
+ (pl<<3) | // bit 3
+ (combined_access & 0x06) | // bit 2,1
+ 0; // bit 0 (read)
+ if (!priv_check[priv_index]) {
+ // Fault on read
+ is_rw = 0;
+ }
+ }
+#endif /* RMW_WRITES */
+ goto page_fault_proper;
+
+page_fault_not_present:
+#if !defined(RMW_WRITES)
+ if (rw == BX_RW)
+ is_rw = 0;
+#endif /* RMW_WRITES */
+ goto page_fault_proper;
+
+ page_fault_proper:
+ error_code |= (pl << 2) | (is_rw << 1);
+ BX_CPU_THIS_PTR cr2 = laddress;
+ // invalidate entry - we can get away without maintaining A bit in PTE
+ // if we don't maintain TLB entries without it set.
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
+ exception(BX_PF_EXCEPTION, error_code, 0);
+ return(0); // keep compiler happy
+}
+
+
+// Translate a linear address to a physical address, for
+// an instruction fetch access (I)
+
+ Bit32u
+BX_CPU_C::itranslate_linear(Bit32u laddress, unsigned pl)
+{
+ Bit32u lpf, ppf, poffset, TLB_index, error_code, paddress;
+ Bit32u pde, pde_addr;
+ Bit32u pte, pte_addr;
+ unsigned priv_index;
+ Bit32u combined_access;
+
+ lpf = laddress & 0xfffff000; // linear page frame
+ poffset = laddress & 0x00000fff; // physical offset
+ TLB_index = BX_TLB_INDEX_OF(lpf);
+
+
+ if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+ paddress = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+ combined_access = BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access;
+priv_check:
+ priv_index =
+#if BX_CPU_LEVEL >= 4
+ (BX_CPU_THIS_PTR cr0.wp<<4) | // bit 4
+#endif
+ (pl<<3) | // bit 3
+ (combined_access & 0x06); // bit 2,1
+ // bit 0 == 0
+
+ if (priv_check[priv_index]) {
+ // Operation has proper privilege.
+ return(paddress);
+ }
+
+ // Protection violation
+ error_code = 0xfffffff9; // RSVD=1, P=1
+ goto page_fault;
+ }
+
+ // Get page dir entry
+ pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+ ((laddress & 0xffc00000) >> 20);
+ BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+ if ( !(pde & 0x01) ) {
+ // Page Directory Entry NOT present
+ error_code = 0xfffffff8; // RSVD=1, P=0
+ goto page_fault;
+ }
+
+ // Get page table entry
+ pte_addr = (pde & 0xfffff000) |
+ ((laddress & 0x003ff000) >> 10);
+ BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+
+ // update PDE if A bit was not set before
+ if ( !(pde & 0x20) ) {
+ pde |= 0x20;
+ BX_CPU_THIS_PTR mem->write_physical(this, pde_addr, 4, &pde);
+ }
+
+ if ( !(pte & 0x01) ) {
+ // Page Table Entry NOT present
+ error_code = 0xfffffff8; // RSVD=1, P=0
+ goto page_fault;
+ }
+
+ //BW added: update PTE if A bit was not set before
+ if ( !(pte & 0x20) ) {
+ pte |= 0x20;
+ BX_CPU_THIS_PTR mem->write_physical(this, pte_addr, 4, &pte);
+ }
+
+ // 386 and 486+ have different bahaviour for combining
+ // privilege from PDE and PTE.
+#if BX_CPU_LEVEL == 3
+ combined_access = (pde | pte) & 0x04; // U/S
+ combined_access |= (pde & pte) & 0x02; // R/W
+#else // 486+
+ combined_access = (pde & pte) & 0x06; // U/S and R/W
+#endif
+
+ ppf = pte & 0xfffff000;
+ paddress = ppf | poffset;
+
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = lpf;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf = ppf;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].pte_addr = pte_addr;
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].combined_access = combined_access;
+ goto priv_check;
+
+
+page_fault:
+ error_code |= (pl << 2);
+ BX_CPU_THIS_PTR cr2 = laddress;
+ // invalidate entry - we can get away without maintaining A bit in PTE
+ // if we don't maintain TLB entries without it set.
+ BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = BX_INVALID_TLB_ENTRY;
+ exception(BX_PF_EXCEPTION, error_code, 0);
+ return(0); // keep compiler happy
+}
+
+
+#if BX_DEBUGGER || BX_DISASM || BX_INSTRUMENTATION
+
+ void
+BX_CPU_C::dbg_xlate_linear2phy(Bit32u laddress, Bit32u *phy, Boolean *valid)
+{
+ Bit32u lpf, ppf, poffset, TLB_index, paddress;
+ Bit32u pde, pde_addr;
+ Bit32u pte, pte_addr;
+
+ if (BX_CPU_THIS_PTR cr0.pg == 0) {
+ *phy = laddress;
+ *valid = 1;
+ return;
+ }
+
+ lpf = laddress & 0xfffff000; // linear page frame
+ poffset = laddress & 0x00000fff; // physical offset
+ TLB_index = BX_TLB_INDEX_OF(lpf);
+
+ // see if page is in the TLB first
+ if (BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf == lpf) {
+ paddress = BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf | poffset;
+ *phy = paddress;
+ *valid = 1;
+ return;
+ }
+
+ // Get page dir entry
+ pde_addr = (BX_CPU_THIS_PTR cr3 & 0xfffff000) |
+ ((laddress & 0xffc00000) >> 20);
+ BX_CPU_THIS_PTR mem->read_physical(this, pde_addr, 4, &pde);
+ if ( !(pde & 0x01) ) {
+ // Page Directory Entry NOT present
+ goto page_fault;
+ }
+
+ // Get page table entry
+ pte_addr = (pde & 0xfffff000) |
+ ((laddress & 0x003ff000) >> 10);
+ BX_CPU_THIS_PTR mem->read_physical(this, pte_addr, 4, &pte);
+ if ( !(pte & 0x01) ) {
+ // Page Table Entry NOT present
+ goto page_fault;
+ }
+
+ ppf = pte & 0xfffff000;
+ paddress = ppf | poffset;
+
+ *phy = paddress;
+ *valid = 1;
+ return;
+
+page_fault:
+ *phy = 0;
+ *valid = 0;
+ return;
+}
+#endif
+
+
+
+ void
+BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
+ unsigned rw, void *data)
+{
+ Bit32u mod4096;
+ unsigned xlate_rw;
+
+
+#if BX_X86_DEBUGGER
+ if ( BX_CPU_THIS_PTR dr7 & 0x000000ff ) {
+ // Only compare debug registers if any breakpoints are enabled
+ Bit32u dr6_bits;
+ unsigned opa, opb;
+ opa = BX_HWDebugMemRW; // Read or Write always compares vs 11b
+ if (rw==BX_READ) // only compares vs 11b
+ opb = opa;
+ else // BX_WRITE or BX_RW; also compare vs 01b
+ opb = BX_HWDebugMemW;
+ dr6_bits = hwdebug_compare(laddress, length, opa, opb);
+ if (dr6_bits) {
+ BX_CPU_THIS_PTR debug_trap |= dr6_bits;
+ BX_CPU_THIS_PTR async_event = 1;
+ }
+ }
+#endif
+
+ if (rw==BX_RW) {
+ xlate_rw = BX_RW;
+ rw = BX_READ;
+ }
+ else {
+ xlate_rw = rw;
+ }
+
+
+ // perhaps put this check before all code which calls this function,
+ // so we don't have to here
+
+ if (BX_CPU_THIS_PTR cr0.pg) {
+ /* check for reference across multiple pages */
+ mod4096 = laddress & 0x00000fff;
+ if ( (mod4096 + length) <= 4096 ) {
+ // Bit32u paddress1;
+
+ /* access within single page */
+ BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
+ BX_CPU_THIS_PTR address_xlation.pages = 1;
+
+ if (rw == BX_READ) {
+ BX_INSTR_LIN_READ(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
+ BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
+ }
+ else {
+ BX_INSTR_LIN_WRITE(laddress, BX_CPU_THIS_PTR address_xlation.paddress1, length);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1, length, data);
+ }
+ return;
+ }
+ else {
+ // access across 2 pages
+ BX_CPU_THIS_PTR address_xlation.paddress1 = dtranslate_linear(laddress, pl, xlate_rw);
+ BX_CPU_THIS_PTR address_xlation.len1 = 4096 - mod4096;
+ BX_CPU_THIS_PTR address_xlation.len2 = length - BX_CPU_THIS_PTR address_xlation.len1;
+ BX_CPU_THIS_PTR address_xlation.pages = 2;
+
+ BX_CPU_THIS_PTR address_xlation.paddress2 = dtranslate_linear(laddress + BX_CPU_THIS_PTR address_xlation.len1, pl, xlate_rw);
+
+#ifdef BX_LITTLE_ENDIAN
+ if (rw == BX_READ) {
+ BX_INSTR_LIN_READ(laddress,
+ BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1);
+ BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1, data);
+ BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+ BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2);
+ BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2,
+ ((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
+ }
+ else {
+ BX_INSTR_LIN_WRITE(laddress,
+ BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1, data);
+ BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+ BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2,
+ ((Bit8u*)data) + BX_CPU_THIS_PTR address_xlation.len1);
+ }
+
+#else // BX_BIG_ENDIAN
+ if (rw == BX_READ) {
+ BX_INSTR_LIN_READ(laddress,
+ BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1);
+ BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1,
+ ((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
+ BX_INSTR_LIN_READ(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+ BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2);
+ BX_CPU_THIS_PTR mem->read_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2, data);
+ }
+ else {
+ BX_INSTR_LIN_WRITE(laddress,
+ BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress1,
+ BX_CPU_THIS_PTR address_xlation.len1,
+ ((Bit8u*)data) + (length - BX_CPU_THIS_PTR address_xlation.len1));
+ BX_INSTR_LIN_WRITE(laddress + BX_CPU_THIS_PTR address_xlation.len1,
+ BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2);
+ BX_CPU_THIS_PTR mem->write_physical(this, BX_CPU_THIS_PTR address_xlation.paddress2,
+ BX_CPU_THIS_PTR address_xlation.len2, data);
+ }
+#endif
+
+ return;
+ }
+ }
+ else {
+ // paging off, pass linear address thru to physical
+ if (rw == BX_READ) {
+ BX_INSTR_LIN_READ(laddress, laddress, length);
+ BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
+ }
+ else {
+ BX_INSTR_LIN_WRITE(laddress, laddress, length);
+ BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
+ }
+ return;
+ }
+}
+
+
+
+
+
+
+
+
+#else // BX_SUPPORT_PAGING
+
+// stub functions for non-support of paging
+ void
+BX_CPU_C::enable_paging(void)
+{
+ BX_PANIC(("enable_paging(): not implemented\n"));
+}
+
+ void
+BX_CPU_C::disable_paging(void)
+{
+ BX_PANIC(("disable_paging() called\n"));
+}
+
+ void
+BX_CPU_C::CR3_change(Bit32u value32)
+{
+ BX_INFO(("CR3_change(): flush TLB cache\n"));
+ BX_INFO(("Page Directory Base %08x\n", (unsigned) value32));
+}
+
+
+ void
+BX_CPU_C::access_linear(Bit32u laddress, unsigned length, unsigned pl,
+ unsigned rw, void *data)
+{
+ /* perhaps put this check before all code which calls this function,
+ * so we don't have to here
+ */
+ if (BX_CPU_THIS_PTR cr0.pg == 0) {
+ if (rw == BX_READ)
+ BX_CPU_THIS_PTR mem->read_physical(this, laddress, length, data);
+ else
+ BX_CPU_THIS_PTR mem->write_physical(this, laddress, length, data);
+ return;
+ }
+
+ BX_PANIC(("access_linear: paging not supported\n"));
+}
+
+ void
+BX_CPU_C::INVLPG(BxInstruction_t* i)
+{}
+
+#endif // BX_SUPPORT_PAGING
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+ void
+BX_CPU_C::UndefinedOpcode(BxInstruction_t *i)
+{
+ if (i->b1 != 0x63) {
+ // Windows hits the ARPL command a bunch of times.
+ // Too much spew...
+ BX_INFO(("UndefinedOpcode: %02x causes exception 6\n",
+ (unsigned) i->b1));
+ }
+ exception(BX_UD_EXCEPTION, 0, 0);
+}
+
+ void
+BX_CPU_C::NOP(BxInstruction_t *i)
+{
+}
+
+
+ void
+BX_CPU_C::HLT(BxInstruction_t *i)
+{
+ // hack to panic if HLT comes from BIOS
+ if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value == 0xf000 )
+ BX_PANIC(("HALT instruction encountered\n"));
+
+ if (CPL!=0) {
+ BX_INFO(("HLT(): CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if ( ! BX_CPU_THIS_PTR eflags.if_ ) {
+ BX_INFO(("WARNING: HLT instruction with IF=0!\n"));
+ }
+
+ // stops instruction execution and places the processor in a
+ // HALT state. An enabled interrupt, NMI, or reset will resume
+ // execution. If interrupt (including NMI) is used to resume
+ // execution after HLT, the saved CS:eIP points to instruction
+ // following HLT.
+
+ // artificial trap bit, why use another variable.
+ BX_CPU_THIS_PTR debug_trap |= 0x80000000; // artificial trap
+ BX_CPU_THIS_PTR async_event = 1; // so processor knows to check
+ // Execution of this instruction completes. The processor
+ // will remain in a halt state until one of the above conditions
+ // is met.
+}
+
+
+ void
+BX_CPU_C::CLTS(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("CLTS: not implemented for < 286\n"));
+#else
+
+ if (v8086_mode()) BX_PANIC(("clts: v8086 mode unsupported\n"));
+
+ /* read errata file */
+ // does CLTS also clear NT flag???
+
+ // #GP(0) if CPL is not 0
+ if (CPL!=0) {
+ BX_INFO(("CLTS(): CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ BX_CPU_THIS_PTR cr0.ts = 0;
+ BX_CPU_THIS_PTR cr0.val32 &= ~0x08;
+#endif
+}
+
+ void
+BX_CPU_C::INVD(BxInstruction_t *i)
+{
+ BX_INFO(("---------------\n"));
+ BX_INFO(("- INVD called -\n"));
+ BX_INFO(("---------------\n"));
+
+#if BX_CPU_LEVEL >= 4
+ invalidate_prefetch_q();
+
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ if (CPL!=0) {
+ BX_INFO(("INVD: CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+ BX_INSTR_CACHE_CNTRL(BX_INSTR_INVD);
+#else
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::WBINVD(BxInstruction_t *i)
+{
+ BX_INFO(("WBINVD: (ignoring)\n"));
+
+#if BX_CPU_LEVEL >= 4
+ invalidate_prefetch_q();
+
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ if (CPL!=0) {
+ BX_INFO(("WBINVD: CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+ }
+ BX_INSTR_CACHE_CNTRL(BX_INSTR_WBINVD);
+#else
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::MOV_DdRd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_DdRd: not supported on < 386\n"));
+#else
+ Bit32u val_32;
+
+ if (v8086_mode()) BX_PANIC(("MOV_DdRd: v8086 mode unsupported\n"));
+
+ /* NOTES:
+ * 32bit operands always used
+ * r/m field specifies general register
+ * mod field should always be 11 binary
+ * reg field specifies which special register
+ */
+
+ if (i->mod != 0xc0) {
+ BX_PANIC(("MOV_DdRd(): rm field not a register!\n"));
+ }
+
+ invalidate_prefetch_q();
+
+ if (protected_mode() && CPL!=0) {
+ BX_PANIC(("MOV_DdRd: CPL!=0\n"));
+ /* #GP(0) if CPL is not 0 */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ val_32 = BX_READ_32BIT_REG(i->rm);
+#if BX_DEBUGGER
+ if (bx_dbg.dreg)
+ BX_INFO(("MOV_DdRd: DR[%u]=%08xh unhandled\n",
+ (unsigned) i->nnn, (unsigned) val_32));
+#endif
+
+ switch (i->nnn) {
+ case 0: // DR0
+ BX_CPU_THIS_PTR dr0 = val_32;
+ break;
+ case 1: // DR1
+ BX_CPU_THIS_PTR dr1 = val_32;
+ break;
+ case 2: // DR2
+ BX_CPU_THIS_PTR dr2 = val_32;
+ break;
+ case 3: // DR3
+ BX_CPU_THIS_PTR dr3 = val_32;
+ break;
+
+ case 4: // DR4
+ case 6: // DR6
+ // DR4 aliased to DR6 by default. With Debug Extensions on,
+ // access to DR4 causes #UD
+#if BX_CPU_LEVEL >= 4
+ if ( (i->nnn == 4) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+ // Debug extensions on
+ BX_INFO(("MOV_DdRd: access to DR4 causes #UD\n"));
+ UndefinedOpcode(i);
+ }
+#endif
+#if BX_CPU_LEVEL <= 4
+ // On 386/486 bit12 is settable
+ BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
+ (val_32 & 0x0000f00f);
+#else
+ // On Pentium+, bit12 is always zero
+ BX_CPU_THIS_PTR dr6 = (BX_CPU_THIS_PTR dr6 & 0xffff0ff0) |
+ (val_32 & 0x0000e00f);
+#endif
+ break;
+
+ case 5: // DR5
+ case 7: // DR7
+ // Note: 486+ ignore GE and LE flags. On the 386, exact
+ // data breakpoint matching does not occur unless it is enabled
+ // by setting the LE and/or GE flags.
+
+ // DR5 aliased to DR7 by default. With Debug Extensions on,
+ // access to DR5 causes #UD
+#if BX_CPU_LEVEL >= 4
+ if ( (i->nnn == 5) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+ // Debug extensions (CR4.DE) on
+ BX_INFO(("MOV_DdRd: access to DR5 causes #UD\n"));
+ UndefinedOpcode(i);
+ }
+#endif
+ // Some sanity checks...
+ if ( val_32 & 0x00002000 ) {
+ BX_PANIC(("MOV_DdRd: GD bit not supported yet\n"));
+ // Note: processor clears GD upon entering debug exception
+ // handler, to allow access to the debug registers
+ }
+ if ( (((val_32>>16) & 3)==2) ||
+ (((val_32>>20) & 3)==2) ||
+ (((val_32>>24) & 3)==2) ||
+ (((val_32>>28) & 3)==2) ) {
+ // IO breakpoints (10b) are not yet supported.
+ BX_PANIC(("MOV_DdRd: write of %08x contains IO breakpoint\n",
+ val_32));
+ }
+ if ( (((val_32>>18) & 3)==2) ||
+ (((val_32>>22) & 3)==2) ||
+ (((val_32>>26) & 3)==2) ||
+ (((val_32>>30) & 3)==2) ) {
+ // LEN0..3 contains undefined length specifier (10b)
+ BX_PANIC(("MOV_DdRd: write of %08x contains undefined LENx\n",
+ val_32));
+ }
+ if ( ((((val_32>>16) & 3)==0) && (((val_32>>18) & 3)!=0)) ||
+ ((((val_32>>20) & 3)==0) && (((val_32>>22) & 3)!=0)) ||
+ ((((val_32>>24) & 3)==0) && (((val_32>>26) & 3)!=0)) ||
+ ((((val_32>>28) & 3)==0) && (((val_32>>30) & 3)!=0)) ) {
+ // Instruction breakpoint with LENx not 00b (1-byte length)
+ BX_PANIC(("MOV_DdRd: write of %08x, R/W=00b LEN!=00b\n",
+ val_32));
+ }
+#if BX_CPU_LEVEL <= 4
+ // 386/486: you can play with all the bits except b10 is always 1
+ BX_CPU_THIS_PTR dr7 = val_32 | 0x00000400;
+#else
+ // Pentium+: bits15,14,12 are hardwired to 0, rest are settable.
+ // Even bits 11,10 are changeable though reserved.
+ BX_CPU_THIS_PTR dr7 = (val_32 & 0xffff2fff) | 0x00000400;
+#endif
+ break;
+ default:
+ BX_PANIC(("MOV_DdRd: control register index out of range\n"));
+ break;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::MOV_RdDd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_RdDd: not supported on < 386\n"));
+#else
+ Bit32u val_32;
+
+ if (v8086_mode()) {
+ BX_INFO(("MOV_RdDd: v8086 mode causes #GP\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ if (i->mod != 0xc0) {
+ BX_PANIC(("MOV_RdDd(): rm field not a register!\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (protected_mode() && (CPL!=0)) {
+ BX_INFO(("MOV_RdDd: CPL!=0 causes #GP\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+#if BX_DEBUGGER
+ if (bx_dbg.dreg)
+ BX_INFO(("MOV_RdDd: DR%u not implemented yet\n", i->nnn));
+#endif
+
+ switch (i->nnn) {
+ case 0: // DR0
+ val_32 = BX_CPU_THIS_PTR dr0;
+ break;
+ case 1: // DR1
+ val_32 = BX_CPU_THIS_PTR dr1;
+ break;
+ case 2: // DR2
+ val_32 = BX_CPU_THIS_PTR dr2;
+ break;
+ case 3: // DR3
+ val_32 = BX_CPU_THIS_PTR dr3;
+ break;
+
+ case 4: // DR4
+ case 6: // DR6
+ // DR4 aliased to DR6 by default. With Debug Extensions on,
+ // access to DR4 causes #UD
+#if BX_CPU_LEVEL >= 4
+ if ( (i->nnn == 4) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+ // Debug extensions on
+ BX_INFO(("MOV_RdDd: access to DR4 causes #UD\n"));
+ UndefinedOpcode(i);
+ }
+#endif
+ val_32 = BX_CPU_THIS_PTR dr6;
+ break;
+
+ case 5: // DR5
+ case 7: // DR7
+ // DR5 aliased to DR7 by default. With Debug Extensions on,
+ // access to DR5 causes #UD
+#if BX_CPU_LEVEL >= 4
+ if ( (i->nnn == 5) && (BX_CPU_THIS_PTR cr4 & 0x00000008) ) {
+ // Debug extensions on
+ BX_INFO(("MOV_RdDd: access to DR5 causes #UD\n"));
+ UndefinedOpcode(i);
+ }
+#endif
+ val_32 = BX_CPU_THIS_PTR dr7;
+ break;
+
+ default:
+ BX_PANIC(("MOV_RdDd: control register index out of range\n"));
+ val_32 = 0;
+ }
+ BX_WRITE_32BIT_REG(i->rm, val_32);
+#endif
+}
+
+
+ void
+BX_CPU_C::LMSW_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LMSW_Ew(): not supported on 8086!\n"));
+#else
+ Bit16u msw;
+ Bit32u cr0;
+
+ if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+ if ( protected_mode() ) {
+ if ( CPL != 0 ) {
+ BX_INFO(("LMSW: CPL != 0, CPL=%u\n", (unsigned) CPL));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ if (i->mod == 0xc0) {
+ msw = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_word(i->seg, i->rm_addr, &msw);
+ }
+
+ // LMSW does not affect PG,CD,NW,AM,WP,NE,ET bits, and cannot clear PE
+
+ // LMSW cannot clear PE
+ if ( ((msw & 0x0001)==0) && BX_CPU_THIS_PTR cr0.pe ) {
+ msw |= 0x0001; // adjust PE bit to current value of 1
+ }
+
+ msw &= 0x000f; // LMSW only affects last 4 flags
+ cr0 = (BX_CPU_THIS_PTR cr0.val32 & 0xfffffff0) | msw;
+ SetCR0(cr0);
+#endif /* BX_CPU_LEVEL < 2 */
+}
+
+ void
+BX_CPU_C::SMSW_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("SMSW_Ew: not supported yet!\n"));
+#else
+ Bit16u msw;
+
+
+#if BX_CPU_LEVEL == 2
+ msw = 0xfff0; /* 80286 init value */
+ msw |= (BX_CPU_THIS_PTR cr0.ts << 3) |
+ (BX_CPU_THIS_PTR cr0.em << 2) |
+ (BX_CPU_THIS_PTR cr0.mp << 1) |
+ BX_CPU_THIS_PTR cr0.pe;
+#else /* 386+ */
+ /* reserved bits 0 ??? */
+ /* should NE bit be included here ??? */
+ // should ET bit be included here (AW)
+ msw = (BX_CPU_THIS_PTR cr0.ts << 3) |
+ (BX_CPU_THIS_PTR cr0.em << 2) |
+ (BX_CPU_THIS_PTR cr0.mp << 1) |
+ BX_CPU_THIS_PTR cr0.pe;
+#endif
+
+
+ if (i->mod == 0xc0) {
+ if (i->os_32) {
+ BX_WRITE_32BIT_REG(i->rm, msw); // zeros out high 16bits
+ }
+ else {
+ BX_WRITE_16BIT_REG(i->rm, msw);
+ }
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &msw);
+ }
+
+#endif
+}
+
+
+ void
+BX_CPU_C::MOV_CdRd(BxInstruction_t *i)
+{
+ // mov general register data to control register
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_CdRd: not supported on < 386\n"));
+#else
+ Bit32u val_32;
+
+
+ if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+ /* NOTES:
+ * 32bit operands always used
+ * r/m field specifies general register
+ * mod field should always be 11 binary
+ * reg field specifies which special register
+ */
+
+ if (i->mod != 0xc0) {
+ BX_PANIC(("MOV_CdRd(): rm field not a register!\n"));
+ }
+
+ invalidate_prefetch_q();
+
+ if (protected_mode() && CPL!=0) {
+ BX_PANIC(("MOV_CdRd: CPL!=0\n"));
+ /* #GP(0) if CPL is not 0 */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ val_32 = BX_READ_32BIT_REG(i->rm);
+
+ switch (i->nnn) {
+ case 0: // CR0 (MSW)
+ // BX_INFO(("MOV_CdRd:CR0: R32 = %08x\n @CS:EIP %04x:%04x ",
+ // (unsigned) val_32,
+ // (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ // (unsigned) BX_CPU_THIS_PTR eip));
+ SetCR0(val_32);
+ break;
+
+ case 1: /* CR1 */
+ BX_PANIC(("MOV_CdRd: CR1 not implemented yet\n"));
+ break;
+ case 2: /* CR2 */
+ BX_INFO(("MOV_CdRd: CR2 not implemented yet\n"));
+#if BX_DEBUGGER
+ if (bx_dbg.creg)
+ BX_INFO(("MOV_CdRd: CR2 = reg\n"));
+#endif
+ BX_CPU_THIS_PTR cr2 = val_32;
+ break;
+ case 3: // CR3
+#if BX_DEBUGGER
+ if (bx_dbg.creg)
+ BX_INFO(("MOV_CdRd:CR3 = %08x\n", (unsigned) val_32));
+#endif
+ // Reserved bits take on value of MOV instruction
+ CR3_change(val_32);
+ BX_INSTR_TLB_CNTRL(BX_INSTR_MOV_CR3, val_32);
+ break;
+ case 4: // CR4
+#if BX_CPU_LEVEL == 3
+ BX_PANIC(("MOV_CdRd: write to CR4 of 0x%08x on 386\n",
+ val_32));
+ UndefinedOpcode(i);
+#else
+ // Protected mode: #GP(0) if attempt to write a 1 to
+ // any reserved bit of CR4
+
+ BX_INFO(("MOV_CdRd: ignoring write to CR4 of 0x%08x\n",
+ val_32));
+ if (val_32) {
+ BX_INFO(("MOV_CdRd: (CR4) write of 0x%08x not supported!\n",
+ val_32));
+ }
+ // Only allow writes of 0 to CR4 for now.
+ // Writes to bits in CR4 should not be 1s as CPUID
+ // returns not-supported for all of these features.
+ BX_CPU_THIS_PTR cr4 = 0;
+#endif
+ break;
+ default:
+ BX_PANIC(("MOV_CdRd: control register index out of range\n"));
+ break;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::MOV_RdCd(BxInstruction_t *i)
+{
+ // mov control register data to register
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_RdCd: not supported on < 386\n"));
+#else
+ Bit32u val_32;
+
+ if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+ /* NOTES:
+ * 32bit operands always used
+ * r/m field specifies general register
+ * mod field should always be 11 binary
+ * reg field specifies which special register
+ */
+
+ if (i->mod != 0xc0) {
+ BX_PANIC(("MOV_RdCd(): rm field not a register!\n"));
+ }
+
+ if (protected_mode() && CPL!=0) {
+ BX_PANIC(("MOV_RdCd: CPL!=0\n"));
+ /* #GP(0) if CPL is not 0 */
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ switch (i->nnn) {
+ case 0: // CR0 (MSW)
+ val_32 = BX_CPU_THIS_PTR cr0.val32;
+#if 0
+ BX_INFO(("MOV_RdCd:CR0: R32 = %08x\n @CS:EIP %04x:%04x\n",
+ (unsigned) val_32,
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ (unsigned) BX_CPU_THIS_PTR eip));
+#endif
+ break;
+ case 1: /* CR1 */
+ BX_PANIC(("MOV_RdCd: CR1 not implemented yet\n"));
+ val_32 = 0;
+ break;
+ case 2: /* CR2 */
+#if BX_DEBUGGER
+ if (bx_dbg.creg)
+ BX_INFO(("MOV_RdCd: CR2\n"));
+#endif
+ val_32 = BX_CPU_THIS_PTR cr2;
+ break;
+ case 3: // CR3
+#if BX_DEBUGGER
+ if (bx_dbg.creg)
+ BX_INFO(("MOV_RdCd: reading CR3\n"));
+#endif
+ val_32 = BX_CPU_THIS_PTR cr3;
+ break;
+ case 4: // CR4
+#if BX_CPU_LEVEL == 3
+ val_32 = 0;
+ BX_INFO(("MOV_RdCd: read of CR4 causes #UD\n"));
+ UndefinedOpcode(i);
+#else
+ BX_INFO(("MOV_RdCd: read of CR4\n"));
+ val_32 = BX_CPU_THIS_PTR cr4;
+#endif
+ break;
+ default:
+ BX_PANIC(("MOV_RdCd: control register index out of range\n"));
+ val_32 = 0;
+ }
+ BX_WRITE_32BIT_REG(i->rm, val_32);
+#endif
+}
+
+ void
+BX_CPU_C::MOV_TdRd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_TdRd:\n"));
+#elif BX_CPU_LEVEL <= 4
+ BX_PANIC(("MOV_TdRd:\n"));
+#else
+ // Pentium+ does not have TRx. They were redesigned using the MSRs.
+ BX_INFO(("MOV_TdRd: causes #UD\n"));
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::MOV_RdTd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("MOV_RdTd:\n"));
+#elif BX_CPU_LEVEL <= 4
+ BX_PANIC(("MOV_RdTd:\n"));
+#else
+ // Pentium+ does not have TRx. They were redesigned using the MSRs.
+ BX_INFO(("MOV_RdTd: causes #UD\n"));
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::LOADALL(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("undocumented LOADALL instruction not supported on 8086\n"));
+#else
+ Bit16u msw, tr, flags, ip, ldtr;
+ Bit16u ds_raw, ss_raw, cs_raw, es_raw;
+ Bit16u di, si, bp, sp, bx, dx, cx, ax;
+ Bit16u base_15_0, limit;
+ Bit8u base_23_16, access;
+
+ if (v8086_mode()) BX_PANIC(("proc_ctrl: v8086 mode unsupported\n"));
+
+#if BX_CPU_LEVEL > 2
+ BX_PANIC(("loadall: not implemented for 386\n"));
+ /* ??? need to set G and other bits, and compute .limit_scaled also */
+ /* for all segments CS,DS,SS,... */
+#endif
+
+ if (BX_CPU_THIS_PTR cr0.pe) {
+ BX_PANIC((
+ "LOADALL not yet supported for protected mode\n"));
+ }
+
+BX_PANIC(("LOADALL: handle CR0.val32\n"));
+ /* MSW */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x806, 2, &msw);
+ BX_CPU_THIS_PTR cr0.pe = (msw & 0x01); msw >>= 1;
+ BX_CPU_THIS_PTR cr0.mp = (msw & 0x01); msw >>= 1;
+ BX_CPU_THIS_PTR cr0.em = (msw & 0x01); msw >>= 1;
+ BX_CPU_THIS_PTR cr0.ts = (msw & 0x01);
+
+ //BX_INFO(("LOADALL: pe=%u, mp=%u, em=%u, ts=%u\n",
+ // (unsigned) BX_CPU_THIS_PTR cr0.pe, (unsigned) BX_CPU_THIS_PTR cr0.mp,
+ // (unsigned) BX_CPU_THIS_PTR cr0.em, (unsigned) BX_CPU_THIS_PTR cr0.ts));
+
+ if (BX_CPU_THIS_PTR cr0.pe || BX_CPU_THIS_PTR cr0.mp || BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts)
+ BX_PANIC(("LOADALL set PE, MP, EM or TS bits in MSW!\n"));
+
+ /* TR */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x816, 2, &tr);
+ BX_CPU_THIS_PTR tr.selector.value = tr;
+ BX_CPU_THIS_PTR tr.selector.rpl = (tr & 0x03); tr >>= 2;
+ BX_CPU_THIS_PTR tr.selector.ti = (tr & 0x01); tr >>= 1;
+ BX_CPU_THIS_PTR tr.selector.index = tr;
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x860, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x862, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x863, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x864, 2, &limit);
+
+
+ BX_CPU_THIS_PTR tr.cache.valid =
+ BX_CPU_THIS_PTR tr.cache.p = (access & 0x80) >> 7;
+ BX_CPU_THIS_PTR tr.cache.dpl = (access & 0x60) >> 5;
+ BX_CPU_THIS_PTR tr.cache.segment = (access & 0x10) >> 4;
+ BX_CPU_THIS_PTR tr.cache.type = (access & 0x0f);
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR tr.cache.u.tss286.limit = limit;
+
+ if ( (BX_CPU_THIS_PTR tr.selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ }
+ if ( BX_CPU_THIS_PTR tr.cache.valid == 0 ) {
+ }
+ if ( BX_CPU_THIS_PTR tr.cache.u.tss286.limit < 43 ) {
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ }
+ if ( BX_CPU_THIS_PTR tr.cache.type != 1 ) {
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ }
+ if ( BX_CPU_THIS_PTR tr.cache.segment ) {
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ }
+ if (BX_CPU_THIS_PTR tr.cache.valid==0) {
+ BX_CPU_THIS_PTR tr.cache.u.tss286.base = 0;
+ BX_CPU_THIS_PTR tr.cache.u.tss286.limit = 0;
+ BX_CPU_THIS_PTR tr.cache.p = 0;
+ BX_CPU_THIS_PTR tr.selector.value = 0;
+ BX_CPU_THIS_PTR tr.selector.index = 0;
+ BX_CPU_THIS_PTR tr.selector.ti = 0;
+ BX_CPU_THIS_PTR tr.selector.rpl = 0;
+ }
+
+
+ /* FLAGS */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x818, 2, &flags);
+ write_flags(flags, 1, 1);
+
+ /* IP */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x81a, 2, &ip);
+ IP = ip;
+
+ /* LDTR */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x81c, 2, &ldtr);
+ BX_CPU_THIS_PTR ldtr.selector.value = ldtr;
+ BX_CPU_THIS_PTR ldtr.selector.rpl = (ldtr & 0x03); ldtr >>= 2;
+ BX_CPU_THIS_PTR ldtr.selector.ti = (ldtr & 0x01); ldtr >>= 1;
+ BX_CPU_THIS_PTR ldtr.selector.index = ldtr;
+ if ( (BX_CPU_THIS_PTR ldtr.selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+ BX_CPU_THIS_PTR ldtr.cache.p = 0;
+ BX_CPU_THIS_PTR ldtr.cache.segment = 0;
+ BX_CPU_THIS_PTR ldtr.cache.type = 0;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = 0;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0;
+ BX_CPU_THIS_PTR ldtr.selector.value = 0;
+ BX_CPU_THIS_PTR ldtr.selector.index = 0;
+ BX_CPU_THIS_PTR ldtr.selector.ti = 0;
+ }
+ else {
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x854, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x856, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x857, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x858, 2, &limit);
+ BX_CPU_THIS_PTR ldtr.cache.valid =
+ BX_CPU_THIS_PTR ldtr.cache.p = access >> 7;
+ BX_CPU_THIS_PTR ldtr.cache.dpl = (access >> 5) & 0x03;
+ BX_CPU_THIS_PTR ldtr.cache.segment = (access >> 4) & 0x01;
+ BX_CPU_THIS_PTR ldtr.cache.type = (access & 0x0f);
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = limit;
+
+ if (access == 0) {
+ BX_PANIC(("loadall: LDTR case access byte=0.\n"));
+ }
+ if ( BX_CPU_THIS_PTR ldtr.cache.valid==0 ) {
+ BX_PANIC(("loadall: ldtr.valid=0\n"));
+ }
+ if (BX_CPU_THIS_PTR ldtr.cache.segment) { /* not a system segment */
+ BX_INFO((" AR byte = %02x\n", (unsigned) access));
+ BX_PANIC(("loadall: LDTR descriptor cache loaded with non system segment\n"));
+ }
+ if ( BX_CPU_THIS_PTR ldtr.cache.type != 2 ) {
+ BX_PANIC(("loadall: LDTR.type(%u) != 2\n", (unsigned) (access & 0x0f)));
+ }
+ }
+
+ /* DS */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x81e, 2, &ds_raw);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = ds_raw;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = (ds_raw & 0x03); ds_raw >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.ti = (ds_raw & 0x01); ds_raw >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.index = ds_raw;
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x848, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x84a, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x84b, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x84c, 2, &limit);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = limit;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = (access & 0x03); access >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = (access & 0x01);
+
+ if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+ }
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid==0 ||
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment==0) {
+ BX_PANIC(("loadall: DS invalid\n"));
+ }
+
+ /* SS */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x820, 2, &ss_raw);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = ss_raw;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = (ss_raw & 0x03); ss_raw >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = (ss_raw & 0x01); ss_raw >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = ss_raw;
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x842, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x844, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x845, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x846, 2, &limit);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = limit;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = (access & 0x03); access >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = (access & 0x01);
+
+ if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+ }
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0 ||
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment==0) {
+ BX_PANIC(("loadall: SS invalid\n"));
+ }
+
+
+ /* CS */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x822, 2, &cs_raw);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = cs_raw;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = (cs_raw & 0x03); cs_raw >>= 2;
+
+ //BX_INFO(("LOADALL: setting cs.selector.rpl to %u\n",
+ // (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl));
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.ti = (cs_raw & 0x01); cs_raw >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = cs_raw;
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x83c, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x83e, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x83f, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x840, 2, &limit);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = limit;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = (access & 0x03); access >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = (access & 0x01);
+
+ if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 0;
+ }
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid==0 ||
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment==0) {
+ BX_PANIC(("loadall: CS invalid\n"));
+ }
+
+ /* ES */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x824, 2, &es_raw);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = es_raw;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = (es_raw & 0x03); es_raw >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.ti = (es_raw & 0x01); es_raw >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.index = es_raw;
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x836, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x838, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x839, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x83a, 2, &limit);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = limit;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = (access & 0x01); access >>= 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = (access & 0x03); access >>= 2;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = (access & 0x01);
+
+#if 0
+ BX_INFO(("cs.dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl));
+ BX_INFO(("ss.dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl));
+ BX_INFO(("BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR ds.cache.dpl));
+ BX_INFO(("BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].dpl = %02x\n", (unsigned) BX_CPU_THIS_PTR es.cache.dpl));
+ BX_INFO(("LOADALL: setting cs.selector.rpl to %u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl));
+ BX_INFO(("LOADALL: setting ss.selector.rpl to %u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl));
+ BX_INFO(("LOADALL: setting ds.selector.rpl to %u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl));
+ BX_INFO(("LOADALL: setting es.selector.rpl to %u\n",
+ (unsigned) BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl));
+#endif
+
+ if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value & 0xfffc) == 0 ) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+ }
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid==0 ||
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment==0) {
+ BX_PANIC(("loadall: ES invalid\n"));
+ }
+
+ /* DI */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x826, 2, &di);
+ DI = di;
+
+ /* SI */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x828, 2, &si);
+ SI = si;
+
+ /* BP */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x82a, 2, &bp);
+ BP = bp;
+
+ /* SP */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x82c, 2, &sp);
+ SP = sp;
+
+ /* BX */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x82e, 2, &bx);
+ BX = bx;
+
+ /* DX */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x830, 2, &dx);
+ DX = dx;
+
+ /* CX */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x832, 2, &cx);
+ CX = cx;
+
+ /* AX */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x834, 2, &ax);
+ AX = ax;
+
+ /* GDTR */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x84e, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x850, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x851, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x852, 2, &limit);
+ BX_CPU_THIS_PTR gdtr.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR gdtr.limit = limit;
+
+#if 0
+ if (access)
+ BX_INFO(("LOADALL: GDTR access bits not 0 (%02x).\n",
+ (unsigned) access));
+#endif
+
+ /* IDTR */
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x85a, 2, &base_15_0);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x85c, 1, &base_23_16);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x85d, 1, &access);
+ BX_CPU_THIS_PTR mem->read_physical(this, 0x85e, 2, &limit);
+ BX_CPU_THIS_PTR idtr.base = (base_23_16 << 16) | base_15_0;
+ BX_CPU_THIS_PTR idtr.limit = limit;
+#endif
+}
+
+
+ void
+BX_CPU_C::CPUID(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 4
+ unsigned type, family, model, stepping, features;
+#endif
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 4
+ switch (EAX) {
+ case 0:
+ // EAX: highest input value understood by CPUID
+ // EBX: vendor ID string
+ // EDX: vendor ID string
+ // ECX: vendor ID string
+ EAX = 1; // 486 or pentium
+ EBX = 0x756e6547; // "Genu"
+ EDX = 0x49656e69; // "ineI"
+ ECX = 0x6c65746e; // "ntel"
+ break;
+
+ case 1:
+ // EAX[3:0] Stepping ID
+ // EAX[7:4] Model: starts at 1
+ // EAX[11:8] Family: 4=486, 5=Pentium, 6=PPro
+ // EAX[13:12] Type: 0=OEM,1=overdrive,2=dual cpu,3=reserved
+ // EAX[31:14] Reserved
+ // EBX: Reserved (0)
+ // ECX: Reserved (0)
+ // EDX: Feature Flags
+ // [0:0] FPU on chip
+ // [1:1] VME: Virtual-8086 Mode enhancements
+ // [2:2] DE: Debug Extensions (I/O breakpoints)
+ // [3:3] PSE: Page Size Extensions
+ // [4:4] TSC: Time Stamp Counter
+ // [5:5] MSR: RDMSR and WRMSR support
+ // [6:6] PAE: Physical Address Extensions
+ // [7:7] MCE: Machine Check Exception
+ // [8:8] CXS: CMPXCHG8B instruction
+ // [9:9] APIC: APIC on Chip
+ // [11:10] Reserved
+ // [12:12] MTRR: Memory Type Range Reg
+ // [13:13] PGE/PTE Global Bit
+ // [14:14] MCA: Machine Check Architecture
+ // [15:15] CMOV: Cond Mov/Cmp Instructions
+ // [22:16] Reserved
+ // [23:23] MMX Technology
+ // [31:24] Reserved
+
+ features = 0; // start with none
+ type = 0; // OEM
+
+#if BX_CPU_LEVEL == 4
+ family = 4;
+# if BX_SUPPORT_FPU
+ // 486dx
+ model = 1;
+ stepping = 3;
+ features |= 0x01;
+# else
+ // 486sx
+ model = 2;
+ stepping = 3;
+# endif
+
+#elif BX_CPU_LEVEL == 5
+ family = 5;
+ model = 1; // Pentium (60,66)
+ stepping = 3; // ???
+ features |= (1<<4); // implement TSC
+# if BX_SUPPORT_FPU
+ features |= 0x01;
+# endif
+
+#elif BX_CPU_LEVEL == 6
+ family = 6;
+ model = 1; // Pentium Pro
+ stepping = 3; // ???
+ features |= (1<<4); // implement TSC
+# if BX_SUPPORT_APIC
+ features |= (1<<9); // APIC on chip
+# endif
+# if BX_SUPPORT_FPU
+ features |= 0x01; // has FPU
+# endif
+#else
+ BX_PANIC(("CPUID: not implemented for > 6\n"));
+#endif
+
+ EAX = (family <<8) | (model<<4) | stepping;
+ EBX = ECX = 0; // reserved
+ EDX = features;
+ break;
+
+ default:
+ EAX = EBX = ECX = EDX = 0; // Reserved, undefined
+ break;
+ }
+#else
+ BX_PANIC(("CPUID: not available on < late 486\n"));
+#endif
+}
+
+ void
+BX_CPU_C::SetCR0(Bit32u val_32)
+{
+ // from either MOV_CdRd() or debug functions
+ // protection checks made already or forcing from debug
+ Boolean prev_pe, prev_pg;
+
+ prev_pe = BX_CPU_THIS_PTR cr0.pe;
+ prev_pg = BX_CPU_THIS_PTR cr0.pg;
+
+ BX_CPU_THIS_PTR cr0.pe = val_32 & 0x01;
+ BX_CPU_THIS_PTR cr0.mp = (val_32 >> 1) & 0x01;
+ BX_CPU_THIS_PTR cr0.em = (val_32 >> 2) & 0x01;
+ BX_CPU_THIS_PTR cr0.ts = (val_32 >> 3) & 0x01;
+ // cr0.et is hardwired to 1
+#if BX_CPU_LEVEL >= 4
+ BX_CPU_THIS_PTR cr0.ne = (val_32 >> 5) & 0x01;
+ BX_CPU_THIS_PTR cr0.wp = (val_32 >> 16) & 0x01;
+ BX_CPU_THIS_PTR cr0.am = (val_32 >> 18) & 0x01;
+ BX_CPU_THIS_PTR cr0.nw = (val_32 >> 29) & 0x01;
+ BX_CPU_THIS_PTR cr0.cd = (val_32 >> 30) & 0x01;
+#endif
+ BX_CPU_THIS_PTR cr0.pg = (val_32 >> 31) & 0x01;
+
+ // handle reserved bits behaviour
+#if BX_CPU_LEVEL == 3
+ BX_CPU_THIS_PTR cr0.val32 = val_32 | 0x7ffffff0;
+#elif BX_CPU_LEVEL == 4
+ BX_CPU_THIS_PTR cr0.val32 = val_32 & 0xe005002f;
+#elif BX_CPU_LEVEL == 5
+ BX_CPU_THIS_PTR cr0.val32 = val_32 | 0x00000010;
+#elif BX_CPU_LEVEL == 6
+ BX_CPU_THIS_PTR cr0.val32 = (val_32 | 0x00000010) & 0xe005003f;
+#else
+#error "MOV_CdRd: implement reserved bits behaviour for this CPU_LEVEL"
+#endif
+
+ //if (BX_CPU_THIS_PTR cr0.ts)
+ // BX_INFO(("MOV_CdRd:CR0.TS set 0x%x\n", (unsigned) val_32));
+
+ if (prev_pe==0 && BX_CPU_THIS_PTR cr0.pe) {
+ enter_protected_mode();
+ }
+ else if (prev_pe==1 && BX_CPU_THIS_PTR cr0.pe==0) {
+ enter_real_mode();
+ }
+
+ if (prev_pg==0 && BX_CPU_THIS_PTR cr0.pg)
+ enable_paging();
+ else if (prev_pg==1 && BX_CPU_THIS_PTR cr0.pg==0)
+ disable_paging();
+}
+
+
+ void
+BX_CPU_C::RSM(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 4
+ invalidate_prefetch_q();
+
+ BX_PANIC(("RSM: System Management Mode not implemented yet\n"));
+#else
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::RDTSC(BxInstruction_t *i)
+{
+#if 0
+#if BX_CPU_LEVEL >= 5
+ Boolean tsd = (BX_CPU_THIS_PTR cr4 & 4)? 1 : 0;
+ Boolean cpl = CPL;
+ if ((tsd==0) || (tsd==1 && cpl==0)) {
+ // return ticks
+ Bit64u ticks = bx_pc_system.time_ticks ();
+ EAX = (Bit32u) (ticks & 0xffffffff);
+ EDX = (Bit32u) ((ticks >> 32) & 0xffffffff);
+ //BX_INFO(("RDTSC: returning EDX:EAX = %08x:%08x\n", EDX, EAX));
+ } else {
+ // not allowed to use RDTSC!
+ exception (BX_GP_EXCEPTION, 0, 0);
+ }
+#else
+ UndefinedOpcode(i);
+#endif
+#endif
+}
+
+ void
+BX_CPU_C::RDMSR(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 5
+ BX_ERROR(("RDMSR: not implemented yet\n"));
+ UndefinedOpcode(i);
+#else
+ UndefinedOpcode(i);
+#endif
+}
+
+ void
+BX_CPU_C::WRMSR(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 5
+ invalidate_prefetch_q();
+
+ BX_PANIC(( "WRMSR: not implemented yet\n"));
+#else
+ UndefinedOpcode(i);
+#endif
+}
+
+#if BX_X86_DEBUGGER
+ Bit32u
+BX_CPU_C::hwdebug_compare(Bit32u laddr_0, unsigned size,
+ unsigned opa, unsigned opb)
+{
+ // Support x86 hardware debug facilities (DR0..DR7)
+ Bit32u dr7 = BX_CPU_THIS_PTR dr7;
+
+ Boolean ibpoint_found = 0;
+ Bit32u laddr_n = laddr_0 + (size - 1);
+ Bit32u dr0, dr1, dr2, dr3;
+ Bit32u dr0_n, dr1_n, dr2_n, dr3_n;
+ Bit32u len0, len1, len2, len3;
+ static unsigned alignment_mask[4] =
+ // 00b=1 01b=2 10b=undef 11b=4
+ { 0xffffffff, 0xfffffffe, 0xffffffff, 0xfffffffc };
+ Bit32u dr0_op, dr1_op, dr2_op, dr3_op;
+
+ len0 = (dr7>>18) & 3;
+ len1 = (dr7>>22) & 3;
+ len2 = (dr7>>26) & 3;
+ len3 = (dr7>>30) & 3;
+
+ dr0 = BX_CPU_THIS_PTR dr0 & alignment_mask[len0];
+ dr1 = BX_CPU_THIS_PTR dr1 & alignment_mask[len1];
+ dr2 = BX_CPU_THIS_PTR dr2 & alignment_mask[len2];
+ dr3 = BX_CPU_THIS_PTR dr3 & alignment_mask[len3];
+
+ dr0_n = dr0 + len0;
+ dr1_n = dr1 + len1;
+ dr2_n = dr2 + len2;
+ dr3_n = dr3 + len3;
+
+ dr0_op = (dr7>>16) & 3;
+ dr1_op = (dr7>>20) & 3;
+ dr2_op = (dr7>>24) & 3;
+ dr3_op = (dr7>>28) & 3;
+
+ // See if this instruction address matches any breakpoints
+ if ( (dr7 & 0x00000003) ) {
+ if ( (dr0_op==opa || dr0_op==opb) &&
+ (laddr_0 <= dr0_n) &&
+ (laddr_n >= dr0) )
+ ibpoint_found = 1;
+ }
+ if ( (dr7 & 0x0000000c) ) {
+ if ( (dr1_op==opa || dr1_op==opb) &&
+ (laddr_0 <= dr1_n) &&
+ (laddr_n >= dr1) )
+ ibpoint_found = 1;
+ }
+ if ( (dr7 & 0x00000030) ) {
+ if ( (dr2_op==opa || dr2_op==opb) &&
+ (laddr_0 <= dr2_n) &&
+ (laddr_n >= dr2) )
+ ibpoint_found = 1;
+ }
+ if ( (dr7 & 0x000000c0) ) {
+ if ( (dr3_op==opa || dr3_op==opb) &&
+ (laddr_0 <= dr3_n) &&
+ (laddr_n >= dr3) )
+ ibpoint_found = 1;
+ }
+
+ // If *any* enabled breakpoints matched, then we need to
+ // set status bits for *all* breakpoints, even disabled ones,
+ // as long as they meet the other breakpoint criteria.
+ // This code is similar to that above, only without the
+ // breakpoint enabled check. Seems weird to duplicate effort,
+ // but its more efficient to do it this way.
+ if (ibpoint_found) {
+ // dr6_mask is the return value. These bits represent the bits to
+ // be OR'd into DR6 as a result of the debug event.
+ Bit32u dr6_mask=0;
+ if ( (dr0_op==opa || dr0_op==opb) &&
+ (laddr_0 <= dr0_n) &&
+ (laddr_n >= dr0) )
+ dr6_mask |= 0x01;
+ if ( (dr1_op==opa || dr1_op==opb) &&
+ (laddr_0 <= dr1_n) &&
+ (laddr_n >= dr1) )
+ dr6_mask |= 0x02;
+ if ( (dr2_op==opa || dr2_op==opb) &&
+ (laddr_0 <= dr2_n) &&
+ (laddr_n >= dr2) )
+ dr6_mask |= 0x04;
+ if ( (dr3_op==opa || dr3_op==opb) &&
+ (laddr_0 <= dr3_n) &&
+ (laddr_n >= dr3) )
+ dr6_mask |= 0x08;
+ return(dr6_mask);
+ }
+ return(0);
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::ARPL_EwGw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("ARPL_EwRw: not supported on 8086!\n"));
+#else /* 286+ */
+
+ Bit16u op2_16, op1_16;
+
+
+ if (protected_mode()) {
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ if ( (op1_16 & 0x03) < (op2_16 & 0x03) ) {
+ op1_16 = (op1_16 & 0xfffc) | (op2_16 & 0x03);
+ /* now write back to destination */
+ if (i->mod == 0xc0) {
+ if (i->os_32) {
+ // if 32bit opsize, then 0xff3f is or'd into
+ // upper 16bits of register
+ Bit32u op1_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ op1_32 = (op1_32 & 0xffff0000) | op1_16;
+ op1_32 |= 0xff3f0000;
+ BX_WRITE_32BIT_REG(i->rm, op1_32);
+ }
+ else {
+ BX_WRITE_16BIT_REG(i->rm, op1_16);
+ }
+ }
+ else {
+ write_RMW_virtual_word(op1_16);
+ }
+ set_ZF(1);
+ }
+ else {
+ set_ZF(0);
+ }
+ }
+ else {
+ // ARPL not recognized in real or v8086 mode
+ UndefinedOpcode(i);
+ return;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LAR_GvEw(BxInstruction_t *i)
+{
+ /* for 16 bit operand size mode */
+ Bit16u raw_selector;
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit32u dword1, dword2;
+
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ if (real_mode()) {
+ BX_PANIC(("LAR_GvEw: not recognized in real mode\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+ /* if selector null, clear ZF and done */
+ if ( (raw_selector & 0xfffc) == 0 ) {
+ set_ZF(0);
+ return;
+ }
+
+ parse_selector(raw_selector, &selector);
+
+ if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+ /* not within descriptor table */
+ set_ZF(0);
+ return;
+ }
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ if (descriptor.valid==0) {
+ set_ZF(0);
+ //BX_INFO(("lar(): descriptor valid bit cleared\n"));
+ return;
+ }
+
+ /* if source selector is visible at CPL & RPL,
+ * within the descriptor table, and of type accepted by LAR instruction,
+ * then load register with segment limit and set ZF
+ */
+
+ if ( descriptor.segment ) { /* normal segment */
+ if ( descriptor.u.segment.executable && descriptor.u.segment.c_ed ) {
+ /* ignore DPL for conforming segments */
+ }
+ else {
+ if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+ set_ZF(0);
+ return;
+ }
+ }
+ set_ZF(1);
+ if (i->os_32) {
+ /* masked by 00FxFF00, where x is undefined */
+ BX_WRITE_32BIT_REG(i->nnn, dword2 & 0x00ffff00);
+ }
+ else {
+ BX_WRITE_16BIT_REG(i->nnn, dword2 & 0xff00);
+ }
+ return;
+ }
+ else { /* system or gate segment */
+ switch ( descriptor.type ) {
+ case 1: /* available TSS */
+ case 2: /* LDT */
+ case 3: /* busy TSS */
+ case 4: /* 286 call gate */
+ case 5: /* task gate */
+#if BX_CPU_LEVEL >= 3
+ case 9: /* available 32bit TSS */
+ case 11: /* busy 32bit TSS */
+ case 12: /* 32bit call gate */
+#endif
+ break;
+ default: /* rest not accepted types to LAR */
+ set_ZF(0);
+ BX_INFO(("lar(): not accepted type\n"));
+ return;
+ break;
+ }
+
+ if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+ set_ZF(0);
+ return;
+ }
+ set_ZF(1);
+ if (i->os_32) {
+ /* masked by 00FxFF00, where x is undefined ??? */
+ BX_WRITE_32BIT_REG(i->nnn, dword2 & 0x00ffff00);
+ }
+ else {
+ BX_WRITE_16BIT_REG(i->nnn, dword2 & 0xff00);
+ }
+ return;
+ }
+}
+
+ void
+BX_CPU_C::LSL_GvEw(BxInstruction_t *i)
+{
+ /* for 16 bit operand size mode */
+ Bit16u raw_selector;
+ Bit32u limit32;
+ //bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit32u dword1, dword2;
+ Bit32u descriptor_dpl;
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+ if (real_mode()) {
+ BX_PANIC(("LSL_GvEw: not recognized in real mode\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+
+ /* if selector null, clear ZF and done */
+ if ( (raw_selector & 0xfffc) == 0 ) {
+ set_ZF(0);
+ return;
+ }
+
+ parse_selector(raw_selector, &selector);
+
+ if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+ /* not within descriptor table */
+ set_ZF(0);
+ return;
+ }
+
+ //parse_descriptor(dword1, dword2, &descriptor);
+
+ descriptor_dpl = (dword2 >> 13) & 0x03;
+
+ if ( (dword2 & 0x00001000) == 0 ) { // system segment
+ Bit32u type;
+
+ type = (dword2 >> 8) & 0x0000000f;
+ switch (type) {
+ case 1: // 16bit TSS
+ case 3: // 16bit TSS
+ case 2: // LDT
+ case 9: // 32bit TSS G00A
+ case 11:// 32bit TSS G00A
+ limit32 = (dword1 & 0x0000ffff) | (dword2 & 0x000f0000);
+ if ( dword2 & 0x00800000 )
+ limit32 = (limit32 << 12) | 0x00000fff;
+ if ( (descriptor_dpl<CPL) || (descriptor_dpl<selector.rpl) ) {
+ set_ZF(0);
+ return;
+ }
+ goto lsl_ok;
+ break;
+ default:
+ set_ZF(0);
+ return;
+ }
+ }
+ else { // data & code segment
+ limit32 = (dword1 & 0x0000ffff) | (dword2 & 0x000f0000);
+ if ( dword2 & 0x00800000 )
+ limit32 = (limit32 << 12) | 0x00000fff;
+ if ( (dword2 & 0x00000c00) == 0x00000c00 ) {
+ // conforming code segment, no check done
+ goto lsl_ok;
+ }
+
+ if ( (descriptor_dpl<CPL) || (descriptor_dpl<selector.rpl) ) {
+ set_ZF(0);
+ return;
+ }
+ goto lsl_ok;
+ }
+
+lsl_ok:
+ /* all checks pass, limit32 is now byte granular, write to op1 */
+ set_ZF(1);
+
+ if (i->os_32)
+ BX_WRITE_32BIT_REG(i->nnn, limit32)
+ else
+ // chop off upper 16 bits
+ BX_WRITE_16BIT_REG(i->nnn, (Bit16u) limit32)
+}
+
+ void
+BX_CPU_C::SLDT_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("SLDT_Ew: not supported on 8086!\n"));
+#else
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ if (real_mode()) {
+ /* not recognized in real address mode */
+ BX_ERROR(("SLDT_Ew: encountered in real mode.\n"));
+ UndefinedOpcode(i);
+ }
+ else {
+ Bit16u val16;
+
+ val16 = BX_CPU_THIS_PTR ldtr.selector.value;
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, val16);
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &val16);
+ }
+ }
+#endif
+}
+
+ void
+BX_CPU_C::STR_Ew(BxInstruction_t *i)
+{
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ if (real_mode()) {
+ // not recognized in real address mode
+ BX_PANIC(("STR_Ew: encountered in real mode.\n"));
+ UndefinedOpcode(i);
+ }
+ else {
+ Bit16u val16;
+
+ val16 = BX_CPU_THIS_PTR tr.selector.value;
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, val16);
+ }
+ else {
+ write_virtual_word(i->seg, i->rm_addr, &val16);
+ }
+ }
+}
+
+ void
+BX_CPU_C::LLDT_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LLDT_Ew: not supported on 8086!\n"));
+#else
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ invalidate_prefetch_q();
+
+ if (real_mode()) {
+ BX_PANIC(("lldt: not recognized in real mode\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+ else { /* protected mode */
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit16u raw_selector;
+ Bit32u dword1, dword2;
+
+
+ /* #GP(0) if the current privilege level is not 0 */
+ if (CPL != 0) {
+ BX_PANIC(("LLDT: CPL != 0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+ /* if selector is NULL, invalidate and done */
+ if ((raw_selector & 0xfffc) == 0) {
+ BX_CPU_THIS_PTR ldtr.selector.value = raw_selector;
+ BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+ return;
+ }
+
+ /* parse fields in selector */
+ parse_selector(raw_selector, &selector);
+
+ // #GP(selector) if the selector operand does not point into GDT
+ if (selector.ti != 0) {
+ BX_INFO(("LLDT: selector.ti != 0\n"));
+ exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+ }
+
+ if ((selector.index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+ BX_PANIC(("lldt: GDT: index > limit\n"));
+ exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+ return;
+ }
+
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 4, 4, 0,
+ BX_READ, &dword2);
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ /* if selector doesn't point to an LDT descriptor #GP(selector) */
+ if ( (descriptor.valid==0) ||
+ descriptor.segment ||
+ (descriptor.type!=2) ) {
+ BX_INFO(("lldt: doesn't point to an LDT descriptor!\n"));
+ exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0);
+ }
+
+ /* #NP(selector) if LDT descriptor is not present */
+ if (descriptor.p==0) {
+ BX_INFO(("lldt: LDT descriptor not present!\n"));
+ exception(BX_NP_EXCEPTION, raw_selector & 0xfffc, 0);
+ }
+
+ if (descriptor.u.ldt.limit < 7) {
+ BX_INFO(("lldt: ldtr.limit < 7\n"));
+ }
+
+ BX_CPU_THIS_PTR ldtr.selector = selector;
+ BX_CPU_THIS_PTR ldtr.cache = descriptor;
+ BX_CPU_THIS_PTR ldtr.cache.valid = 1;
+
+ return;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LTR_Ew(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LTR_Ew: not supported on 8086!\n"));
+#else
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit16u raw_selector;
+ Bit32u dword1, dword2;
+
+
+ /* #GP(0) if the current privilege level is not 0 */
+ if (CPL != 0) {
+ BX_PANIC(("LTR: CPL != 0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+ /* if selector is NULL, invalidate and done */
+ if ((raw_selector & 0xfffc) == 0) {
+ BX_PANIC(("ltr: loading with NULL selector!\n"));
+ /* if this is OK, then invalidate and load selector & descriptor cache */
+ /* load here */
+ BX_CPU_THIS_PTR tr.selector.value = raw_selector;
+ BX_CPU_THIS_PTR tr.cache.valid = 0;
+ return;
+ }
+
+ /* parse fields in selector, then check for null selector */
+ parse_selector(raw_selector, &selector);
+
+ if (selector.ti) {
+ BX_PANIC(("ltr: selector.ti != 0\n"));
+ return;
+ }
+
+ /* fetch 2 dwords of descriptor; call handles out of limits checks */
+ fetch_raw_descriptor(&selector, &dword1, &dword2, BX_GP_EXCEPTION);
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ /* #GP(selector) if object is not a TSS or is already busy */
+ if ( (descriptor.valid==0) || descriptor.segment ||
+ (descriptor.type!=1 && descriptor.type!=9) ) {
+ BX_PANIC(("ltr: doesn't point to an available TSS descriptor!\n"));
+ exception(BX_GP_EXCEPTION, raw_selector & 0xfffc, 0); /* 0 ??? */
+ return;
+ }
+
+ /* #NP(selector) if TSS descriptor is not present */
+ if (descriptor.p==0) {
+ BX_PANIC(("ltr: LDT descriptor not present!\n"));
+ exception(BX_NP_EXCEPTION, raw_selector & 0xfffc, 0); /* 0 ??? */
+ return;
+ }
+
+ if (descriptor.type==1 && descriptor.u.tss286.limit<43) {
+ BX_PANIC(("ltr:286TSS: loading tr.limit < 43\n"));
+ }
+ else if (descriptor.type==9 && descriptor.u.tss386.limit_scaled<103) {
+ BX_PANIC(("ltr:386TSS: loading tr.limit < 103\n"));
+ }
+
+ BX_CPU_THIS_PTR tr.selector = selector;
+ BX_CPU_THIS_PTR tr.cache = descriptor;
+ BX_CPU_THIS_PTR tr.cache.valid = 1;
+
+ /* mark as busy */
+ dword2 |= 0x00000200; /* set busy bit */
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector.index*8 + 4, 4, 0,
+ BX_WRITE, &dword2);
+
+ return;
+ }
+ else {
+ BX_PANIC(("ltr_ew: not recognized in real-mode!\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::VERR_Ew(BxInstruction_t *i)
+{
+ /* for 16 bit operand size mode */
+ Bit16u raw_selector;
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit32u dword1, dword2;
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+ if (real_mode()) {
+ BX_PANIC(("VERR_Ew: not recognized in real mode\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+ /* if selector null, clear ZF and done */
+ if ( (raw_selector & 0xfffc) == 0 ) {
+ set_ZF(0);
+ BX_INFO(("VERR: null selector\n"));
+ return;
+ }
+
+ /* if source selector is visible at CPL & RPL,
+ * within the descriptor table, and of type accepted by VERR instruction,
+ * then load register with segment limit and set ZF */
+ parse_selector(raw_selector, &selector);
+
+ if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+ /* not within descriptor table */
+ set_ZF(0);
+ BX_INFO(("VERR: not in table\n"));
+ return;
+ }
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ if ( descriptor.segment==0 ) { /* system or gate descriptor */
+ set_ZF(0); /* inaccessible */
+ BX_INFO(("VERR: system descriptor\n"));
+ return;
+ }
+
+ if ( descriptor.valid==0 ) {
+ set_ZF(0);
+ BX_INFO(("VERR: valid bit cleared\n"));
+ return;
+ }
+
+ /* normal data/code segment */
+ if ( descriptor.u.segment.executable ) { /* code segment */
+ /* ignore DPL for readable conforming segments */
+ if ( descriptor.u.segment.c_ed &&
+ descriptor.u.segment.r_w) {
+ set_ZF(1); /* accessible */
+ BX_INFO(("VERR: conforming code, OK\n"));
+ return;
+ }
+ if ( descriptor.u.segment.r_w==0 ) {
+ set_ZF(0); /* inaccessible */
+ BX_INFO(("VERR: code not readable\n"));
+ return;
+ }
+ /* readable, non-conforming code segment */
+ if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+ set_ZF(0); /* inaccessible */
+ BX_INFO(("VERR: non-coforming code not withing priv level\n"));
+ return;
+ }
+ set_ZF(1); /* accessible */
+ BX_INFO(("VERR: code seg readable\n"));
+ return;
+ }
+ else { /* data segment */
+ if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+ set_ZF(0); /* not accessible */
+ BX_INFO(("VERR: data seg not withing priv level\n"));
+ return;
+ }
+ set_ZF(1); /* accessible */
+ BX_INFO(("VERR: data segment OK\n"));
+ return;
+ }
+}
+
+ void
+BX_CPU_C::VERW_Ew(BxInstruction_t *i)
+{
+ /* for 16 bit operand size mode */
+ Bit16u raw_selector;
+ bx_descriptor_t descriptor;
+ bx_selector_t selector;
+ Bit32u dword1, dword2;
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+ if (real_mode()) {
+ BX_PANIC(("VERW_Ew: not recognized in real mode\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ if (i->mod == 0xc0) {
+ raw_selector = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &raw_selector);
+ }
+
+ /* if selector null, clear ZF and done */
+ if ( (raw_selector & 0xfffc) == 0 ) {
+ set_ZF(0);
+ BX_INFO(("VERW: null selector\n"));
+ return;
+ }
+
+ /* if source selector is visible at CPL & RPL,
+ * within the descriptor table, and of type accepted by VERW instruction,
+ * then load register with segment limit and set ZF */
+ parse_selector(raw_selector, &selector);
+
+ if ( !fetch_raw_descriptor2(&selector, &dword1, &dword2) ) {
+ /* not within descriptor table */
+ set_ZF(0);
+ BX_INFO(("VERW: not in table\n"));
+ return;
+ }
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ /* rule out system segments & code segments */
+ if ( descriptor.segment==0 || descriptor.u.segment.executable ) {
+ set_ZF(0);
+ BX_INFO(("VERW: system seg or code\n"));
+ return;
+ }
+
+ if ( descriptor.valid==0 ) {
+ set_ZF(0);
+ BX_INFO(("VERW: valid bit cleared\n"));
+ return;
+ }
+
+ /* data segment */
+ if ( descriptor.u.segment.r_w ) { /* writable */
+ if ( (descriptor.dpl<CPL) || (descriptor.dpl<selector.rpl) ) {
+ set_ZF(0); /* not accessible */
+ BX_INFO(("VERW: writable data seg not within priv level\n"));
+ return;
+ }
+ set_ZF(1); /* accessible */
+ BX_INFO(("VERW: data seg writable\n"));
+ return;
+ }
+
+ set_ZF(0); /* not accessible */
+ BX_INFO(("VERW: data seg not writable\n"));
+ return;
+}
+
+ void
+BX_CPU_C::SGDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("SGDT_Ms: not supported on 8086!\n"));
+#else
+ Bit16u limit_16;
+ Bit32u base_32;
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* undefined opcode exception */
+ BX_PANIC(("SGDT_Ms: use of register is undefined opcode.\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ limit_16 = BX_CPU_THIS_PTR gdtr.limit;
+ base_32 = BX_CPU_THIS_PTR gdtr.base;
+#if BX_CPU_LEVEL == 2
+ base_32 |= 0xff000000; /* ??? */
+#else /* 386+ */
+ /* 32bit processors always write 32bits of base */
+#endif
+ write_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+ write_virtual_dword(i->seg, i->rm_addr+2, &base_32);
+
+#endif
+}
+
+ void
+BX_CPU_C::SIDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("SIDT_Ms: not supported on 8086!\n"));
+#else
+ Bit16u limit_16;
+ Bit32u base_32;
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* undefined opcode exception */
+ BX_PANIC(("SIDT: use of register is undefined opcode.\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ limit_16 = BX_CPU_THIS_PTR idtr.limit;
+ base_32 = BX_CPU_THIS_PTR idtr.base;
+
+#if BX_CPU_LEVEL == 2
+ base_32 |= 0xff000000;
+#else /* 386+ */
+ /* ??? regardless of operand size, all 32bits of base are stored */
+#endif
+
+ write_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+ write_virtual_dword(i->seg, i->rm_addr+2, &base_32);
+
+#endif
+}
+
+ void
+BX_CPU_C::LGDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LGDT_Ms: not supported on 8086!\n"));
+#else
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ invalidate_prefetch_q();
+
+ if (protected_mode() && (CPL!=0)) {
+ BX_PANIC(("LGDT: protected mode: CPL!=0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ BX_PANIC(("LGDT generating exception 6\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit16u limit_16;
+ Bit32u base0_31;
+
+ read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+ read_virtual_dword(i->seg, i->rm_addr + 2, &base0_31);
+
+ BX_CPU_THIS_PTR gdtr.limit = limit_16;
+ BX_CPU_THIS_PTR gdtr.base = base0_31;
+ }
+ else
+#endif
+ {
+ Bit16u limit_16, base0_15;
+ Bit8u base16_23;
+
+ read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+ read_virtual_word(i->seg, i->rm_addr + 2, &base0_15);
+
+ read_virtual_byte(i->seg, i->rm_addr + 4, &base16_23);
+
+ /* ignore high 8 bits */
+
+ BX_CPU_THIS_PTR gdtr.limit = limit_16;
+ BX_CPU_THIS_PTR gdtr.base = (base16_23 << 16) | base0_15;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LIDT_Ms(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LIDT_Ms: not supported on 8086!\n"));
+#else
+ Bit16u limit_16;
+ Bit32u base_32;
+
+
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+ invalidate_prefetch_q();
+
+ if (protected_mode()) {
+ if (CPL != 0) {
+ BX_PANIC(("LIDT(): CPL(%u) != 0\n", (unsigned) CPL));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ /* undefined opcode exception */
+ BX_PANIC(("LIDT generating exception 6\n"));
+ UndefinedOpcode(i);
+ return;
+ }
+
+ read_virtual_word(i->seg, i->rm_addr, &limit_16);
+
+ read_virtual_dword(i->seg, i->rm_addr + 2, &base_32);
+
+ BX_CPU_THIS_PTR idtr.limit = limit_16;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32)
+ BX_CPU_THIS_PTR idtr.base = base_32;
+ else
+#endif
+ BX_CPU_THIS_PTR idtr.base = base_32 & 0x00ffffff; /* ignore upper 8 bits */
+
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::enter_protected_mode(void)
+{
+// BX_INFO(("processor switching into PROTECTED mode!!!\n"));
+// debug(BX_CPU_THIS_PTR prev_eip);
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+#if BX_DEBUGGER
+ if (bx_dbg.reset)
+ BX_INFO(("processor switching into PROTECTED mode!!!\n"));
+#endif
+
+if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl!=0 || BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl!=0 )
+ BX_PANIC(("enter_protected_mode: CS or SS rpl != 0\n"));
+}
+
+
+ void
+BX_CPU_C::enter_real_mode(void)
+{
+// ???
+// BX_INFO(("processor switching into REAL mode!!!\n"));
+// debug(BX_CPU_THIS_PTR prev_eip);
+ if (v8086_mode()) BX_PANIC(("protect_ctrl: v8086 mode unsupported\n"));
+
+#if BX_DEBUGGER
+ if (bx_dbg.reset)
+ BX_INFO(("processor switching into REAL mode!!!\n"));
+#endif
+
+if ( BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl!=0 || BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl!=0 )
+ BX_PANIC(("enter_real_mode: CS or SS rpl != 0\n"));
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::Resolve16Mod0Rm0(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BX + SI);
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm1(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BX + DI);
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm2(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BP + SI);
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm3(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BP + DI);
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm4(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) SI;
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm5(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) DI;
+}
+ void
+BX_CPU_C::Resolve16Mod0Rm7(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) BX;
+}
+
+ void
+BX_CPU_C::Resolve16Mod1or2Rm0(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BX + SI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm1(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BX + DI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm2(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BP + SI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm3(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BP + DI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm4(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (SI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm5(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (DI + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm6(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BP + (Bit16s) i->displ16u);
+}
+ void
+BX_CPU_C::Resolve16Mod1or2Rm7(BxInstruction_t *i)
+{
+ i->rm_addr = (Bit16u) (BX + (Bit16s) i->displ16u);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::Resolve32Mod0Rm0(BxInstruction_t *i)
+{
+ i->rm_addr = EAX;
+}
+ void
+BX_CPU_C::Resolve32Mod0Rm1(BxInstruction_t *i)
+{
+ i->rm_addr = ECX;
+}
+ void
+BX_CPU_C::Resolve32Mod0Rm2(BxInstruction_t *i)
+{
+ i->rm_addr = EDX;
+}
+ void
+BX_CPU_C::Resolve32Mod0Rm3(BxInstruction_t *i)
+{
+ i->rm_addr = EBX;
+}
+ void
+BX_CPU_C::Resolve32Mod0Rm6(BxInstruction_t *i)
+{
+ i->rm_addr = ESI;
+}
+ void
+BX_CPU_C::Resolve32Mod0Rm7(BxInstruction_t *i)
+{
+ i->rm_addr = EDI;
+}
+
+
+ void
+BX_CPU_C::Resolve32Mod1or2Rm0(BxInstruction_t *i)
+{
+ i->rm_addr = EAX + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm1(BxInstruction_t *i)
+{
+ i->rm_addr = ECX + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm2(BxInstruction_t *i)
+{
+ i->rm_addr = EDX + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm3(BxInstruction_t *i)
+{
+ i->rm_addr = EBX + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm5(BxInstruction_t *i)
+{
+ i->rm_addr = EBP + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm6(BxInstruction_t *i)
+{
+ i->rm_addr = ESI + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Rm7(BxInstruction_t *i)
+{
+ i->rm_addr = EDI + i->displ32u;
+}
+
+
+ void
+BX_CPU_C::Resolve32Mod0Base0(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EAX + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base1(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ECX + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base2(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EDX + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base3(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EBX + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base4(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ESP + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base5(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = i->displ32u + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base6(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ESI + scaled_index;
+}
+ void
+BX_CPU_C::Resolve32Mod0Base7(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EDI + scaled_index;
+}
+
+
+
+
+ void
+BX_CPU_C::Resolve32Mod1or2Base0(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EAX + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base1(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ECX + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base2(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EDX + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base3(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EBX + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base4(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ESP + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base5(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EBP + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base6(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = ESI + scaled_index + i->displ32u;
+}
+ void
+BX_CPU_C::Resolve32Mod1or2Base7(BxInstruction_t *i)
+{
+ Bit32u scaled_index;
+
+ if (i->index != 4)
+ scaled_index = BX_READ_32BIT_REG(i->index) << i->scale;
+ else
+ scaled_index = 0;
+ i->rm_addr = EDI + scaled_index + i->displ32u;
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+
+ void
+BX_CPU_C::LES_GvMp(BxInstruction_t *i)
+{
+ if (i->mod == 0xc0) {
+ // (BW) NT seems to use this when booting.
+ BX_INFO(("invalid use of LES, must use memory reference!\n"));
+ UndefinedOpcode(i);
+ }
+
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ Bit16u es;
+ Bit32u reg_32;
+
+ read_virtual_dword(i->seg, i->rm_addr, ®_32);
+ read_virtual_word(i->seg, i->rm_addr + 4, &es);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+
+ BX_WRITE_32BIT_REG(i->nnn, reg_32);
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ { /* 16 bit mode */
+ Bit16u reg_16, es;
+
+ read_virtual_word(i->seg, i->rm_addr, ®_16);
+ read_virtual_word(i->seg, i->rm_addr + 2, &es);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+
+ BX_WRITE_16BIT_REG(i->nnn, reg_16);
+ }
+}
+
+ void
+BX_CPU_C::LDS_GvMp(BxInstruction_t *i)
+{
+ if (i->mod == 0xc0) {
+ BX_PANIC(("invalid use of LDS, must use memory reference!\n"));
+ UndefinedOpcode(i);
+ }
+
+#if BX_CPU_LEVEL > 2
+ if (i->os_32) {
+ Bit16u ds;
+ Bit32u reg_32;
+
+ read_virtual_dword(i->seg, i->rm_addr, ®_32);
+ read_virtual_word(i->seg, i->rm_addr + 4, &ds);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+
+ BX_WRITE_32BIT_REG(i->nnn, reg_32);
+ }
+ else
+#endif /* BX_CPU_LEVEL > 2 */
+ { /* 16 bit mode */
+ Bit16u reg_16, ds;
+
+ read_virtual_word(i->seg, i->rm_addr, ®_16);
+ read_virtual_word(i->seg, i->rm_addr + 2, &ds);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+
+ BX_WRITE_16BIT_REG(i->nnn, reg_16);
+ }
+}
+
+ void
+BX_CPU_C::LFS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("lfs_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+ if (i->mod == 0xc0) {
+ BX_PANIC(("invalid use of LFS, must use memory reference!\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (i->os_32) {
+ Bit32u reg_32;
+ Bit16u fs;
+
+ read_virtual_dword(i->seg, i->rm_addr, ®_32);
+ read_virtual_word(i->seg, i->rm_addr + 4, &fs);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+
+ BX_WRITE_32BIT_REG(i->nnn, reg_32);
+ }
+ else { /* 16 bit operand size */
+ Bit16u reg_16;
+ Bit16u fs;
+
+ read_virtual_word(i->seg, i->rm_addr, ®_16);
+ read_virtual_word(i->seg, i->rm_addr + 2, &fs);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+
+ BX_WRITE_16BIT_REG(i->nnn, reg_16);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LGS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("lgs_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+ if (i->mod == 0xc0) {
+ BX_PANIC(("invalid use of LGS, must use memory reference!\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (i->os_32) {
+ Bit32u reg_32;
+ Bit16u gs;
+
+ read_virtual_dword(i->seg, i->rm_addr, ®_32);
+ read_virtual_word(i->seg, i->rm_addr + 4, &gs);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+
+ BX_WRITE_32BIT_REG(i->nnn, reg_32);
+ }
+ else { /* 16 bit operand size */
+ Bit16u reg_16;
+ Bit16u gs;
+
+ read_virtual_word(i->seg, i->rm_addr, ®_16);
+ read_virtual_word(i->seg, i->rm_addr + 2, &gs);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+
+ BX_WRITE_16BIT_REG(i->nnn, reg_16);
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LSS_GvMp(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("lss_gvmp: not supported on 8086\n"));
+#else /* 386+ */
+
+ if (i->mod == 0xc0) {
+ BX_PANIC(("invalid use of LSS, must use memory reference!\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (i->os_32) {
+ Bit32u reg_32;
+ Bit16u ss_raw;
+
+ read_virtual_dword(i->seg, i->rm_addr, ®_32);
+ read_virtual_word(i->seg, i->rm_addr + 4, &ss_raw);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss_raw);
+
+ BX_WRITE_32BIT_REG(i->nnn, reg_32);
+ }
+ else { /* 16 bit operand size */
+ Bit16u reg_16;
+ Bit16u ss_raw;
+
+ read_virtual_word(i->seg, i->rm_addr, ®_16);
+ read_virtual_word(i->seg, i->rm_addr + 2, &ss_raw);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss_raw);
+
+ BX_WRITE_16BIT_REG(i->nnn, reg_16);
+ }
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
+{
+#if BX_CPU_LEVEL >= 3
+ if (v8086_mode()) {
+ /* ??? don't need to set all these fields */
+ seg->selector.value = new_value;
+ seg->selector.rpl = 3;
+ seg->cache.valid = 1;
+ seg->cache.p = 1;
+ seg->cache.dpl = 3;
+ seg->cache.segment = 1; /* regular segment */
+ if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_CS])
+ seg->cache.u.segment.executable = 1; /* code segment */
+ else
+ seg->cache.u.segment.executable = 0; /* data segment */
+ seg->cache.u.segment.c_ed = 0; /* expand up */
+ seg->cache.u.segment.r_w = 1; /* writeable */
+ seg->cache.u.segment.a = 1; /* accessed */
+ seg->cache.u.segment.base = new_value << 4;
+ seg->cache.u.segment.limit = 0xffff;
+ seg->cache.u.segment.limit_scaled = 0xffff;
+ seg->cache.u.segment.g = 0; /* byte granular */
+ seg->cache.u.segment.d_b = 0; /* default 16bit size */
+ seg->cache.u.segment.avl = 0;
+
+ return;
+ }
+#endif
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_SS]) {
+ Bit16u index;
+ Bit8u ti;
+ Bit8u rpl;
+ bx_descriptor_t descriptor;
+ Bit32u dword1, dword2;
+
+ if ((new_value & 0xfffc) == 0) { /* null selector */
+ BX_PANIC(("load_seg_reg: SS: new_value == 0\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ return;
+ }
+
+ index = new_value >> 3;
+ ti = (new_value >> 2) & 0x01;
+ rpl = (new_value & 0x03);
+
+ /* examine AR byte of destination selector for legal values: */
+
+ if (ti == 0) { /* GDT */
+ if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+ BX_PANIC(("load_seg_reg: GDT: %s: index(%04x) > limit(%06x)\n",
+ BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+ BX_READ, &dword2);
+ }
+ else { /* LDT */
+ if (BX_CPU_THIS_PTR ldtr.cache.valid==0) { /* ??? */
+ BX_INFO(("load_seg_reg: LDT invalid\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+ BX_INFO(("load_seg_reg ss: LDT: index > limit\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+ BX_READ, &dword2);
+ }
+
+ /* selector's RPL must = CPL, else #GP(selector) */
+ if (rpl != CPL) {
+ BX_INFO(("load_seg_reg(): rpl != CPL\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ if (descriptor.valid==0) {
+ BX_INFO(("load_seg_reg(): valid bit cleared\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+
+ /* AR byte must indicate a writable data segment else #GP(selector) */
+ if ( (descriptor.segment==0) ||
+ descriptor.u.segment.executable ||
+ descriptor.u.segment.r_w==0 ) {
+ BX_INFO(("load_seg_reg(): not writable data segment\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ }
+
+ /* DPL in the AR byte must equal CPL else #GP(selector) */
+ if (descriptor.dpl != CPL) {
+ BX_INFO(("load_seg_reg(): dpl != CPL\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ }
+
+ /* segment must be marked PRESENT else #SS(selector) */
+ if (descriptor.p == 0) {
+ BX_INFO(("load_seg_reg(): not present\n"));
+ exception(BX_SS_EXCEPTION, new_value & 0xfffc, 0);
+ }
+
+ /* load SS with selector, load SS cache with descriptor */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = new_value;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.index = index;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.ti = ti;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = rpl;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = descriptor;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
+
+ /* now set accessed bit in descriptor */
+ dword2 |= 0x0100;
+ if (ti == 0) { /* GDT */
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+ BX_WRITE, &dword2);
+ }
+ else { /* LDT */
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+ BX_WRITE, &dword2);
+ }
+
+ return;
+ }
+ else if ( (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_DS]) ||
+ (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_ES])
+#if BX_CPU_LEVEL >= 3
+ || (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_FS]) ||
+ (seg==&BX_CPU_THIS_PTR sregs[BX_SREG_GS])
+#endif
+ ) {
+ Bit16u index;
+ Bit8u ti;
+ Bit8u rpl;
+ bx_descriptor_t descriptor;
+ Bit32u dword1, dword2;
+
+
+ if ((new_value & 0xfffc) == 0) { /* null selector */
+ seg->selector.index = 0;
+ seg->selector.ti = 0;
+ seg->selector.rpl = 0;
+ seg->selector.value = 0;
+ seg->cache.valid = 0; /* invalidate null selector */
+ return;
+ }
+
+ index = new_value >> 3;
+ ti = (new_value >> 2) & 0x01;
+ rpl = (new_value & 0x03);
+
+ /* selector index must be within descriptor limits, else #GP(selector) */
+
+ if (ti == 0) { /* GDT */
+ if ((index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+ BX_INFO(("load_seg_reg: GDT: %s: index(%04x) > limit(%06x)\n",
+ BX_CPU_THIS_PTR strseg(seg), (unsigned) index, (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+ BX_READ, &dword2);
+ }
+ else { /* LDT */
+ if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
+ BX_INFO(("load_seg_reg: LDT invalid\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ if ((index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+ BX_INFO(("load_seg_reg ds,es: LDT: index > limit\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8, 4, 0,
+ BX_READ, &dword1);
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+ BX_READ, &dword2);
+ }
+
+ parse_descriptor(dword1, dword2, &descriptor);
+
+ if (descriptor.valid==0) {
+ BX_INFO(("load_seg_reg(): valid bit cleared\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+
+ /* AR byte must indicate data or readable code segment else #GP(selector) */
+ if ( descriptor.segment==0 ||
+ (descriptor.u.segment.executable==1 &&
+ descriptor.u.segment.r_w==0) ) {
+ BX_INFO(("load_seg_reg(): not data or readable code\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+
+ /* If data or non-conforming code, then both the RPL and the CPL
+ * must be less than or equal to DPL in AR byte else #GP(selector) */
+ if ( descriptor.u.segment.executable==0 ||
+ descriptor.u.segment.c_ed==0 ) {
+ if ((rpl > descriptor.dpl) || (CPL > descriptor.dpl)) {
+ BX_INFO(("load_seg_reg: RPL & CPL must be <= DPL\n"));
+ exception(BX_GP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+ }
+
+ /* segment must be marked PRESENT else #NP(selector) */
+ if (descriptor.p == 0) {
+ BX_INFO(("load_seg_reg: segment not present\n"));
+ exception(BX_NP_EXCEPTION, new_value & 0xfffc, 0);
+ return;
+ }
+
+ /* load segment register with selector */
+ /* load segment register-cache with descriptor */
+ seg->selector.value = new_value;
+ seg->selector.index = index;
+ seg->selector.ti = ti;
+ seg->selector.rpl = rpl;
+ seg->cache = descriptor;
+ seg->cache.valid = 1;
+
+ /* now set accessed bit in descriptor */
+ dword2 |= 0x0100;
+ if (ti == 0) { /* GDT */
+ access_linear(BX_CPU_THIS_PTR gdtr.base + index*8 + 4, 4, 0,
+ BX_WRITE, &dword2);
+ }
+ else { /* LDT */
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + index*8 + 4, 4, 0,
+ BX_WRITE, &dword2);
+ }
+ return;
+ }
+ else {
+ BX_PANIC(("load_seg_reg(): invalid segment register passed!\n"));
+ return;
+ }
+ }
+
+ /* real mode */
+ /* seg->limit = ; ??? different behaviours depening on seg reg. */
+ /* something about honoring previous values */
+
+ /* ??? */
+ if (seg == &BX_CPU_THIS_PTR sregs[BX_SREG_CS]) {
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = new_value;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* regular segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* code segment */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* expand up */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = new_value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffff;
+#if BX_CPU_LEVEL >= 3
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 0; /* byte granular */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; /* default 16bit size */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+ }
+ else { /* SS, DS, ES, FS, GS */
+ seg->selector.value = new_value;
+ seg->cache.valid = 1;
+ seg->cache.p = 1; // set this???
+ seg->cache.u.segment.base = new_value << 4;
+ seg->cache.segment = 1; /* regular segment */
+ seg->cache.u.segment.a = 1; /* accessed */
+ /* set G, D_B, AVL bits here ??? */
+ }
+#else /* 8086 */
+
+ seg->selector.value = new_value;
+ seg->cache.u.segment.base = new_value << 4;
+#endif
+}
+
+
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::parse_selector(Bit16u raw_selector, bx_selector_t *selector)
+{
+ selector->value = raw_selector;
+ selector->index = raw_selector >> 3;
+ selector->ti = (raw_selector >> 2) & 0x01;
+ selector->rpl = raw_selector & 0x03;
+}
+#endif
+
+ void
+BX_CPU_C::parse_descriptor(Bit32u dword1, Bit32u dword2, bx_descriptor_t *temp)
+{
+ Bit8u AR_byte;
+
+ AR_byte = dword2 >> 8;
+ temp->p = (AR_byte >> 7) & 0x01;
+ temp->dpl = (AR_byte >> 5) & 0x03;
+ temp->segment = (AR_byte >> 4) & 0x01;
+ temp->type = (AR_byte & 0x0f);
+ temp->valid = 0; /* start out invalid */
+
+
+ if (temp->segment) { /* data/code segment descriptors */
+ temp->u.segment.executable = (AR_byte >> 3) & 0x01;
+ temp->u.segment.c_ed = (AR_byte >> 2) & 0x01;
+ temp->u.segment.r_w = (AR_byte >> 1) & 0x01;
+ temp->u.segment.a = (AR_byte >> 0) & 0x01;
+
+ temp->u.segment.limit = (dword1 & 0xffff);
+ temp->u.segment.base = (dword1 >> 16) |
+ ((dword2 & 0xFF) << 16);
+
+#if BX_CPU_LEVEL >= 3
+ temp->u.segment.limit |= (dword2 & 0x000F0000);
+ temp->u.segment.g = (dword2 & 0x00800000) > 0;
+ temp->u.segment.d_b = (dword2 & 0x00400000) > 0;
+ temp->u.segment.avl = (dword2 & 0x00100000) > 0;
+ temp->u.segment.base |= (dword2 & 0xFF000000);
+ if (temp->u.segment.g) {
+ if ( (temp->u.segment.executable==0) && (temp->u.segment.c_ed) )
+ temp->u.segment.limit_scaled = (temp->u.segment.limit << 12);
+ else
+ temp->u.segment.limit_scaled = (temp->u.segment.limit << 12) | 0x0fff;
+ }
+ else
+#endif
+ temp->u.segment.limit_scaled = temp->u.segment.limit;
+
+ temp->valid = 1;
+ }
+ else { // system & gate segment descriptors
+ switch ( temp->type ) {
+ case 0: // reserved
+ case 8: // reserved
+ case 10: // reserved
+ case 13: // reserved
+ temp->valid = 0;
+ break;
+ case 1: // 286 TSS (available)
+ case 3: // 286 TSS (busy)
+ temp->u.tss286.base = (dword1 >> 16) |
+ ((dword2 & 0xff) << 16);
+ temp->u.tss286.limit = (dword1 & 0xffff);
+ temp->valid = 1;
+ break;
+ case 2: // LDT descriptor
+ temp->u.ldt.base = (dword1 >> 16) |
+ ((dword2 & 0xFF) << 16);
+#if BX_CPU_LEVEL >= 3
+ temp->u.ldt.base |= (dword2 & 0xff000000);
+#endif
+ temp->u.ldt.limit = (dword1 & 0xffff);
+ temp->valid = 1;
+ break;
+ case 4: // 286 call gate
+ case 6: // 286 interrupt gate
+ case 7: // 286 trap gate
+ /* word count only used for call gate */
+ temp->u.gate286.word_count = dword2 & 0x1f;
+ temp->u.gate286.dest_selector = dword1 >> 16;;
+ temp->u.gate286.dest_offset = dword1 & 0xffff;
+ temp->valid = 1;
+ break;
+ case 5: // 286/386 task gate
+ temp->u.taskgate.tss_selector = dword1 >> 16;;
+ temp->valid = 1;
+ break;
+
+#if BX_CPU_LEVEL >= 3
+ case 9: // 386 TSS (available)
+ case 11: // 386 TSS (busy)
+ temp->u.tss386.base = (dword1 >> 16) |
+ ((dword2 & 0xff) << 16) |
+ (dword2 & 0xff000000);
+ temp->u.tss386.limit = (dword1 & 0x0000ffff) |
+ (dword2 & 0x000f0000);
+ temp->u.tss386.g = (dword2 & 0x00800000) > 0;
+ temp->u.tss386.avl = (dword2 & 0x00100000) > 0;
+ if (temp->u.tss386.g)
+ temp->u.tss386.limit_scaled = (temp->u.tss386.limit << 12) | 0x0fff;
+ else
+ temp->u.tss386.limit_scaled = temp->u.tss386.limit;
+ temp->valid = 1;
+ break;
+
+ case 12: // 386 call gate
+ case 14: // 386 interrupt gate
+ case 15: // 386 trap gate
+ // word count only used for call gate
+ temp->u.gate386.dword_count = dword2 & 0x1f;
+ temp->u.gate386.dest_selector = dword1 >> 16;;
+ temp->u.gate386.dest_offset = (dword2 & 0xffff0000) |
+ (dword1 & 0x0000ffff);
+ temp->valid = 1;
+ break;
+#endif
+ default: BX_PANIC(("parse_descriptor(): case %d unfinished\n",
+ (unsigned) temp->type));
+ temp->valid = 0;
+ }
+ }
+}
+
+ void
+BX_CPU_C::load_ldtr(bx_selector_t *selector, bx_descriptor_t *descriptor)
+{
+ /* check for null selector, if so invalidate LDTR */
+ if ( (selector->value & 0xfffc)==0 ) {
+ BX_CPU_THIS_PTR ldtr.selector = *selector;
+ BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+ return;
+ }
+
+ if (!descriptor)
+ BX_PANIC(("load_ldtr(): descriptor == NULL!\n"));
+
+ BX_CPU_THIS_PTR ldtr.cache = *descriptor; /* whole structure copy */
+ BX_CPU_THIS_PTR ldtr.selector = *selector;
+
+ if (BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit < 7) {
+ BX_PANIC(("load_ldtr(): ldtr.limit < 7\n"));
+ }
+
+ BX_CPU_THIS_PTR ldtr.cache.valid = 1;
+}
+
+ void
+BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor,
+ Bit8u cpl)
+{
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector = *selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache = *descriptor;
+
+ /* caller may request different CPL then in selector */
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpl;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; /* ??? */
+ // (BW) Added cpl to the selector value.
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value =
+ (0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl;
+}
+
+ void
+BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cpl)
+{
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector = *selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl;
+
+ if ( (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value & 0xfffc) == 0 )
+ BX_PANIC(("load_ss(): null selector passed\n"));
+
+ if ( !BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid ) {
+ BX_PANIC(("load_ss(): invalid selector/descriptor passed.\n"));
+ }
+}
+
+
+
+#if BX_CPU_LEVEL >= 2
+ void
+BX_CPU_C::fetch_raw_descriptor(bx_selector_t *selector,
+ Bit32u *dword1, Bit32u *dword2, Bit8u exception_no)
+{
+ if (selector->ti == 0) { /* GDT */
+ if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit) {
+BX_INFO(("-----------------------------------\n"));
+BX_INFO(("selector->index*8 + 7 = %u\n", (unsigned) selector->index*8 + 7));
+BX_INFO(("gdtr.limit = %u\n", (unsigned) BX_CPU_THIS_PTR gdtr.limit));
+ BX_INFO(("fetch_raw_descriptor: GDT: index > limit\n"));
+debug(BX_CPU_THIS_PTR prev_eip);
+BX_INFO(("-----------------------------------\n"));
+ exception(exception_no, selector->value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
+ BX_READ, dword1);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
+ BX_READ, dword2);
+ }
+ else { /* LDT */
+ if (BX_CPU_THIS_PTR ldtr.cache.valid==0) {
+ BX_PANIC(("fetch_raw_descriptor: LDTR.valid=0\n"));
+ }
+ if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit) {
+ BX_PANIC(("fetch_raw_descriptor: LDT: index > limit\n"));
+ exception(exception_no, selector->value & 0xfffc, 0);
+ return;
+ }
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
+ BX_READ, dword1);
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
+ BX_READ, dword2);
+ }
+}
+#endif
+
+
+
+
+
+ Boolean
+BX_CPU_C::fetch_raw_descriptor2(bx_selector_t *selector,
+ Bit32u *dword1, Bit32u *dword2)
+{
+ if (selector->ti == 0) { /* GDT */
+ if ((selector->index*8 + 7) > BX_CPU_THIS_PTR gdtr.limit)
+ return(0);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8, 4, 0,
+ BX_READ, dword1);
+ access_linear(BX_CPU_THIS_PTR gdtr.base + selector->index*8 + 4, 4, 0,
+ BX_READ, dword2);
+ return(1);
+ }
+ else { /* LDT */
+ if ((selector->index*8 + 7) > BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit)
+ return(0);
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8, 4, 0,
+ BX_READ, dword1);
+ access_linear(BX_CPU_THIS_PTR ldtr.cache.u.ldt.base + selector->index*8 + 4, 4, 0,
+ BX_READ, dword2);
+ return(1);
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+ void
+BX_CPU_C::SHLD_EwGw(BxInstruction_t *i)
+{
+ Bit16u op1_16, op2_16, result_16;
+ Bit32u temp_32, result_32;
+ unsigned count;
+
+ /* op1:op2 << count. result stored in op1 */
+ if (i->b1 == 0x1a4)
+ count = i->Ib;
+ else // 0x1a5
+ count = CL;
+
+ count &= 0x1f; // use only 5 LSB's
+
+
+ if (!count) return; /* NOP */
+ // count is 1..31
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ temp_32 = (op1_16 << 16) | (op2_16); // double formed by op1:op2
+ result_32 = temp_32 << count;
+ if (count > 16) {
+ // hack to act like x86 SHLD when count > 16
+ // actually shifting op1:op2:op2 << count
+ result_32 |= (op2_16 << (count - 16));
+ }
+ result_16 = result_32 >> 16;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * SHLD count affects the following flags: S,Z,P,C,O
+ */
+ set_CF( (temp_32 >> (32 - count)) & 0x01 );
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ set_ZF(result_16 == 0);
+ set_SF(result_16 >> 15);
+ set_PF_base((Bit8u) result_16);
+}
+
+
+ void
+BX_CPU_C::SHRD_EwGw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("shrd_evgvib: not supported on < 386\n"));
+#else
+ Bit16u op1_16, op2_16, result_16;
+ Bit32u temp_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0x1ac)
+ count = i->Ib;
+ else // 0x1ad
+ count = CL;
+ count &= 0x1F; /* use only 5 LSB's */
+
+ if (!count) return; /* NOP */
+
+ // count is 1..31
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+ op2_16 = BX_READ_16BIT_REG(i->nnn);
+
+ temp_32 = (op2_16 << 16) | op1_16; // double formed by op2:op1
+ result_32 = temp_32 >> count;
+ if (count > 16) {
+ // hack to act like x86 SHLD when count > 16
+ // actually shifting op2:op2:op1 >> count
+ result_32 |= (op2_16 << (32 - count));
+ }
+ result_16 = result_32;
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * SHRD count affects the following flags: S,Z,P,C,O
+ */
+
+ set_CF((temp_32 >> (count - 1)) & 0x01);
+ set_ZF(result_16 == 0);
+ set_SF(result_16 >> 15);
+ /* for shift of 1, OF set if sign change occurred. */
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ set_PF_base((Bit8u) result_16);
+#endif /* BX_CPU_LEVEL >= 3 */
+}
+
+
+
+ void
+BX_CPU_C::ROL_Ew(BxInstruction_t *i)
+{
+
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x0f; // only use bottom 4 bits
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ if (count) {
+ result_16 = (op1_16 << count) | (op1_16 >> (16 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * ROL count affects the following flags: C
+ */
+
+ set_CF(result_16 & 0x01);
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::ROR_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16, result_b15;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x0f; // use only 4 LSB's
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ if (count) {
+ result_16 = (op1_16 >> count) | (op1_16 << (16 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * ROR count affects the following flags: C
+ */
+ result_b15 = result_16 & 0x8000;
+
+ set_CF(result_b15 != 0);
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ }
+}
+
+
+
+ void
+BX_CPU_C::RCL_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x1F;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ count %= 17;
+
+ if (!count) return;
+
+ if (count==1) {
+ result_16 = (op1_16 << 1) | get_CF();
+ }
+ else if (count==16) {
+ result_16 = (get_CF() << 15) |
+ (op1_16 >> 1);
+ }
+ else { // 2..15
+ result_16 = (op1_16 << count) |
+ (get_CF() << (count - 1)) |
+ (op1_16 >> (17 - count));
+ }
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * RCL count affects the following flags: C
+ */
+
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ set_CF((op1_16 >> (16 - count)) & 0x01);
+}
+
+
+
+ void
+BX_CPU_C::RCR_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count = count & 0x1F;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ count %= 17;
+ if (count) {
+ result_16 = (op1_16 >> count) |
+ (get_CF() << (16 - count)) |
+ (op1_16 << (17 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * RCR count affects the following flags: C
+ */
+
+ set_CF((op1_16 >> (count - 1)) & 0x01);
+ if (count == 1)
+ set_OF(((op1_16 ^ result_16) & 0x8000) > 0);
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::SHL_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x1F; /* use only 5 LSB's */
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ if (!count) return;
+
+ result_16 = (op1_16 << count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHL16);
+}
+
+
+
+
+ void
+BX_CPU_C::SHR_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x1F; /* use only 5 LSB's */
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ if (!count) return;
+
+ result_16 = (op1_16 >> count);
+
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ SET_FLAGS_OSZAPC_16(op1_16, count, result_16, BX_INSTR_SHR16);
+}
+
+
+
+ void
+BX_CPU_C::SAR_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16, result_16;
+ unsigned count;
+
+ if ( i->b1 == 0xc1 )
+ count = i->Ib;
+ else if ( i->b1 == 0xd1 )
+ count = 1;
+ else // 0xd3
+ count = CL;
+
+ count &= 0x1F; /* use only 5 LSB's */
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ if (!count) return;
+
+ if (count < 16) {
+ if (op1_16 & 0x8000) {
+ result_16 = (op1_16 >> count) | (0xffff << (16 - count));
+ }
+ else {
+ result_16 = (op1_16 >> count);
+ }
+ }
+ else {
+ if (op1_16 & 0x8000) {
+ result_16 = 0xffff;
+ }
+ else {
+ result_16 = 0;
+ }
+ }
+
+
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, result_16);
+ }
+ else {
+ write_RMW_virtual_word(result_16);
+ }
+
+ /* set eflags:
+ * SAR count affects the following flags: S,Z,P,C
+ */
+ if (count < 16) {
+ set_CF((op1_16 >> (count - 1)) & 0x01);
+ }
+ else {
+ if (op1_16 & 0x8000) {
+ set_CF(1);
+ }
+ else {
+ set_CF(0);
+ }
+ }
+
+ set_ZF(result_16 == 0);
+ set_SF(result_16 >> 15);
+ if (count == 1)
+ set_OF(0);
+ set_PF_base((Bit8u) result_16);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::SHLD_EdGd(BxInstruction_t *i)
+{
+ Bit32u op1_32, op2_32, result_32;
+ unsigned count;
+
+ /* op1:op2 << count. result stored in op1 */
+
+ if (i->b1 == 0x1a4)
+ count = i->Ib & 0x1f;
+ else // 0x1a5
+ count = CL & 0x1f;
+
+ if (!count) return; /* NOP */
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ result_32 = (op1_32 << count) | (op2_32 >> (32 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * SHLD count affects the following flags: S,Z,P,C,O
+ */
+ set_CF((op1_32 >> (32 - count)) & 0x01);
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+ set_ZF(result_32 == 0);
+ set_PF_base(result_32);
+ set_SF(result_32 >> 31);
+}
+
+
+ void
+BX_CPU_C::SHRD_EdGd(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ BX_PANIC(("shrd_evgvib: not supported on < 386\n"));
+#else
+ Bit32u op1_32, op2_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0x1ac)
+ count = i->Ib & 0x1f;
+ else // 0x1ad
+ count = CL & 0x1f;
+
+ if (!count) return; /* NOP */
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+ op2_32 = BX_READ_32BIT_REG(i->nnn);
+
+ result_32 = (op2_32 << (32 - count)) | (op1_32 >> count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * SHRD count affects the following flags: S,Z,P,C,O
+ */
+
+ set_CF((op1_32 >> (count - 1)) & 0x01);
+ set_ZF(result_32 == 0);
+ set_SF(result_32 >> 31);
+ /* for shift of 1, OF set if sign change occurred. */
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+ set_PF_base(result_32);
+#endif /* BX_CPU_LEVEL >= 3 */
+}
+
+
+
+ void
+BX_CPU_C::ROL_Ed(BxInstruction_t *i)
+{
+
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (count) {
+ result_32 = (op1_32 << count) | (op1_32 >> (32 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * ROL count affects the following flags: C
+ */
+
+ set_CF(result_32 & 0x01);
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::ROR_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32, result_b31;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (count) {
+ result_32 = (op1_32 >> count) | (op1_32 << (32 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * ROR count affects the following flags: C
+ */
+ result_b31 = result_32 & 0x80000000;
+
+ set_CF(result_b31 != 0);
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+ }
+}
+
+
+
+ void
+BX_CPU_C::RCL_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (!count) return;
+
+ if (count==1) {
+ result_32 = (op1_32 << 1) | get_CF();
+ }
+ else {
+ result_32 = (op1_32 << count) |
+ (get_CF() << (count - 1)) |
+ (op1_32 >> (33 - count));
+ }
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * RCL count affects the following flags: C
+ */
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+ set_CF((op1_32 >> (32 - count)) & 0x01);
+}
+
+
+
+ void
+BX_CPU_C::RCR_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (!count) return;
+
+ if (count==1) {
+ result_32 = (op1_32 >> 1) | (get_CF() << 31);
+ }
+ else {
+ result_32 = (op1_32 >> count) |
+ (get_CF() << (32 - count)) |
+ (op1_32 << (33 - count));
+ }
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * RCR count affects the following flags: C
+ */
+
+ set_CF((op1_32 >> (count - 1)) & 0x01);
+ if (count == 1)
+ set_OF(((op1_32 ^ result_32) & 0x80000000) > 0);
+}
+
+
+
+
+ void
+BX_CPU_C::SHL_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (!count) return;
+
+ result_32 = (op1_32 << count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHL32);
+}
+
+
+
+
+ void
+BX_CPU_C::SHR_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (!count) return;
+
+ result_32 = (op1_32 >> count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ SET_FLAGS_OSZAPC_32(op1_32, count, result_32, BX_INSTR_SHR32);
+}
+
+
+
+ void
+BX_CPU_C::SAR_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32, result_32;
+ unsigned count;
+
+ if (i->b1 == 0xc1)
+ count = i->Ib & 0x1f;
+ else if (i->b1 == 0xd1)
+ count = 1;
+ else // (i->b1 == 0xd3)
+ count = CL & 0x1f;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ if (!count) return;
+
+ /* count < 32, since only lower 5 bits used */
+ if (op1_32 & 0x80000000) {
+ result_32 = (op1_32 >> count) | (0xffffffff << (32 - count));
+ }
+ else {
+ result_32 = (op1_32 >> count);
+ }
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, result_32);
+ }
+ else {
+ write_RMW_virtual_dword(result_32);
+ }
+
+ /* set eflags:
+ * SAR count affects the following flags: S,Z,P,C
+ */
+
+ set_CF((op1_32 >> (count - 1)) & 0x01);
+ set_ZF(result_32 == 0);
+ set_SF(result_32 >> 31);
+ if (count == 1)
+ set_OF(0);
+ set_PF_base(result_32);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::ROL_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count &= 0x07; // use only lowest 3 bits
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (count) {
+ result_8 = (op1_8 << count) | (op1_8 >> (8 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ /* set eflags:
+ * ROL count affects the following flags: C
+ */
+
+ set_CF(result_8 & 0x01);
+ if (count == 1)
+ set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::ROR_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ Bit8u result_b7;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+
+ count &= 0x07; /* use only bottom 3 bits */
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (count) {
+ result_8 = (op1_8 >> count) | (op1_8 << (8 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ /* set eflags:
+ * ROR count affects the following flags: C
+ */
+ result_b7 = result_8 & 0x80;
+
+ set_CF(result_b7 != 0);
+ if (count == 1)
+ set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+ }
+}
+
+
+
+ void
+BX_CPU_C::RCL_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count = (count & 0x1F) % 9;
+
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (count) {
+ result_8 = (op1_8 << count) |
+ (get_CF() << (count - 1)) |
+ (op1_8 >> (9 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ /* set eflags:
+ * RCL count affects the following flags: C
+ */
+ if (count == 1)
+ set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+ set_CF((op1_8 >> (8 - count)) & 0x01);
+ }
+}
+
+
+
+ void
+BX_CPU_C::RCR_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count = ( count & 0x1F ) % 9;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (count) {
+ result_8 = (op1_8 >> count) |
+ (get_CF() << (8 - count)) |
+ (op1_8 << (9 - count));
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ /* set eflags:
+ * RCR count affects the following flags: C
+ */
+
+ set_CF((op1_8 >> (count - 1)) & 0x01);
+ if (count == 1)
+ set_OF(((op1_8 ^ result_8) & 0x80) > 0);
+ }
+}
+
+
+
+
+ void
+BX_CPU_C::SHL_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count &= 0x1F;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (!count) return;
+
+ result_8 = (op1_8 << count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHL8);
+}
+
+
+
+ void
+BX_CPU_C::SHR_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count &= 0x1F;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (!count) return;
+
+ result_8 = (op1_8 >> count);
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ SET_FLAGS_OSZAPC_8(op1_8, count, result_8, BX_INSTR_SHR8);
+}
+
+
+
+
+ void
+BX_CPU_C::SAR_Eb(BxInstruction_t *i)
+{
+ Bit8u op1_8, result_8;
+ unsigned count;
+
+ if (i->b1 == 0xc0)
+ count = i->Ib;
+ else if (i->b1 == 0xd0)
+ count = 1;
+ else // 0xd2
+ count = CL;
+
+ count &= 0x1F;
+
+ /* op1 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_8 = BX_READ_8BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_RMW_virtual_byte(i->seg, i->rm_addr, &op1_8);
+ }
+
+ if (!count) return;
+
+ if (count < 8) {
+ if (op1_8 & 0x80) {
+ result_8 = (op1_8 >> count) | (0xff << (8 - count));
+ }
+ else {
+ result_8 = (op1_8 >> count);
+ }
+ }
+ else {
+ if (op1_8 & 0x80) {
+ result_8 = 0xff;
+ }
+ else {
+ result_8 = 0;
+ }
+ }
+
+ /* now write result back to destination */
+ if (i->mod == 0xc0) {
+ BX_WRITE_8BIT_REG(i->rm, result_8);
+ }
+ else {
+ write_RMW_virtual_byte(result_8);
+ }
+
+ /* set eflags:
+ * SAR count affects the following flags: S,Z,P,C
+ */
+
+ if (count < 8) {
+ set_CF((op1_8 >> (count - 1)) & 0x01);
+ }
+ else {
+ if (op1_8 & 0x80) {
+ set_CF(1);
+ }
+ else {
+ set_CF(0);
+ }
+ }
+
+ set_ZF(result_8 == 0);
+ set_SF(result_8 >> 7);
+ if (count == 1)
+ set_OF(0);
+ set_PF_base(result_8);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+#if 0
+ void
+BX_CPU_C::BOUND_GvMa(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("BOUND_GvMa: not supported on 8086!\n"));
+#else
+
+ if (i->mod == 0xc0) {
+ /* undefined opcode exception */
+ BX_PANIC(("bound: op2 must be mem ref\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (i->os_32) {
+ Bit32s bound_min, bound_max;
+ Bit32s op1_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &bound_min);
+ read_virtual_dword(i->seg, i->rm_addr+4, (Bit32u *) &bound_max);
+
+ /* ??? */
+ if ( (op1_32 < bound_min) || (op1_32 > bound_max) ) {
+ BX_INFO(("BOUND: fails bounds test\n"));
+ exception(5, 0, 0);
+ }
+ }
+ else {
+ Bit16s bound_min, bound_max;
+ Bit16s op1_16;
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &bound_min);
+ read_virtual_word(i->seg, i->rm_addr+2, (Bit16u *) &bound_max);
+
+ /* ??? */
+ if ( (op1_16 < bound_min) || (op1_16 > bound_max) ) {
+ BX_INFO(("BOUND: fails bounds test\n"));
+ exception(5, 0, 0);
+ }
+ }
+
+#endif
+}
+
+ void
+BX_CPU_C::INT1(BxInstruction_t *i)
+{
+ // This is an undocumented instrucion (opcode 0xf1)
+ // which is useful for an ICE system.
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ interrupt(1, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+#endif
+
+ void
+sid_cpu_c::INT3(BxInstruction_t *i)
+{
+ // INT 3 is not IOPL sensitive
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+//BX_PANIC(("INT3: bailing\n"));
+ interrupt(3, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+
+
+ void
+sid_cpu_c::INT_Ib(BxInstruction_t *i)
+{
+ Bit8u imm8;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ imm8 = i->Ib;
+
+ if (v8086_mode() && (IOPL<3)) {
+ //BX_INFO(("int_ib: v8086: IOPL<3\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+#ifdef SHOW_EXIT_STATUS
+if ( (imm8 == 0x21) && (AH == 0x4c) ) {
+ BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x\n", (unsigned) AL, (unsigned) BX));
+ }
+#endif
+
+ interrupt(imm8, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+#if 0
+
+ void
+BX_CPU_C::INTO(BxInstruction_t *i)
+{
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ /* ??? is this IOPL sensitive ? */
+ if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported\n"));
+
+ if (get_OF()) {
+ interrupt(4, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+ }
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+ void
+BX_CPU_C::BOUND_GvMa(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("BOUND_GvMa: not supported on 8086!\n"));
+#else
+
+ if (i->mod == 0xc0) {
+ /* undefined opcode exception */
+ BX_PANIC(("bound: op2 must be mem ref\n"));
+ UndefinedOpcode(i);
+ }
+
+ if (i->os_32) {
+ Bit32s bound_min, bound_max;
+ Bit32s op1_32;
+
+ op1_32 = BX_READ_32BIT_REG(i->nnn);
+
+ read_virtual_dword(i->seg, i->rm_addr, (Bit32u *) &bound_min);
+ read_virtual_dword(i->seg, i->rm_addr+4, (Bit32u *) &bound_max);
+
+ /* ??? */
+ if ( (op1_32 < bound_min) || (op1_32 > bound_max) ) {
+ BX_INFO(("BOUND: fails bounds test\n"));
+ exception(5, 0, 0);
+ }
+ }
+ else {
+ Bit16s bound_min, bound_max;
+ Bit16s op1_16;
+
+ op1_16 = BX_READ_16BIT_REG(i->nnn);
+
+ read_virtual_word(i->seg, i->rm_addr, (Bit16u *) &bound_min);
+ read_virtual_word(i->seg, i->rm_addr+2, (Bit16u *) &bound_max);
+
+ /* ??? */
+ if ( (op1_16 < bound_min) || (op1_16 > bound_max) ) {
+ BX_INFO(("BOUND: fails bounds test\n"));
+ exception(5, 0, 0);
+ }
+ }
+
+#endif
+}
+
+ void
+BX_CPU_C::INT1(BxInstruction_t *i)
+{
+ // This is an undocumented instrucion (opcode 0xf1)
+ // which is useful for an ICE system.
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ interrupt(1, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+
+ void
+BX_CPU_C::INT3(BxInstruction_t *i)
+{
+ // INT 3 is not IOPL sensitive
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+//BX_PANIC(("INT3: bailing\n"));
+ interrupt(3, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+
+
+ void
+BX_CPU_C::INT_Ib(BxInstruction_t *i)
+{
+ Bit8u imm8;
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ imm8 = i->Ib;
+
+ if (v8086_mode() && (IOPL<3)) {
+ //BX_INFO(("int_ib: v8086: IOPL<3\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+#ifdef SHOW_EXIT_STATUS
+if ( (imm8 == 0x21) && (AH == 0x4c) ) {
+ BX_INFO(("INT 21/4C called AL=0x%02x, BX=0x%04x\n", (unsigned) AL, (unsigned) BX));
+ }
+#endif
+
+ interrupt(imm8, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+}
+
+
+ void
+BX_CPU_C::INTO(BxInstruction_t *i)
+{
+
+#if BX_DEBUGGER
+ BX_CPU_THIS_PTR show_flag |= Flag_int;
+#endif
+
+ /* ??? is this IOPL sensitive ? */
+ if (v8086_mode()) BX_PANIC(("soft_int: v8086 mode unsupported\n"));
+
+ if (get_OF()) {
+ interrupt(4, 1, 0, 0);
+ BX_INSTR_FAR_BRANCH(BX_INSTR_IS_INT,
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value,
+ BX_CPU_THIS_PTR eip);
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+ void
+BX_CPU_C::PUSH_RX(BxInstruction_t *i)
+{
+ push_16( BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx );
+}
+
+ void
+BX_CPU_C::POP_RX(BxInstruction_t *i)
+{
+ Bit16u rx;
+
+ pop_16(&rx);
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].word.rx = rx;
+}
+
+ void
+BX_CPU_C::POP_Ew(BxInstruction_t *i)
+{
+ Bit16u val16;
+
+ pop_16(&val16);
+
+ if (i->mod == 0xc0) {
+ BX_WRITE_16BIT_REG(i->rm, val16);
+ }
+ else {
+ // Note: there is one little weirdism here. When 32bit addressing
+ // is used, it is possible to use ESP in the modrm addressing.
+ // If used, the value of ESP after the pop is used to calculate
+ // the address.
+ if (i->as_32 && (i->mod!=0xc0) && (i->rm==4) && (i->base==4)) {
+ BX_CPU_CALL_METHOD (i->ResolveModrm, (i));
+ }
+ write_virtual_word(i->seg, i->rm_addr, &val16);
+ }
+}
+
+ void
+BX_CPU_C::PUSHAD16(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("PUSHAD: not supported on an 8086\n"));
+#else
+ Bit32u temp_ESP;
+ Bit16u sp;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 16) ) {
+ BX_PANIC(("PUSHA(): stack doesn't have enough room!\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+ else
+#endif
+ {
+ if (temp_ESP < 16)
+ BX_PANIC(("pushad: eSP < 16\n"));
+ }
+
+ sp = SP;
+
+ /* ??? optimize this by using virtual write, all checks passed */
+ push_16(AX);
+ push_16(CX);
+ push_16(DX);
+ push_16(BX);
+ push_16(sp);
+ push_16(BP);
+ push_16(SI);
+ push_16(DI);
+#endif
+}
+
+ void
+BX_CPU_C::POPAD16(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("POPAD not supported on an 8086\n"));
+#else /* 286+ */
+
+ Bit16u di, si, bp, tmp, bx, dx, cx, ax;
+
+ if (protected_mode()) {
+ if ( !can_pop(16) ) {
+ BX_PANIC(("pop_a: not enough bytes on stack\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ /* ??? optimize this */
+ pop_16(&di);
+ pop_16(&si);
+ pop_16(&bp);
+ pop_16(&tmp); /* value for SP discarded */
+ pop_16(&bx);
+ pop_16(&dx);
+ pop_16(&cx);
+ pop_16(&ax);
+
+ DI = di;
+ SI = si;
+ BP = bp;
+ BX = bx;
+ DX = dx;
+ CX = cx;
+ AX = ax;
+#endif
+}
+
+ void
+BX_CPU_C::PUSH_Iw(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("PUSH_Iv: not supported on 8086!\n"));
+#else
+
+ Bit16u imm16;
+
+ imm16 = i->Iw;
+
+ push_16(imm16);
+#endif
+}
+
+ void
+BX_CPU_C::PUSH_Ew(BxInstruction_t *i)
+{
+ Bit16u op1_16;
+
+ /* op1_16 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_16 = BX_READ_16BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_word(i->seg, i->rm_addr, &op1_16);
+ }
+
+ push_16(op1_16);
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+
+ void
+BX_CPU_C::POP_Ed(BxInstruction_t *i)
+{
+ Bit32u val32;
+
+ pop_32(&val32);
+
+ if (i->mod == 0xc0) {
+ BX_WRITE_32BIT_REG(i->rm, val32);
+ }
+ else {
+ // Note: there is one little weirdism here. When 32bit addressing
+ // is used, it is possible to use ESP in the modrm addressing.
+ // If used, the value of ESP after the pop is used to calculate
+ // the address.
+ if (i->as_32 && (i->mod!=0xc0) && (i->rm==4) && (i->base==4)) {
+ // call method on BX_CPU_C object
+ BX_CPU_CALL_METHOD (i->ResolveModrm, (i));
+ }
+ write_virtual_dword(i->seg, i->rm_addr, &val32);
+ }
+}
+
+ void
+BX_CPU_C::PUSH_ERX(BxInstruction_t *i)
+{
+ push_32(BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx);
+}
+
+ void
+BX_CPU_C::POP_ERX(BxInstruction_t *i)
+{
+ Bit32u erx;
+
+ pop_32(&erx);
+ BX_CPU_THIS_PTR gen_reg[i->b1 & 0x07].erx = erx;
+}
+
+
+ void
+BX_CPU_C::PUSH_CS(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
+}
+ void
+BX_CPU_C::PUSH_DS(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
+}
+ void
+BX_CPU_C::PUSH_ES(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
+}
+ void
+BX_CPU_C::PUSH_FS(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
+}
+ void
+BX_CPU_C::PUSH_GS(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
+}
+ void
+BX_CPU_C::PUSH_SS(BxInstruction_t *i)
+{
+ if (i->os_32)
+ push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+ else
+ push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
+}
+
+
+ void
+BX_CPU_C::POP_DS(BxInstruction_t *i)
+{
+ if (i->os_32) {
+ Bit32u ds;
+ pop_32(&ds);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], (Bit16u) ds);
+ }
+ else {
+ Bit16u ds;
+ pop_16(&ds);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], ds);
+ }
+}
+ void
+BX_CPU_C::POP_ES(BxInstruction_t *i)
+{
+ if (i->os_32) {
+ Bit32u es;
+ pop_32(&es);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], (Bit16u) es);
+ }
+ else {
+ Bit16u es;
+ pop_16(&es);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], es);
+ }
+}
+ void
+BX_CPU_C::POP_FS(BxInstruction_t *i)
+{
+ if (i->os_32) {
+ Bit32u fs;
+ pop_32(&fs);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
+ }
+ else {
+ Bit16u fs;
+ pop_16(&fs);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], fs);
+ }
+}
+ void
+BX_CPU_C::POP_GS(BxInstruction_t *i)
+{
+ if (i->os_32) {
+ Bit32u gs;
+ pop_32(&gs);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
+ }
+ else {
+ Bit16u gs;
+ pop_16(&gs);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], gs);
+ }
+}
+ void
+BX_CPU_C::POP_SS(BxInstruction_t *i)
+{
+ if (i->os_32) {
+ Bit32u ss;
+ pop_32(&ss);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], (Bit16u) ss);
+ }
+ else {
+ Bit16u ss;
+ pop_16(&ss);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], ss);
+ }
+
+ // POP SS inhibits interrupts, debug exceptions and single-step
+ // trap exceptions until the execution boundary following the
+ // next instruction is reached.
+ // Same code as MOV_SwEw()
+ BX_CPU_THIS_PTR inhibit_mask |=
+ BX_INHIBIT_INTERRUPTS | BX_INHIBIT_DEBUG;
+ BX_CPU_THIS_PTR async_event = 1;
+}
+
+
+ void
+BX_CPU_C::PUSHAD32(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("PUSHAD: not supported on an 8086\n"));
+#else
+ Bit32u temp_ESP;
+ Bit32u esp;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+
+ if (protected_mode()) {
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 32) ) {
+ BX_PANIC(("PUSHAD(): stack doesn't have enough room!\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+ else {
+ if (temp_ESP < 32)
+ BX_PANIC(("pushad: eSP < 32\n"));
+ }
+
+ esp = ESP;
+
+ /* ??? optimize this by using virtual write, all checks passed */
+ push_32(EAX);
+ push_32(ECX);
+ push_32(EDX);
+ push_32(EBX);
+ push_32(esp);
+ push_32(EBP);
+ push_32(ESI);
+ push_32(EDI);
+#endif
+}
+
+ void
+BX_CPU_C::POPAD32(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("POPAD not supported on an 8086\n"));
+#else /* 286+ */
+ Bit32u edi, esi, ebp, etmp, ebx, edx, ecx, eax;
+
+ if (protected_mode()) {
+ if ( !can_pop(32) ) {
+ BX_PANIC(("pop_ad: not enough bytes on stack\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ /* ??? optimize this */
+ pop_32(&edi);
+ pop_32(&esi);
+ pop_32(&ebp);
+ pop_32(&etmp); /* value for ESP discarded */
+ pop_32(&ebx);
+ pop_32(&edx);
+ pop_32(&ecx);
+ pop_32(&eax);
+
+ EDI = edi;
+ ESI = esi;
+ EBP = ebp;
+ EBX = ebx;
+ EDX = edx;
+ ECX = ecx;
+ EAX = eax;
+#endif
+}
+
+ void
+BX_CPU_C::PUSH_Id(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("PUSH_Iv: not supported on 8086!\n"));
+#else
+
+ Bit32u imm32;
+
+ imm32 = i->Id;
+
+ push_32(imm32);
+#endif
+}
+
+ void
+BX_CPU_C::PUSH_Ed(BxInstruction_t *i)
+{
+ Bit32u op1_32;
+
+ /* op1_32 is a register or memory reference */
+ if (i->mod == 0xc0) {
+ op1_32 = BX_READ_32BIT_REG(i->rm);
+ }
+ else {
+ /* pointer, segment address pair */
+ read_virtual_dword(i->seg, i->rm_addr, &op1_32);
+ }
+
+ push_32(op1_32);
+}
+
+
+ void
+BX_CPU_C::ENTER_IwIb(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("ENTER_IwIb: not supported by 8086!\n"));
+#else
+ Bit32u frame_ptr32;
+ Bit16u frame_ptr16;
+ Bit8u level;
+
+ level = i->Ib2;
+
+ invalidate_prefetch_q();
+
+ level %= 32;
+/* ??? */
+if (level) BX_PANIC(("enter(): level > 0\n"));
+//if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b && i->os_32==0) {
+// BX_INFO(("enter(): stacksize!=opsize: I'm unsure of the code for this\n"));
+// BX_PANIC((" The Intel manuals are a mess on this one!\n"));
+// }
+
+ if ( protected_mode() ) {
+ Bit32u bytes_to_push, temp_ESP;
+
+ if (level == 0) {
+ if (i->os_32)
+ bytes_to_push = 4 + i->Iw;
+ else
+ bytes_to_push = 2 + i->Iw;
+ }
+ else { /* level > 0 */
+ if (i->os_32)
+ bytes_to_push = 4 + (level-1)*4 + 4 + i->Iw;
+ else
+ bytes_to_push = 2 + (level-1)*2 + 2 + i->Iw;
+ }
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+ if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, bytes_to_push) ) {
+ BX_PANIC(("ENTER: not enough room on stack!\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ }
+ }
+
+ if (i->os_32)
+ push_32(EBP);
+ else
+ push_16(BP);
+
+ // can just do frame_ptr32 = ESP for either case ???
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ frame_ptr32 = ESP;
+ else
+ frame_ptr32 = SP;
+
+ if (level > 0) {
+ /* do level-1 times */
+ while (--level) {
+ if (i->os_32) {
+ Bit32u temp32;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+ EBP -= 4;
+ read_virtual_dword(BX_SEG_REG_SS, EBP, &temp32);
+ ESP -= 4;
+ write_virtual_dword(BX_SEG_REG_SS, ESP, &temp32);
+ }
+ else { /* 16bit stacksize */
+ BP -= 4;
+ read_virtual_dword(BX_SEG_REG_SS, BP, &temp32);
+ SP -= 4;
+ write_virtual_dword(BX_SEG_REG_SS, SP, &temp32);
+ }
+ }
+ else { /* 16bit opsize */
+ Bit16u temp16;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+ EBP -= 2;
+ read_virtual_word(BX_SEG_REG_SS, EBP, &temp16);
+ ESP -= 2;
+ write_virtual_word(BX_SEG_REG_SS, ESP, &temp16);
+ }
+ else { /* 16bit stacksize */
+ BP -= 2;
+ read_virtual_word(BX_SEG_REG_SS, BP, &temp16);
+ SP -= 2;
+ write_virtual_word(BX_SEG_REG_SS, SP, &temp16);
+ }
+ }
+ } /* while (--level) */
+
+ /* push(frame pointer) */
+ if (i->os_32) {
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+ ESP -= 4;
+ write_virtual_dword(BX_SEG_REG_SS, ESP, &frame_ptr32);
+ }
+ else {
+ SP -= 4;
+ write_virtual_dword(BX_SEG_REG_SS, SP, &frame_ptr32);
+ }
+ }
+ else { /* 16bit opsize */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+ frame_ptr16 = frame_ptr32;
+ ESP -= 2;
+ write_virtual_word(BX_SEG_REG_SS, ESP, &frame_ptr16);
+ }
+ else {
+ frame_ptr16 = frame_ptr32;
+ SP -= 2;
+ write_virtual_word(BX_SEG_REG_SS, SP, &frame_ptr16);
+ }
+ }
+ } /* if (level > 0) ... */
+
+ if (i->os_32)
+ EBP = frame_ptr32;
+ else
+ BP = frame_ptr32;
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* 32bit stacksize */
+ ESP = ESP - i->Iw;
+ }
+ else { /* 16bit stack */
+ SP = SP - i->Iw;
+ }
+#endif
+}
+
+ void
+BX_CPU_C::LEAVE(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 2
+ BX_PANIC(("LEAVE: not supported by 8086!\n"));
+#else
+ Bit32u temp_EBP;
+
+
+ invalidate_prefetch_q();
+
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_EBP = EBP;
+ else
+#endif
+ temp_EBP = BP;
+
+ if ( protected_mode() ) {
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed) { /* expand up */
+ if (temp_EBP <= BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("LEAVE: BP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].limit\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+ else { /* normal */
+ if (temp_EBP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled) {
+ BX_PANIC(("LEAVE: BP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].limit\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+ }
+
+
+ // delete frame
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP = EBP;
+ else
+#endif
+ SP = BP;
+
+ // restore frame pointer
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u temp32;
+
+ pop_32(&temp32);
+ EBP = temp32;
+ }
+ else
+#endif
+ {
+ Bit16u temp16;
+
+ pop_16(&temp16);
+ BP = temp16;
+ }
+#endif
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+ void
+BX_CPU_C::push_16(Bit16u value16)
+{
+ Bit32u temp_ESP;
+
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+#endif
+ temp_ESP = SP;
+ if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_ESP, 2)) {
+ BX_PANIC(("push_16(): can't push on stack\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+
+ /* access within limits */
+ write_virtual_word(BX_SEG_REG_SS, temp_ESP - 2, &value16);
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP -= 2;
+ else
+ SP -= 2;
+ return;
+ }
+ else
+#endif
+ { /* real mode */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) {
+ if (ESP == 1)
+ BX_PANIC(("CPU shutting down due to lack of stack space, ESP==1\n"));
+ ESP -= 2;
+ temp_ESP = ESP;
+ }
+ else {
+ if (SP == 1)
+ BX_PANIC(("CPU shutting down due to lack of stack space, SP==1\n"));
+ SP -= 2;
+ temp_ESP = SP;
+ }
+
+ write_virtual_word(BX_SEG_REG_SS, temp_ESP, &value16);
+ return;
+ }
+}
+
+#if BX_CPU_LEVEL >= 3
+ /* push 32 bit operand size */
+ void
+BX_CPU_C::push_32(Bit32u value32)
+{
+ /* must use StackAddrSize, and either ESP or SP accordingly */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
+ /* 32bit stack size: pushes use SS:ESP */
+ if (protected_mode()) {
+ if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, ESP, 4)) {
+ BX_PANIC(("push_32(): push outside stack limits\n"));
+ /* #SS(0) */
+ }
+ }
+ else { /* real mode */
+ if ((ESP>=1) && (ESP<=3)) {
+ BX_PANIC(("push_32: ESP=%08x\n", (unsigned) ESP));
+ }
+ }
+
+ write_virtual_dword(BX_SEG_REG_SS, ESP-4, &value32);
+ ESP -= 4;
+ /* will return after error anyway */
+ return;
+ }
+ else { /* 16bit stack size: pushes use SS:SP */
+ if (protected_mode()) {
+ if (!can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, SP, 4)) {
+ BX_PANIC(("push_32(): push outside stack limits\n"));
+ /* #SS(0) */
+ }
+ }
+ else { /* real mode */
+ if ((SP>=1) && (SP<=3)) {
+ BX_PANIC(("push_32: SP=%08x\n", (unsigned) SP));
+ }
+ }
+
+ write_virtual_dword(BX_SEG_REG_SS, (Bit16u) (SP-4), &value32);
+ SP -= 4;
+ /* will return after error anyway */
+ return;
+ }
+}
+#endif /* BX_CPU_LEVEL >= 3 */
+
+ void
+BX_CPU_C::pop_16(Bit16u *value16_ptr)
+{
+ Bit32u temp_ESP;
+
+#if BX_CPU_LEVEL >= 3
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+#endif
+ temp_ESP = SP;
+
+#if BX_CPU_LEVEL >= 2
+ if (protected_mode()) {
+ if ( !can_pop(2) ) {
+ BX_INFO(("pop_16(): can't pop from stack\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+#endif
+
+
+ /* access within limits */
+ read_virtual_word(BX_SEG_REG_SS, temp_ESP, value16_ptr);
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ ESP += 2;
+ else
+ SP += 2;
+}
+
+#if BX_CPU_LEVEL >= 3
+ void
+BX_CPU_C::pop_32(Bit32u *value32_ptr)
+{
+ Bit32u temp_ESP;
+
+ /* 32 bit stack mode: use SS:ESP */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ /* 16 bit stack mode: use SS:SP */
+ if (protected_mode()) {
+ if ( !can_pop(4) ) {
+ BX_PANIC(("pop_32(): can't pop from stack\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+ }
+
+ /* access within limits */
+ read_virtual_dword(BX_SEG_REG_SS, temp_ESP, value32_ptr);
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b==1)
+ ESP += 4;
+ else
+ SP += 4;
+}
+#endif
+
+
+
+#if BX_CPU_LEVEL >= 2
+ Boolean
+BX_CPU_C::can_push(bx_descriptor_t *descriptor, Bit32u esp, Bit32u bytes)
+{
+ if ( real_mode() ) { /* code not needed ??? */
+ BX_PANIC(("can_push(): called in real mode\n"));
+ return(0); /* never gets here */
+ }
+
+ // small stack compares against 16-bit SP
+ if (!descriptor->u.segment.d_b)
+ esp &= 0x0000ffff;
+
+
+ if (descriptor->valid==0) {
+ BX_PANIC(("can_push(): SS invalidated.\n"));
+ return(0);
+ }
+
+ if (descriptor->p==0) {
+ BX_PANIC(("can_push(): not present\n"));
+ return(0);
+ }
+
+
+ if (descriptor->u.segment.c_ed) { /* expand down segment */
+ Bit32u expand_down_limit;
+
+ if (descriptor->u.segment.d_b)
+ expand_down_limit = 0xffffffff;
+ else
+ expand_down_limit = 0x0000ffff;
+
+ if (esp==0) {
+ BX_PANIC(("can_push(): esp=0, wraparound?\n"));
+ return(0);
+ }
+
+ if (esp < bytes) {
+ BX_PANIC(("can_push(): expand-down: esp < N\n"));
+ return(0);
+ }
+ if ( (esp - bytes) <= descriptor->u.segment.limit_scaled ) {
+ BX_PANIC(("can_push(): expand-down: esp-N < limit\n"));
+ return(0);
+ }
+ if ( esp > expand_down_limit ) {
+ BX_PANIC(("can_push(): esp > expand-down-limit\n"));
+ return(0);
+ }
+ return(1);
+ }
+ else { /* normal (expand-up) segment */
+ if (descriptor->u.segment.limit_scaled==0) {
+ BX_PANIC(("can_push(): found limit of 0\n"));
+ return(0);
+ }
+
+ // Look at case where esp==0. Possibly, it's an intentional wraparound
+ // If so, limit must be the maximum for the given stack size
+ if (esp==0) {
+ if (descriptor->u.segment.d_b && (descriptor->u.segment.limit_scaled==0xffffffff))
+ return(1);
+ if ((descriptor->u.segment.d_b==0) && (descriptor->u.segment.limit_scaled>=0xffff))
+ return(1);
+ BX_PANIC(("can_push(): esp=0, normal, wraparound? limit=%08x\n",
+ descriptor->u.segment.limit_scaled));
+ return(0);
+ }
+
+ if (esp < bytes) {
+ BX_INFO(("can_push(): expand-up: esp < N\n"));
+ return(0);
+ }
+ if ((esp-1) > descriptor->u.segment.limit_scaled) {
+ BX_INFO(("can_push(): expand-up: SP > limit\n"));
+ return(0);
+ }
+ /* all checks pass */
+ return(1);
+ }
+}
+#endif
+
+
+#if BX_CPU_LEVEL >= 2
+ Boolean
+BX_CPU_C::can_pop(Bit32u bytes)
+{
+ Bit32u temp_ESP, expand_down_limit;
+
+ /* ??? */
+ if (real_mode()) BX_PANIC(("can_pop(): called in real mode?\n"));
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* Big bit set: use ESP */
+ temp_ESP = ESP;
+ expand_down_limit = 0xFFFFFFFF;
+ }
+ else { /* Big bit clear: use SP */
+ temp_ESP = SP;
+ expand_down_limit = 0xFFFF;
+ }
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid==0) {
+ BX_PANIC(("can_pop(): SS invalidated.\n"));
+ return(0); /* never gets here */
+ }
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p==0) { /* ??? */
+ BX_PANIC(("can_pop(): SS.p = 0\n"));
+ return(0);
+ }
+
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed) { /* expand down segment */
+ if ( temp_ESP == expand_down_limit ) {
+ BX_PANIC(("can_pop(): found SP=ffff\n"));
+ return(0);
+ }
+ if ( ((expand_down_limit - temp_ESP) + 1) >= bytes )
+ return(1);
+ return(0);
+ }
+ else { /* normal (expand-up) segment */
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled==0) {
+ BX_PANIC(("can_pop(): SS.limit = 0\n"));
+ }
+ if ( temp_ESP == expand_down_limit ) {
+ BX_PANIC(("can_pop(): found SP=ffff\n"));
+ return(0);
+ }
+ if ( temp_ESP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled ) {
+ BX_PANIC(("can_pop(): eSP > SS.limit\n"));
+ return(0);
+ }
+ if ( ((BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled - temp_ESP) + 1) >= bytes )
+ return(1);
+ return(0);
+ }
+}
+#endif
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+// Classes for helping to make checkpoints of the emulator state.
+
+#ifndef _STATE_FILE_H
+#define _STATE_FILE_H
+#include <stdio.h>
+#include <stddef.h>
+
+
+class state_file {
+ void init(void);
+public:
+ FILE *file;
+ class logfunctions *log;
+
+ FILE *get_handle();
+ void write(Bit8u);
+ void write(Bit16u);
+ void write(Bit32u);
+ void write(Bit64u);
+ void write(const void*, size_t);
+ void read(Bit8u &);
+ void read(Bit16u &);
+ void read(Bit32u &);
+ void read(Bit64u &);
+ void read(void *, size_t);
+ void write_check(const char *);
+ void read_check (const char *);
+
+ state_file (const char *name, const char *options);
+ state_file (FILE *f);
+ ~state_file();
+};
+
+#endif // #ifndef _STATE_FILE_H
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+/* MOVSB ES:[EDI], DS:[ESI] DS may be overridden
+ * mov string from DS:[ESI] into ES:[EDI]
+ */
+
+ void
+BX_CPU_C::MOVSB_XbYb(BxInstruction_t *i)
+{
+ unsigned seg;
+ Bit8u temp8;
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u esi, edi;
+
+ esi = ESI;
+ edi = EDI;
+
+ read_virtual_byte(seg, esi, &temp8);
+
+ write_virtual_byte(BX_SEG_REG_ES, edi, &temp8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI, EDI */
+ esi--;
+ edi--;
+ }
+ else {
+ /* increment ESI, EDI */
+ esi++;
+ edi++;
+ }
+
+ ESI = esi;
+ EDI = edi;
+ }
+
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit address mode */
+ Bit16u si, di;
+
+ si = SI;
+ di = DI;
+
+ read_virtual_byte(seg, si, &temp8);
+
+ write_virtual_byte(BX_SEG_REG_ES, di, &temp8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement SI, DI */
+ si--;
+ di--;
+ }
+ else {
+ /* increment SI, DI */
+ si++;
+ di++;
+ }
+
+ SI = si;
+ DI = di;
+ }
+}
+
+ void
+BX_CPU_C::MOVSW_XvYv(BxInstruction_t *i)
+{
+ unsigned seg;
+
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u temp32;
+
+ Bit32u esi, edi;
+
+ esi = ESI;
+ edi = EDI;
+
+ if (i->os_32) {
+ read_virtual_dword(seg, esi, &temp32);
+
+ write_virtual_dword(BX_SEG_REG_ES, edi, &temp32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 4;
+ edi -= 4;
+ }
+ else {
+ /* increment ESI */
+ esi += 4;
+ edi += 4;
+ }
+ } /* if (i->os_32) ... */
+ else { /* 16 bit opsize mode */
+ Bit16u temp16;
+
+ read_virtual_word(seg, esi, &temp16);
+
+ write_virtual_word(BX_SEG_REG_ES, edi, &temp16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 2;
+ edi -= 2;
+ }
+ else {
+ /* increment ESI */
+ esi += 2;
+ edi += 2;
+ }
+ }
+
+ ESI = esi;
+ EDI = edi;
+ }
+
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u si, di;
+
+ si = SI;
+ di = DI;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u temp32;
+
+ read_virtual_dword(seg, si, &temp32);
+
+ write_virtual_dword(BX_SEG_REG_ES, di, &temp32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si -= 4;
+ di -= 4;
+ }
+ else {
+ /* increment ESI */
+ si += 4;
+ di += 4;
+ }
+ } /* if (i->os_32) ... */
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize mode */
+ Bit16u temp16;
+
+ read_virtual_word(seg, si, &temp16);
+
+ write_virtual_word(BX_SEG_REG_ES, di, &temp16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement SI, DI */
+ si -= 2;
+ di -= 2;
+ }
+ else {
+ /* increment SI, DI */
+ si += 2;
+ di += 2;
+ }
+ }
+
+ SI = si;
+ DI = di;
+ }
+}
+
+ void
+BX_CPU_C::CMPSB_XbYb(BxInstruction_t *i)
+{
+ unsigned seg;
+ Bit8u op1_8, op2_8, diff_8;
+
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u esi, edi;
+
+ esi = ESI;
+ edi = EDI;
+
+ read_virtual_byte(seg, esi, &op1_8);
+
+ read_virtual_byte(BX_SEG_REG_ES, edi, &op2_8);
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMPS8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi--;
+ edi--;
+ }
+ else {
+ /* increment ESI */
+ esi++;
+ edi++;
+ }
+
+ EDI = edi;
+ ESI = esi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u si, di;
+
+ si = SI;
+ di = DI;
+
+ read_virtual_byte(seg, si, &op1_8);
+
+ read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_CMPS8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si--;
+ di--;
+ }
+ else {
+ /* increment ESI */
+ si++;
+ di++;
+ }
+
+ DI = di;
+ SI = si;
+ }
+}
+
+ void
+BX_CPU_C::CMPSW_XvYv(BxInstruction_t *i)
+{
+ unsigned seg;
+
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u op1_32, op2_32, diff_32;
+ Bit32u esi, edi;
+
+ esi = ESI;
+ edi = EDI;
+
+
+ if (i->os_32) {
+ read_virtual_dword(seg, esi, &op1_32);
+
+ read_virtual_dword(BX_SEG_REG_ES, edi, &op2_32);
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMPS32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 4;
+ edi -= 4;
+ }
+ else {
+ /* increment ESI */
+ esi += 4;
+ edi += 4;
+ }
+ }
+ else { /* 16 bit opsize */
+ Bit16u op1_16, op2_16, diff_16;
+
+ read_virtual_word(seg, esi, &op1_16);
+
+ read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 2;
+ edi -= 2;
+ }
+ else {
+ /* increment ESI */
+ esi += 2;
+ edi += 2;
+ }
+ }
+
+
+ EDI = edi;
+ ESI = esi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit address mode */
+ Bit16u si, di;
+
+ si = SI;
+ di = DI;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u op1_32, op2_32, diff_32;
+
+ read_virtual_dword(seg, si, &op1_32);
+
+ read_virtual_dword(BX_SEG_REG_ES, di, &op2_32);
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_CMPS32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si -= 4;
+ di -= 4;
+ }
+ else {
+ /* increment ESI */
+ si += 4;
+ di += 4;
+ }
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize */
+ Bit16u op1_16, op2_16, diff_16;
+
+ read_virtual_word(seg, si, &op1_16);
+
+ read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_CMPS16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si -= 2;
+ di -= 2;
+ }
+ else {
+ /* increment ESI */
+ si += 2;
+ di += 2;
+ }
+ }
+
+
+ DI = di;
+ SI = si;
+ }
+}
+
+ void
+BX_CPU_C::SCASB_ALXb(BxInstruction_t *i)
+{
+ Bit8u op1_8, op2_8, diff_8;
+
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u edi;
+
+ edi = EDI;
+
+ op1_8 = AL;
+
+ read_virtual_byte(BX_SEG_REG_ES, edi, &op2_8);
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
+
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ edi--;
+ }
+ else {
+ /* increment ESI */
+ edi++;
+ }
+
+ EDI = edi;
+ }
+
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u di;
+
+ di = DI;
+
+ op1_8 = AL;
+
+ read_virtual_byte(BX_SEG_REG_ES, di, &op2_8);
+
+ diff_8 = op1_8 - op2_8;
+
+ SET_FLAGS_OSZAPC_8(op1_8, op2_8, diff_8, BX_INSTR_SCAS8);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ di--;
+ }
+ else {
+ /* increment ESI */
+ di++;
+ }
+
+ DI = di;
+ }
+}
+
+ void
+BX_CPU_C::SCASW_eAXXv(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u edi;
+
+ edi = EDI;
+
+ if (i->os_32) {
+ Bit32u op1_32, op2_32, diff_32;
+
+ op1_32 = EAX;
+ read_virtual_dword(BX_SEG_REG_ES, edi, &op2_32);
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SCAS32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ edi -= 4;
+ }
+ else {
+ /* increment ESI */
+ edi += 4;
+ }
+ }
+ else { /* 16 bit opsize */
+ Bit16u op1_16, op2_16, diff_16;
+
+ op1_16 = AX;
+ read_virtual_word(BX_SEG_REG_ES, edi, &op2_16);
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ edi -= 2;
+ }
+ else {
+ /* increment ESI */
+ edi += 2;
+ }
+ }
+
+ EDI = edi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u di;
+
+ di = DI;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u op1_32, op2_32, diff_32;
+
+ op1_32 = EAX;
+ read_virtual_dword(BX_SEG_REG_ES, di, &op2_32);
+
+ diff_32 = op1_32 - op2_32;
+
+ SET_FLAGS_OSZAPC_32(op1_32, op2_32, diff_32, BX_INSTR_SCAS32);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ di -= 4;
+ }
+ else {
+ /* increment ESI */
+ di += 4;
+ }
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize */
+ Bit16u op1_16, op2_16, diff_16;
+
+ op1_16 = AX;
+ read_virtual_word(BX_SEG_REG_ES, di, &op2_16);
+
+ diff_16 = op1_16 - op2_16;
+
+ SET_FLAGS_OSZAPC_16(op1_16, op2_16, diff_16, BX_INSTR_SCAS16);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ di -= 2;
+ }
+ else {
+ /* increment ESI */
+ di += 2;
+ }
+ }
+
+ DI = di;
+ }
+}
+
+ void
+BX_CPU_C::STOSB_YbAL(BxInstruction_t *i)
+{
+ Bit8u al;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u edi;
+
+ edi = EDI;
+
+ al = AL;
+ write_virtual_byte(BX_SEG_REG_ES, edi, &al);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ edi--;
+ }
+ else {
+ /* increment EDI */
+ edi++;
+ }
+
+ EDI = edi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address size */
+ Bit16u di;
+
+ di = DI;
+
+ al = AL;
+ write_virtual_byte(BX_SEG_REG_ES, di, &al);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ di--;
+ }
+ else {
+ /* increment EDI */
+ di++;
+ }
+
+ DI = di;
+ }
+}
+
+ void
+BX_CPU_C::STOSW_YveAX(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u edi;
+
+ edi = EDI;
+
+ if (i->os_32) {
+ Bit32u eax;
+
+ eax = EAX;
+ write_virtual_dword(BX_SEG_REG_ES, edi, &eax);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ edi -= 4;
+ }
+ else {
+ /* increment EDI */
+ edi += 4;
+ }
+ } /* if (i->os_32) ... */
+ else { /* 16 bit opsize mode */
+ Bit16u ax;
+
+ ax = AX;
+ write_virtual_word(BX_SEG_REG_ES, edi, &ax);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ edi -= 2;
+ }
+ else {
+ /* increment EDI */
+ edi += 2;
+ }
+ }
+
+ EDI = edi;
+ }
+
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address size */
+ Bit16u di;
+
+ di = DI;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u eax;
+
+ eax = EAX;
+ write_virtual_dword(BX_SEG_REG_ES, di, &eax);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ di -= 4;
+ }
+ else {
+ /* increment EDI */
+ di += 4;
+ }
+ } /* if (i->os_32) ... */
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize mode */
+ Bit16u ax;
+
+ ax = AX;
+ write_virtual_word(BX_SEG_REG_ES, di, &ax);
+
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement EDI */
+ di -= 2;
+ }
+ else {
+ /* increment EDI */
+ di += 2;
+ }
+ }
+
+ DI = di;
+ }
+}
+
+
+ void
+BX_CPU_C::LODSB_ALXb(BxInstruction_t *i)
+{
+ unsigned seg;
+ Bit8u al;
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u esi;
+
+ esi = ESI;
+
+ read_virtual_byte(seg, esi, &al);
+
+ AL = al;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi--;
+ }
+ else {
+ /* increment ESI */
+ esi++;
+ }
+
+ ESI = esi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u si;
+
+ si = SI;
+
+ read_virtual_byte(seg, si, &al);
+
+ AL = al;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si--;
+ }
+ else {
+ /* increment ESI */
+ si++;
+ }
+
+ SI = si;
+ }
+}
+
+ void
+BX_CPU_C::LODSW_eAXXv(BxInstruction_t *i)
+{
+ unsigned seg;
+
+ if (!BX_NULL_SEG_REG(i->seg)) {
+ seg = i->seg;
+ }
+ else {
+ seg = BX_SEG_REG_DS;
+ }
+
+#if BX_CPU_LEVEL >= 3
+ if (i->as_32) {
+ Bit32u esi;
+
+ esi = ESI;
+
+ if (i->os_32) {
+ Bit32u eax;
+
+ read_virtual_dword(seg, esi, &eax);
+
+ EAX = eax;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 4;
+ }
+ else {
+ /* increment ESI */
+ esi += 4;
+ }
+ } /* if (i->os_32) ... */
+ else { /* 16 bit opsize mode */
+ Bit16u ax;
+ read_virtual_word(seg, esi, &ax);
+
+ AX = ax;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ esi -= 2;
+ }
+ else {
+ /* increment ESI */
+ esi += 2;
+ }
+ }
+
+ ESI = esi;
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16bit address mode */
+ Bit16u si;
+
+ si = SI;
+
+#if BX_CPU_LEVEL >= 3
+ if (i->os_32) {
+ Bit32u eax;
+
+ read_virtual_dword(seg, si, &eax);
+
+ EAX = eax;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si -= 4;
+ }
+ else {
+ /* increment ESI */
+ si += 4;
+ }
+ }
+ else
+#endif /* BX_CPU_LEVEL >= 3 */
+ { /* 16 bit opsize mode */
+ Bit16u ax;
+
+ read_virtual_word(seg, si, &ax);
+
+ AX = ax;
+ if (BX_CPU_THIS_PTR eflags.df) {
+ /* decrement ESI */
+ si -= 2;
+ }
+ else {
+ /* increment ESI */
+ si += 2;
+ }
+ }
+
+ SI = si;
+ }
+}
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+
+
+
+#if BX_SUPPORT_TASKING
+
+#if BX_CPU_LEVEL >= 2
+
+// Notes:
+// ======
+// Step 2: TSS descriptor is not busy TS (for IRET); GP (for JMP, CALL, INT)
+// returns error code (Task's backlink TSS)???
+
+// * TSS selector must map to GDT
+// * TSS is stored in linear address space
+// * what to do with I/O Map Base
+// * what to do with T flag
+// * where to set CR3 and flush paging cache
+// * what happens when fault occurs, with some seg regs having valid bit cleared?
+// * should check validity of current TR(TSS) before writing into it
+//
+
+ // ======================
+ // 286 Task State Segment
+ // ======================
+ // dynamic item | hex dec offset
+ // 0 task LDT selector | 2a 42
+ // 1 DS selector | 28 40
+ // 1 SS selector | 26 38
+ // 1 CS selector | 24 36
+ // 1 ES selector | 22 34
+ // 1 DI | 20 32
+ // 1 SI | 1e 30
+ // 1 BP | 1c 28
+ // 1 SP | 1a 26
+ // 1 BX | 18 24
+ // 1 DX | 16 22
+ // 1 CX | 14 20
+ // 1 AX | 12 18
+ // 1 flag word | 10 16
+ // 1 IP (entry point) | 0e 14
+ // 0 SS for CPL 2 | 0c 12
+ // 0 SP for CPL 2 | 0a 10
+ // 0 SS for CPL 1 | 08 08
+ // 0 SP for CPL 1 | 06 06
+ // 0 SS for CPL 0 | 04 04
+ // 0 SP for CPL 0 | 02 02
+ // back link selector to TSS | 00 00
+
+
+ // ======================
+ // 386 Task State Segment
+ // ======================
+ // |31 16|15 0|
+ // |I/O Map Base |000000000000000000000|T| 64 static
+ // |0000000000000000| LDT | 60 static
+ // |0000000000000000| GS selector | 5c dynamic
+ // |0000000000000000| FS selector | 58 dynamic
+ // |0000000000000000| DS selector | 54 dynamic
+ // |0000000000000000| SS selector | 50 dynamic
+ // |0000000000000000| CS selector | 4c dynamic
+ // |0000000000000000| ES selector | 48 dynamic
+ // | EDI | 44 dynamic
+ // | ESI | 40 dynamic
+ // | EBP | 3c dynamic
+ // | ESP | 38 dynamic
+ // | EBX | 34 dynamic
+ // | EDX | 30 dynamic
+ // | ECX | 2c dynamic
+ // | EAX | 28 dynamic
+ // | EFLAGS | 24 dynamic
+ // | EIP (entry point) | 20 dynamic
+ // | CR3 (PDPR) | 1c static
+ // |000000000000000 | SS for CPL 2 | 18 static
+ // | ESP for CPL 2 | 14 static
+ // |000000000000000 | SS for CPL 1 | 10 static
+ // | ESP for CPL 1 | 0c static
+ // |000000000000000 | SS for CPL 0 | 08 static
+ // | ESP for CPL 0 | 04 static
+ // |000000000000000 | back link to prev TSS | 00 dynamic (updated only when return expected)
+
+
+ // ==================================================
+ // Effect of task switch on Busy, NT, and Link Fields
+ // ==================================================
+
+ // Field jump call/interrupt iret
+ // ------------------------------------------------------
+ // new busy bit Set Set No change
+ // old busy bit Cleared No change Cleared
+ // new NT flag No change Set No change
+ // old NT flag No change No change Cleared
+ // new link No change old TSS selector No change
+ // old link No change No change No change
+ // CR0.TS Set Set Set
+
+ // Note: I checked 386, 486, and Pentium, and they all exhibited
+ // exactly the same behaviour as above. There seems to
+ // be some misprints in the Intel docs.
+
+
+ void
+BX_CPU_C::task_switch(bx_selector_t *tss_selector,
+ bx_descriptor_t *tss_descriptor, unsigned source,
+ Bit32u dword1, Bit32u dword2)
+{
+ Bit32u obase32; // base address of old TSS
+ Bit32u nbase32; // base address of new TSS
+ Bit32u temp32, newCR3;
+ Bit16u raw_cs_selector, raw_ss_selector, raw_ds_selector, raw_es_selector,
+ raw_fs_selector, raw_gs_selector, raw_ldt_selector;
+ Bit16u temp16, trap_word;
+ bx_selector_t cs_selector, ss_selector, ds_selector, es_selector,
+ fs_selector, gs_selector, ldt_selector;
+ bx_descriptor_t cs_descriptor, ss_descriptor, ds_descriptor, es_descriptor,
+ fs_descriptor, gs_descriptor, ldt_descriptor;
+ Bit32u old_TSS_max, new_TSS_max, old_TSS_limit, new_TSS_limit;
+ Bit32u newEAX, newECX, newEDX, newEBX;
+ Bit32u newESP, newEBP, newESI, newEDI;
+ Bit32u newEFLAGS, oldEFLAGS, newEIP;
+ unsigned exception_no;
+ Bit16u error_code;
+
+//BX_DEBUG(( "TASKING: ENTER\n" ));
+
+ invalidate_prefetch_q();
+
+ // Discard any traps and inhibits for new context; traps will
+ // resume upon return.
+ BX_CPU_THIS_PTR debug_trap = 0;
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+
+
+
+
+ // The following checks are made before calling task_switch(), for
+ // JMP & CALL only. These checks are NOT made for exceptions, interrupts, & IRET
+ //
+ // 1) TSS DPL must be >= CPL
+ // 2) TSS DPL must be >= TSS selector RPL
+ // 3) TSS descriptor is not busy. TS(for IRET); GP(for JMP, CALL, INT)
+
+ // Privilege and busy checks done in CALL, JUMP, INT, IRET
+
+ exception_no = 256; // no exception
+ error_code = 0;
+ oldEFLAGS = read_eflags();
+
+ // Gather info about old TSS
+ if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
+ obase32 = BX_CPU_THIS_PTR tr.cache.u.tss286.base;
+ old_TSS_max = 43;
+ old_TSS_limit = BX_CPU_THIS_PTR tr.cache.u.tss286.limit;
+ }
+ else {
+ obase32 = BX_CPU_THIS_PTR tr.cache.u.tss386.base;
+ old_TSS_max = 103;
+ old_TSS_limit = BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled;
+ }
+
+ // Gather info about new TSS
+ if (tss_descriptor->type <= 3) { // {1,3}
+ nbase32 = tss_descriptor->u.tss286.base; // new TSS.base
+ new_TSS_max = 43;
+ new_TSS_limit = tss_descriptor->u.tss286.limit;
+ }
+ else { // tss_descriptor->type = {9,11}
+ nbase32 = tss_descriptor->u.tss386.base; // new TSS.base
+ new_TSS_max = 103;
+ new_TSS_limit = tss_descriptor->u.tss386.limit_scaled;
+ }
+
+ // Task State Seg must be present, else #NP(TSS selector)
+ if (tss_descriptor->p==0) {
+ BX_INFO(("task_switch: TSS.p == 0\n"));
+ exception(BX_NP_EXCEPTION, tss_selector->value & 0xfffc, 0);
+ }
+
+ // TSS must have valid limit, else #TS(TSS selector)
+ if (tss_selector->ti ||
+ tss_descriptor->valid==0 ||
+ new_TSS_limit < new_TSS_max) {
+ BX_PANIC(("task_switch(): TR not valid\n"));
+ exception(BX_TS_EXCEPTION, tss_selector->value & 0xfffc, 0);
+ }
+
+ // Check that old TSS, new TSS, and all segment descriptors
+ // used in the task switch are paged in.
+ if (BX_CPU_THIS_PTR cr0.pg) {
+ //BX_RW, BX_READ, BX_WRITE
+ // Old TSS
+ (void) dtranslate_linear(nbase32, 0, /*rw*/ BX_WRITE);
+ (void) dtranslate_linear(nbase32+old_TSS_max, 0, /*rw*/ BX_WRITE);
+
+ // New TSS
+ (void) dtranslate_linear(nbase32, 0, /*rw*/ 0);
+ (void) dtranslate_linear(nbase32+new_TSS_max, 0, /*rw*/ 0);
+
+ // ??? fix RW above
+ // ??? touch old/new TSS descriptors here when necessary.
+ }
+
+ // Need to fetch all new registers and temporarily store them.
+
+ if (tss_descriptor->type <= 3) {
+ access_linear(nbase32 + 14, 2, 0, BX_READ, &temp16);
+ newEIP = temp16; // zero out upper word
+ access_linear(nbase32 + 16, 2, 0, BX_READ, &temp16);
+ newEFLAGS = temp16;
+
+ // incoming TSS is 16bit:
+ // - upper word of general registers is set to 0xFFFF
+ // - upper word of eflags is zero'd
+ // - FS, GS are zero'd
+ // - upper word of eIP is zero'd
+ access_linear(nbase32 + 18, 2, 0, BX_READ, &temp16);
+ newEAX = 0xffff0000 | temp16;
+ access_linear(nbase32 + 20, 2, 0, BX_READ, &temp16);
+ newECX = 0xffff0000 | temp16;
+ access_linear(nbase32 + 22, 2, 0, BX_READ, &temp16);
+ newEDX = 0xffff0000 | temp16;
+ access_linear(nbase32 + 24, 2, 0, BX_READ, &temp16);
+ newEBX = 0xffff0000 | temp16;
+ access_linear(nbase32 + 26, 2, 0, BX_READ, &temp16);
+ newESP = 0xffff0000 | temp16;
+ access_linear(nbase32 + 28, 2, 0, BX_READ, &temp16);
+ newEBP = 0xffff0000 | temp16;
+ access_linear(nbase32 + 30, 2, 0, BX_READ, &temp16);
+ newESI = 0xffff0000 | temp16;
+ access_linear(nbase32 + 32, 2, 0, BX_READ, &temp16);
+ newEDI = 0xffff0000 | temp16;
+
+ access_linear(nbase32 + 34, 2, 0, BX_READ, &raw_es_selector);
+ access_linear(nbase32 + 36, 2, 0, BX_READ, &raw_cs_selector);
+ access_linear(nbase32 + 38, 2, 0, BX_READ, &raw_ss_selector);
+ access_linear(nbase32 + 40, 2, 0, BX_READ, &raw_ds_selector);
+ access_linear(nbase32 + 42, 2, 0, BX_READ, &raw_ldt_selector);
+
+ raw_fs_selector = 0; // use a NULL selector
+ raw_gs_selector = 0; // use a NULL selector
+ // No CR3 change for 286 task switch
+ newCR3 = 0; // keep compiler happy (not used)
+ trap_word = 0; // keep compiler happy (not used)
+ }
+ else {
+ access_linear(nbase32 + 0x1c, 4, 0, BX_READ, &newCR3);
+ access_linear(nbase32 + 0x20, 4, 0, BX_READ, &newEIP);
+ access_linear(nbase32 + 0x24, 4, 0, BX_READ, &newEFLAGS);
+ access_linear(nbase32 + 0x28, 4, 0, BX_READ, &newEAX);
+ access_linear(nbase32 + 0x2c, 4, 0, BX_READ, &newECX);
+ access_linear(nbase32 + 0x30, 4, 0, BX_READ, &newEDX);
+ access_linear(nbase32 + 0x34, 4, 0, BX_READ, &newEBX);
+ access_linear(nbase32 + 0x38, 4, 0, BX_READ, &newESP);
+ access_linear(nbase32 + 0x3c, 4, 0, BX_READ, &newEBP);
+ access_linear(nbase32 + 0x40, 4, 0, BX_READ, &newESI);
+ access_linear(nbase32 + 0x44, 4, 0, BX_READ, &newEDI);
+ access_linear(nbase32 + 0x48, 2, 0, BX_READ, &raw_es_selector);
+ access_linear(nbase32 + 0x4c, 2, 0, BX_READ, &raw_cs_selector);
+ access_linear(nbase32 + 0x50, 2, 0, BX_READ, &raw_ss_selector);
+ access_linear(nbase32 + 0x54, 2, 0, BX_READ, &raw_ds_selector);
+ access_linear(nbase32 + 0x58, 2, 0, BX_READ, &raw_fs_selector);
+ access_linear(nbase32 + 0x5c, 2, 0, BX_READ, &raw_gs_selector);
+ access_linear(nbase32 + 0x60, 2, 0, BX_READ, &raw_ldt_selector);
+ access_linear(nbase32 + 0x64, 2, 0, BX_READ, &trap_word);
+ // I/O Map Base Address ???
+ }
+
+#if 0
+if (ss_descriptor.u.segment.d_b && (tss_descriptor->type<9)) {
+ BX_DEBUG(( "++++++++++++++++++++++++++\n" ));
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+ exception(BX_SS_EXCEPTION, raw_ss_selector & 0xfffc, 0);
+ //exception(BX_TS_EXCEPTION, tss_selector->value & 0xfffc, 0);
+ }
+#endif
+
+
+ //
+ // Step 6: If JMP or IRET, clear busy bit in old task TSS descriptor,
+ // otherwise leave set.
+ //
+
+ // effect on Busy bit of old task
+ if ( (source==BX_TASK_FROM_JUMP) || (source==BX_TASK_FROM_IRET) ) {
+ // Bit is cleared
+ access_linear(BX_CPU_THIS_PTR gdtr.base +
+ BX_CPU_THIS_PTR tr.selector.index*8 + 4,
+ 4, 0, BX_READ, &temp32);
+ temp32 &= ~0x00000200;
+ access_linear(BX_CPU_THIS_PTR gdtr.base +
+ BX_CPU_THIS_PTR tr.selector.index*8 + 4,
+ 4, 0, BX_WRITE, &temp32);
+ }
+
+
+ //
+ // Step 7: If IRET, clear NT flag in temp image of EFLAGS, otherwise
+ // leave alone.
+ //
+
+ if (source == BX_TASK_FROM_IRET) {
+ // NT flags in old task is cleared with an IRET
+ oldEFLAGS &= ~0x00004000;
+ }
+
+
+ //
+ // Step 8: Save dynamic state of old task.
+ //
+
+ if (BX_CPU_THIS_PTR tr.cache.type <= 3) {
+ temp16 = IP; access_linear(obase32 + 14, 2, 0, BX_WRITE, &temp16);
+ temp16 = oldEFLAGS; access_linear(obase32 + 16, 2, 0, BX_WRITE, &temp16);
+ temp16 = AX; access_linear(obase32 + 18, 2, 0, BX_WRITE, &temp16);
+ temp16 = CX; access_linear(obase32 + 20, 2, 0, BX_WRITE, &temp16);
+ temp16 = DX; access_linear(obase32 + 22, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX; access_linear(obase32 + 24, 2, 0, BX_WRITE, &temp16);
+ temp16 = SP; access_linear(obase32 + 26, 2, 0, BX_WRITE, &temp16);
+ temp16 = BP; access_linear(obase32 + 28, 2, 0, BX_WRITE, &temp16);
+ temp16 = SI; access_linear(obase32 + 30, 2, 0, BX_WRITE, &temp16);
+ temp16 = DI; access_linear(obase32 + 32, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+ access_linear(obase32 + 34, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ access_linear(obase32 + 36, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ access_linear(obase32 + 38, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+ access_linear(obase32 + 40, 2, 0, BX_WRITE, &temp16);
+ }
+ else {
+ temp32 = EIP; access_linear(obase32 + 0x20, 4, 0, BX_WRITE, &temp32);
+ temp32 = oldEFLAGS; access_linear(obase32 + 0x24, 4, 0, BX_WRITE, &temp32);
+ temp32 = EAX; access_linear(obase32 + 0x28, 4, 0, BX_WRITE, &temp32);
+ temp32 = ECX; access_linear(obase32 + 0x2c, 4, 0, BX_WRITE, &temp32);
+ temp32 = EDX; access_linear(obase32 + 0x30, 4, 0, BX_WRITE, &temp32);
+ temp32 = EBX; access_linear(obase32 + 0x34, 4, 0, BX_WRITE, &temp32);
+ temp32 = ESP; access_linear(obase32 + 0x38, 4, 0, BX_WRITE, &temp32);
+ temp32 = EBP; access_linear(obase32 + 0x3c, 4, 0, BX_WRITE, &temp32);
+ temp32 = ESI; access_linear(obase32 + 0x40, 4, 0, BX_WRITE, &temp32);
+ temp32 = EDI; access_linear(obase32 + 0x44, 4, 0, BX_WRITE, &temp32);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
+ access_linear(obase32 + 0x48, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+ access_linear(obase32 + 0x4c, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
+ access_linear(obase32 + 0x50, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
+ access_linear(obase32 + 0x54, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
+ access_linear(obase32 + 0x58, 2, 0, BX_WRITE, &temp16);
+ temp16 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
+ access_linear(obase32 + 0x5c, 2, 0, BX_WRITE, &temp16);
+ }
+
+
+
+ //
+ // Commit point. At this point, we commit to the new
+ // context. If an unrecoverable error occurs in further
+ // processing, we complete the task switch without performing
+ // additional access and segment availablility checks and
+ // generate the appropriate exception prior to beginning
+ // execution of the new task.
+ //
+
+
+ // Task switch clears LE/L3/L2/L1/L0 in DR7
+ BX_CPU_THIS_PTR dr7 &= ~0x00000155;
+
+
+// effect on link field of new task
+if ( source==BX_TASK_FROM_CALL_OR_INT ) {
+ // set to selector of old task's TSS
+ temp16 = BX_CPU_THIS_PTR tr.selector.value;
+ access_linear(nbase32 + 0, 2, 0, BX_WRITE, &temp16);
+ }
+
+
+
+ //
+ // Step 9: If call or interrupt, set the NT flag in the eflags
+ // image stored in new task's TSS. If IRET or JMP,
+ // NT is restored from new TSS eflags image. (no change)
+ //
+
+ // effect on NT flag of new task
+ if ( source==BX_TASK_FROM_CALL_OR_INT ) {
+ newEFLAGS |= 0x4000; // flag is set
+ }
+
+
+ //
+ // Step 10: If CALL, interrupt, or JMP, set busy flag in new task's
+ // TSS descriptor. If IRET, leave set.
+ //
+
+ if ( (source==BX_TASK_FROM_JUMP) || (source==BX_TASK_FROM_CALL_OR_INT) ) {
+ // set the new task's busy bit
+ access_linear(BX_CPU_THIS_PTR gdtr.base + tss_selector->index*8 + 4,
+ 4, 0, BX_READ, &dword2);
+ dword2 |= 0x00000200;
+ access_linear(BX_CPU_THIS_PTR gdtr.base + tss_selector->index*8 + 4,
+ 4, 0, BX_WRITE, &dword2);
+ }
+
+
+ //
+ // Step 11: Set TS flag in the CR0 image stored in the new task TSS.
+ //
+
+ // set TS bit in CR0 register
+ BX_CPU_THIS_PTR cr0.ts = 1;
+ BX_CPU_THIS_PTR cr0.val32 |= 0x00000008;
+
+
+ //
+ // Step 12: Load the task register with the segment selector and
+ // descriptor for the new task TSS.
+ //
+
+ BX_CPU_THIS_PTR tr.selector = *tss_selector;
+ BX_CPU_THIS_PTR tr.cache = *tss_descriptor;
+
+
+ //
+ // Step 13: Load the new task (dynamic) state from new TSS.
+ // Any errors associated with loading and qualification of
+ // segment descriptors in this step occur in the new task's
+ // context. State loaded here includes LDTR, CR3,
+ // EFLAGS, EIP, general purpose registers, and segment
+ // descriptor parts of the segment registers.
+ //
+
+ if (tss_descriptor->type >= 9) {
+ CR3_change(newCR3); // Tell paging unit about new cr3 value
+ BX_INSTR_TLB_CNTRL(BX_INSTR_TASKSWITCH, newCR3);
+ }
+
+ BX_CPU_THIS_PTR prev_eip = EIP = newEIP;
+ write_eflags(newEFLAGS, 1,1,1,1);
+ EAX = newEAX;
+ ECX = newECX;
+ EDX = newEDX;
+ EBX = newEBX;
+ ESP = newESP;
+ EBP = newEBP;
+ ESI = newESI;
+ EDI = newEDI;
+
+ // Fill in selectors for all segment registers. If errors
+ // occur later, the selectors will at least be loaded.
+ parse_selector(raw_es_selector, &es_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector = es_selector;
+ parse_selector(raw_cs_selector, &cs_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector = cs_selector;
+ parse_selector(raw_ss_selector, &ss_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector = ss_selector;
+ parse_selector(raw_ds_selector, &ds_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector = ds_selector;
+ parse_selector(raw_fs_selector, &fs_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector = fs_selector;
+ parse_selector(raw_gs_selector, &gs_selector);
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector = gs_selector;
+ parse_selector(raw_ldt_selector, &ldt_selector);
+ BX_CPU_THIS_PTR ldtr.selector = ldt_selector;
+
+ // Start out with invalid descriptor caches, fill in
+ // with values only as they are validated.
+ BX_CPU_THIS_PTR ldtr.cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0;
+
+
+// need to test valid bit in fetch_raw_descriptor?()
+// or set limit to 0 instead when LDT is loaded with
+// null. ??? +++
+BX_CPU_THIS_PTR ldtr.cache.u.ldt.limit = 0;
+
+ // LDTR
+ if (ldt_selector.ti) {
+ // LDT selector must be in GDT
+ BX_INFO(("task_switch: bad LDT selector TI=1\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ldt_selector & 0xfffc;
+ goto post_exception;
+ }
+
+// ??? is LDT loaded in v8086 mode
+ if ( (raw_ldt_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&ldt_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad LDT fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ldt_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &ldt_descriptor);
+
+ // LDT selector of new task is valid, else #TS(new task's LDT)
+ if (ldt_descriptor.valid==0 ||
+ ldt_descriptor.type!=2 ||
+ ldt_descriptor.segment ||
+ ldt_descriptor.u.ldt.limit<7) {
+ BX_INFO(("task_switch: bad LDT segment\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ldt_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ // LDT of new task is present in memory, else #TS(new tasks's LDT)
+ else if (ldt_descriptor.p==0) {
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ldt_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in LDTR shadow cache
+ BX_CPU_THIS_PTR ldtr.cache = ldt_descriptor;
+ }
+ else {
+ // NULL LDT selector is OK, leave cache invalid
+ }
+
+ if (v8086_mode()) {
+ // load seg regs as 8086 registers
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], raw_cs_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], raw_ss_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], raw_ds_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], raw_es_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], raw_fs_selector);
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], raw_gs_selector);
+ }
+ else {
+
+ // CS
+ if ( (raw_cs_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&cs_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad CS fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &cs_descriptor);
+
+ // CS descriptor AR byte must indicate code segment else #TS(CS)
+ if (cs_descriptor.valid==0 || cs_descriptor.segment==0 ||
+ cs_descriptor.u.segment.executable==0) {
+ BX_PANIC(("task_switch: CS not valid executable seg\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if non-conforming then DPL must equal selector RPL else #TS(CS)
+ else if (cs_descriptor.u.segment.c_ed==0 &&
+ cs_descriptor.dpl!=cs_selector.rpl) {
+ BX_INFO(("task_switch: non-conforming: CS.dpl!=CS.RPL\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if conforming then DPL must be <= selector RPL else #TS(CS)
+ else if (cs_descriptor.u.segment.c_ed &&
+ cs_descriptor.dpl>cs_selector.rpl) {
+ BX_INFO(("task_switch: conforming: CS.dpl>RPL\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // Code segment is present in memory, else #NP(new code segment)
+ else if (cs_descriptor.p==0) {
+ BX_PANIC(("task_switch: CS.p==0\n"));
+ exception_no = BX_NP_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache = cs_descriptor;
+ }
+ else {
+ // If new cs selector is null #TS(CS)
+ BX_PANIC(("task_switch: CS NULL\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_cs_selector & 0xfffc;
+ goto post_exception;
+ }
+
+
+ // SS
+ if ( (raw_ss_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&ss_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad SS fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &ss_descriptor);
+ // SS selector must be within its descriptor table limits else #TS(SS)
+ // SS descriptor AR byte must must indicate writable data segment,
+ // else #TS(SS)
+ if (ss_descriptor.valid==0 ||
+ ss_descriptor.segment==0 ||
+ ss_descriptor.u.segment.executable ||
+ ss_descriptor.u.segment.r_w==0) {
+ BX_INFO(("task_switch: SS not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ //
+ // Stack segment is present in memory, else #SF(new stack segment)
+ //
+ else if (ss_descriptor.p==0) {
+ BX_PANIC(("task_switch: SS not present\n"));
+ exception_no = BX_SS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ // Stack segment DPL matches CS.RPL, else #TS(new stack segment)
+ else if (ss_descriptor.dpl != cs_selector.rpl) {
+ BX_PANIC(("task_switch: SS.rpl != CS.RPL\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ // Stack segment DPL matches selector RPL, else #TS(new stack segment)
+ else if (ss_descriptor.dpl != ss_selector.rpl) {
+ BX_PANIC(("task_switch: SS.dpl != SS.rpl\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+#if 0
+ // +++
+ else if (ss_descriptor.u.segment.d_b && (tss_descriptor->type<9)) {
+ BX_DEBUG(( "++++++++++++++++++++++++++\n" ));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+#endif
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = ss_descriptor;
+ }
+ else {
+ // SS selector is valid, else #TS(new stack segment)
+ BX_PANIC(("task_switch: SS NULL\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ss_selector & 0xfffc;
+ goto post_exception;
+ }
+
+
+ // if new selector is not null then perform following checks:
+ // index must be within its descriptor table limits else #TS(selector)
+ // AR byte must indicate data or readable code else #TS(selector)
+ // if data or non-conforming code then:
+ // DPL must be >= CPL else #TS(selector)
+ // DPL must be >= RPL else #TS(selector)
+ // AR byte must indicate PRESENT else #NP(selector)
+ // load cache with new segment descriptor and set valid bit
+
+
+
+ // DS
+ if ( (raw_ds_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&ds_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad DS fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ds_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &ds_descriptor);
+ if (ds_descriptor.valid==0 || ds_descriptor.segment==0 ||
+ (ds_descriptor.u.segment.executable &&
+ ds_descriptor.u.segment.r_w==0)) {
+ BX_PANIC(("task_switch: DS not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ds_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if data or non-conforming code
+ else if (ds_descriptor.type<12 &&
+ (ds_descriptor.dpl<cs_selector.rpl ||
+ ds_descriptor.dpl<ds_selector.rpl)) {
+ BX_PANIC(("task_switch: DS.dpl not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_ds_selector & 0xfffc;
+ goto post_exception;
+ }
+ else if (ds_descriptor.p==0) {
+ BX_PANIC(("task_switch: DS.p==0\n"));
+ exception_no = BX_NP_EXCEPTION;
+ error_code = raw_ds_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache = ds_descriptor;
+ }
+ else {
+ // NULL DS selector is OK, leave cache invalid
+ }
+
+ // ES
+ if ( (raw_es_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&es_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad ES fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_es_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &es_descriptor);
+ if (es_descriptor.valid==0 || es_descriptor.segment==0 ||
+ (es_descriptor.u.segment.executable &&
+ es_descriptor.u.segment.r_w==0)) {
+ BX_PANIC(("task_switch: ES not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_es_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if data or non-conforming code
+ else if (es_descriptor.type<12 &&
+ (es_descriptor.dpl<cs_selector.rpl ||
+ es_descriptor.dpl<es_selector.rpl)) {
+ BX_PANIC(("task_switch: ES.dpl not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_es_selector & 0xfffc;
+ goto post_exception;
+ }
+ else if (es_descriptor.p==0) {
+ BX_PANIC(("task_switch: ES.p==0\n"));
+ exception_no = BX_NP_EXCEPTION;
+ error_code = raw_es_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache = es_descriptor;
+ }
+ else {
+ // NULL ES selector is OK, leave cache invalid
+ }
+
+
+ // FS
+ if ( (raw_fs_selector & 0xfffc) != 0 ) { // not NULL
+ Boolean good;
+ good = fetch_raw_descriptor2(&fs_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad FS fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_fs_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &fs_descriptor);
+ if (fs_descriptor.valid==0 || fs_descriptor.segment==0 ||
+ (fs_descriptor.u.segment.executable &&
+ fs_descriptor.u.segment.r_w==0)) {
+ BX_PANIC(("task_switch: FS not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_fs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if data or non-conforming code
+ else if (fs_descriptor.type<12 &&
+ (fs_descriptor.dpl<cs_selector.rpl ||
+ fs_descriptor.dpl<fs_selector.rpl)) {
+ BX_PANIC(("task_switch: FS.dpl not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_fs_selector & 0xfffc;
+ goto post_exception;
+ }
+ else if (fs_descriptor.p==0) {
+ BX_PANIC(("task_switch: FS.p==0\n"));
+ exception_no = BX_NP_EXCEPTION;
+ error_code = raw_fs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache = fs_descriptor;
+ }
+ else {
+ // NULL FS selector is OK, leave cache invalid
+ }
+
+ // GS
+ if ( (raw_gs_selector & 0xfffc) != 0 ) {
+ Boolean good;
+ good = fetch_raw_descriptor2(&gs_selector, &dword1, &dword2);
+ if (!good) {
+ BX_INFO(("task_switch: bad GS fetch\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_gs_selector & 0xfffc;
+ goto post_exception;
+ }
+
+ parse_descriptor(dword1, dword2, &gs_descriptor);
+ if (gs_descriptor.valid==0 || gs_descriptor.segment==0 ||
+ (gs_descriptor.u.segment.executable &&
+ gs_descriptor.u.segment.r_w==0)) {
+ BX_PANIC(("task_switch: GS not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_gs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // if data or non-conforming code
+ else if (gs_descriptor.type<12 &&
+ (gs_descriptor.dpl<cs_selector.rpl ||
+ gs_descriptor.dpl<gs_selector.rpl)) {
+ BX_PANIC(("task_switch: GS.dpl not valid\n"));
+ exception_no = BX_TS_EXCEPTION;
+ error_code = raw_gs_selector & 0xfffc;
+ goto post_exception;
+ }
+ else if (gs_descriptor.p==0) {
+ BX_PANIC(("task_switch: GS.p==0\n"));
+ //exception(BX_NP_EXCEPTION, raw_gs_selector & 0xfffc, 0);
+ exception_no = BX_NP_EXCEPTION;
+ error_code = raw_gs_selector & 0xfffc;
+ goto post_exception;
+ }
+ // All checks pass, fill in shadow cache
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache = gs_descriptor;
+ }
+ else {
+ // NULL GS selector is OK, leave cache invalid
+ }
+
+ }
+
+
+ if ((tss_descriptor->type>=9) && (trap_word & 0x0001)) {
+ BX_CPU_THIS_PTR debug_trap |= 0x00008000; // BT flag in DR6
+ BX_CPU_THIS_PTR async_event = 1; // so processor knows to check
+ BX_INFO(("task_switch: T bit set in new TSS.\n"));
+ }
+
+
+
+ //
+ // Step 14: Begin execution of new task.
+ //
+//BX_DEBUG(( "TASKING: LEAVE\n" ));
+ return;
+
+post_exception:
+ BX_CPU_THIS_PTR debug_trap = 0;
+ BX_CPU_THIS_PTR inhibit_mask = 0;
+ BX_INFO(("task switch: posting exception %u after commit point\n",
+ exception_no));
+ exception(exception_no, error_code, 0);
+ return;
+}
+
+
+ void
+BX_CPU_C::get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp)
+{
+ if (BX_CPU_THIS_PTR tr.cache.valid==0)
+ BX_PANIC(("get_SS_ESP_from_TSS: TR.cache invalid\n"));
+
+ if (BX_CPU_THIS_PTR tr.cache.type==9) {
+ // 32-bit TSS
+ Bit32u TSSstackaddr;
+
+ TSSstackaddr = 8*pl + 4;
+ if ( (TSSstackaddr+7) >
+ BX_CPU_THIS_PTR tr.cache.u.tss386.limit_scaled )
+ exception(BX_TS_EXCEPTION,
+ BX_CPU_THIS_PTR tr.selector.value & 0xfffc, 0);
+
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base +
+ TSSstackaddr+4, 2, 0, BX_READ, ss);
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss386.base +
+ TSSstackaddr, 4, 0, BX_READ, esp);
+ }
+ else if (BX_CPU_THIS_PTR tr.cache.type==1) {
+ // 16-bit TSS
+ Bit16u temp16;
+ Bit32u TSSstackaddr;
+
+ TSSstackaddr = 4*pl + 2;
+ if ( (TSSstackaddr+4) > BX_CPU_THIS_PTR tr.cache.u.tss286.limit )
+ exception(BX_TS_EXCEPTION,
+ BX_CPU_THIS_PTR tr.selector.value & 0xfffc, 0);
+
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss286.base +
+ TSSstackaddr+2, 2, 0, BX_READ, ss);
+ access_linear(BX_CPU_THIS_PTR tr.cache.u.tss286.base +
+ TSSstackaddr, 2, 0, BX_READ, &temp16);
+ *esp = temp16; // truncate
+ }
+ else {
+ BX_PANIC(("get_SS_ESP_from_TSS: TR is bogus type (%u)\n",
+ (unsigned) BX_CPU_THIS_PTR tr.cache.type));
+ }
+}
+#endif
+
+
+
+#else // BX_SUPPORT_TASKING
+
+
+// for non-support of hardware tasking
+
+#if BX_CPU_LEVEL >= 2
+ /* corresponds to SWITCH_TASKS algorithm in Intel documentation */
+ void
+BX_CPU_C::task_switch(bx_selector_t *selector,
+ bx_descriptor_t *descriptor, unsigned source,
+ Bit32u dword1, Bit32u dword2)
+{
+ UNUSED(selector);
+ UNUSED(descriptor);
+ UNUSED(source);
+ UNUSED(dword1);
+ UNUSED(dword2);
+
+ BX_INFO(("task_switch(): not complete\n"));
+}
+
+ void
+BX_CPU_C::get_SS_ESP_from_TSS(unsigned pl, Bit16u *ss, Bit32u *esp)
+{
+}
+#endif
+
+
+#endif // BX_SUPPORT_TASKING
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+#define NEED_CPU_REG_SHORTCUTS 1
+#include "bochs.h"
+#define LOG_THIS BX_CPU_THIS_PTR
+
+
+// Notes:
+//
+// The high bits of the 32bit eip image are ignored by
+// the IRET to VM. The high bits of the 32bit esp image
+// are loaded into ESP. A subsequent push uses
+// only the low 16bits since it's in VM. In neither case
+// did a protection fault occur during actual tests. This
+// is contrary to the Intel docs which claim a #GP for
+// eIP out of code limits.
+//
+// IRET to VM does affect IOPL, IF, VM, and RF
+
+
+#if BX_SUPPORT_V8086_MODE
+
+
+#if BX_CPU_LEVEL >= 3
+
+
+ void
+BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector,
+ Bit32u flags32)
+{
+ Bit32u temp_ESP, new_esp, esp_laddr;
+ Bit16u raw_es_selector, raw_ds_selector, raw_fs_selector,
+ raw_gs_selector, raw_ss_selector;
+
+
+ // Must be 32bit effective opsize, VM is in upper 16bits of eFLAGS
+ // CPL = 0 to get here
+
+ // ----------------
+ // | | OLD GS | eSP+32
+ // | | OLD FS | eSP+28
+ // | | OLD DS | eSP+24
+ // | | OLD ES | eSP+20
+ // | | OLD SS | eSP+16
+ // | OLD ESP | eSP+12
+ // | OLD EFLAGS | eSP+8
+ // | | OLD CS | eSP+4
+ // | OLD EIP | eSP+0
+ // ----------------
+
+ if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b)
+ temp_ESP = ESP;
+ else
+ temp_ESP = SP;
+
+ // top 36 bytes of stack must be within stack limits, else #GP(0)
+ if ( !can_pop(36) ) {
+ BX_PANIC(("iret: VM: top 36 bytes not within limits\n"));
+ exception(BX_SS_EXCEPTION, 0, 0);
+ return;
+ }
+
+ if ( new_eip & 0xffff0000 ) {
+ BX_INFO(("IRET to V86-mode: ignoring upper 16-bits\n"));
+ new_eip = new_eip & 0xffff;
+ }
+
+ esp_laddr = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base +
+ temp_ESP;
+
+ // load SS:ESP from stack
+ access_linear(esp_laddr + 12, 4, 0, BX_READ, &new_esp);
+ access_linear(esp_laddr + 16, 2, 0, BX_READ, &raw_ss_selector);
+
+ // load ES,DS,FS,GS from stack
+ access_linear(esp_laddr + 20, 2, 0, BX_READ, &raw_es_selector);
+ access_linear(esp_laddr + 24, 2, 0, BX_READ, &raw_ds_selector);
+ access_linear(esp_laddr + 28, 2, 0, BX_READ, &raw_fs_selector);
+ access_linear(esp_laddr + 32, 2, 0, BX_READ, &raw_gs_selector);
+
+ write_eflags(flags32, /*change IOPL*/ 1, /*change IF*/ 1,
+ /*change VM*/ 1, /*change RF*/ 1);
+
+ // load CS:EIP from stack; already read and passed as args
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = raw_cs_selector;
+ EIP = new_eip;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = raw_es_selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value = raw_ds_selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value = raw_fs_selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = raw_gs_selector;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = raw_ss_selector;
+ ESP = new_esp; // Full 32bits are loaded.
+
+ init_v8086_mode();
+}
+
+
+ void
+BX_CPU_C::stack_return_from_v86(BxInstruction_t *i)
+{
+ //BX_INFO(("stack_return_from_v86:\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+
+#if 0
+ if (IOPL != 3) {
+ // trap to virtual 8086 monitor
+ BX_INFO(("stack_return_from_v86: IOPL != 3\n"));
+ exception(BX_GP_EXCEPTION, 0, 0);
+ }
+
+ if (i->os_32) {
+ Bit32u eip, ecs_raw, eflags;
+
+// ??? should be some stack checks here
+ pop_32(&eip);
+ pop_32(&ecs_raw);
+ pop_32(&eflags);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw);
+ BX_CPU_THIS_PTR eip = eip;
+ write_eflags(eflags, /*IOPL*/ CPL==0, /*IF*/ 1, /*VM*/ 0, /*RF*/ 1);
+ }
+ else {
+ Bit16u ip, cs_raw, flags;
+
+// ??? should be some stack checks here
+ pop_16(&ip);
+ pop_16(&cs_raw);
+ pop_16(&flags);
+
+ load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
+ BX_CPU_THIS_PTR eip = (Bit32u) ip;
+ write_flags(flags, /*IOPL*/ CPL==0, /*IF*/ 1);
+ }
+#endif
+}
+
+
+ void
+BX_CPU_C::init_v8086_mode(void)
+{
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = 3;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.executable = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.rpl = 3;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.executable = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.rpl = 3;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.executable = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.rpl = 3;
+
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.p = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.dpl = 3;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.executable = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.r_w = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.a = 1;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.base =
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value << 4;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled = 0xffff;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.g = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+ BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.rpl = 3;
+}
+
+
+#endif /* BX_CPU_LEVEL >= 3 */
+
+
+
+
+
+#else // BX_SUPPORT_V8086_MODE
+
+// non-support of v8086 mode
+
+ void
+BX_CPU_C::stack_return_to_v86(Bit32u new_eip, Bit32u raw_cs_selector, Bit32u flags32)
+{
+ BX_INFO(("stack_return_to_v86: VM bit set in EFLAGS stack image\n"));
+ v8086_message();
+}
+
+ void
+BX_CPU_C::stack_return_from_v86(BxInstruction_t *i)
+{
+ BX_INFO(("stack_return_from_v86:\n"));
+ v8086_message();
+}
+
+ void
+BX_CPU_C::v8086_message(void)
+{
+ BX_INFO(("Program compiled with BX_SUPPORT_V8086_MODE = 0\n"));
+ BX_INFO(("You need to rerun the configure script and recompile\n"));
+ BX_INFO((" to use virtual-8086 mode features.\n"));
+ BX_PANIC(("Bummer!\n"));
+}
+#endif // BX_SUPPORT_V8086_MODE
--- /dev/null
+// x86-memory-modes.cc - set up protected mode. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include "x86.h"
+
+void x86_cpu::enter_protected_mode()
+{
+ if (memory_mode == "default")
+ {
+ // This mode sets all segment bases to 0x0, and sets all
+ // limits to 0xfffff
+ // create a global descriptor table in memory:
+ // null descriptor:
+ for(int i = 0; i < 16; i += 4)
+ write_data_memory_4(0x0, i, 0x0);
+
+ // CS descriptor:
+ write_data_memory_4(0x0, 0x0010, 0xffff0000);
+ write_data_memory_4(0x0, 0x0014, 0x009b4f00);
+
+ // DS descriptor:
+ write_data_memory_4(0x0, 0x0018, 0xffff0000);
+ write_data_memory_4(0x0, 0x001c, 0x00934f00);
+
+ // CS (Code Segment) selector and descriptor in bochs representation:
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.value = 0x0010;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.index = 0x0002;
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+ // DS (Data Segment) selector and descriptor in bochs representation:
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xfffff; // 2000
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+ /* ES (Extra Segment) and descriptor cache */
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled = 0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+ /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.value = 0x0018;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.value = 0x0018;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+ /* SS (Stack Segment) and descriptor cache */
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xfffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.g = 0; /* byte granular */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+ /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.gdtr.base = 0x00000000;
+ bx_cpu.gdtr.limit = 0x001f;
+#endif
+ // set PE bit in CR0 so that protected mode is enabled
+ bx_cpu.SetCR0(0x01);
+
+ }
+ else if (memory_mode == "cygmon")
+ {
+ // support for initial cygmon memory layout
+
+ // this section simulates the Cygmon rom monitor startup code
+
+ // create a global descriptor table in memory:
+ // null descriptor:
+ for(int i = 0; i < 16; i += 4)
+ write_data_memory_4(0x0, i, 0x0);
+
+ // CS descriptor:
+ write_data_memory_4(0x0, 0x10, 0xffff0000);
+ write_data_memory_4(0x0, 0x14, 0x009bcf00);
+
+ // DS descriptor:
+ write_data_memory_4(0x0, 0x18, 0xffff0000);
+ write_data_memory_4(0x0, 0x1c, 0x0093cf00);
+
+ // CS (Code Segment) selector and descriptor in bochs representation:
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.value = 0x0010;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.index = 0x0002;
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_CS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.executable = 1; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0;
+#endif
+
+ // DS (Data Segment) selector and descriptor in bochs representation:
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_DS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xfffff; // 2000
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0;
+#endif
+
+ /* ES (Extra Segment) and descriptor cache */
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_ES].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.limit_scaled = 0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_ES].cache.u.segment.avl = 0;
+#endif
+
+ /* FS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.value = 0x0018;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_FS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.limit_scaled = 0xffffffff;
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_FS].cache.u.segment.avl = 0;
+#endif
+
+
+ /* GS and descriptor cache */
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.value = 0x0018;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_GS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.limit_scaled = 0xffffffff;
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_GS].cache.u.segment.avl = 0;
+#endif
+
+ /* SS (Stack Segment) and descriptor cache */
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.value = 0x0018;
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.index = 0x0003;
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.ti = 0;
+ bx_cpu.sregs[BX_SEG_REG_SS].selector.rpl = 0;
+
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.valid = 1;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.p = 1;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.dpl = 0;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.segment = 1; /* data/code segment */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.type = 3; /* read/write access */
+
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.executable = 0; /* data/stack segment */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.c_ed = 0; /* normal expand up */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.r_w = 1; /* writeable */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.a = 1; /* accessed */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.base = 0x00000000;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit = 0xfffff;
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.limit_scaled = 0xffffffff;
+#endif
+#if BX_CPU_LEVEL >= 3
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.g = 1; /* 4Kb granular */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.d_b = 1; /* 32bit default size */
+ bx_cpu.sregs[BX_SEG_REG_SS].cache.u.segment.avl = 0;
+#endif
+
+ //
+ /* GDTR (Global Descriptor Table Register) */
+#if BX_CPU_LEVEL >= 2
+ bx_cpu.gdtr.base = 0x00000000;
+ bx_cpu.gdtr.limit = 0x001f;
+#endif
+ // set PE bit in CR0 so that protected mode is enabled
+ bx_cpu.SetCR0(0x01);
+ }
+ else
+ {
+ cerr << "hw-cpu-x86: unsupported memory mode" << endl;
+ }
+}
--- /dev/null
+// x86.cc - member function implementations for the x86 sid component. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include "x86.h"
+
+x86_cpu::x86_cpu () :
+ memory_mode("default"),
+ blocking_on_syscall(false),
+ verbose_p(false)
+{
+ bx_mem.sid_cpu = this;
+ bx_cpu.sid_cpu = this;
+
+ bx_cpu.init(&bx_mem);
+
+ // set up registers for use by gloss component.
+ // see libgloss/i386/* for calling conventions
+ // and exception-sid.cc for handling of int 0x80
+ this->add_watchable_register (string("syscall-arg0"), &bx_cpu.gen_reg[0].erx);
+ this->add_watchable_register (string("syscall-arg1"), &bx_cpu.gen_reg[3].erx);
+ this->add_watchable_register (string("syscall-arg2"), &bx_cpu.gen_reg[1].erx);
+ this->add_watchable_register (string("syscall-arg3"), &bx_cpu.gen_reg[2].erx);
+ this->add_watchable_register (string("syscall-result"), &bx_cpu.gen_reg[0].erx);
+
+ this->add_watchable_register (string("syscall-trap"), &bx_cpu.gen_reg[0].erx);
+ this->add_watchable_register (string("syscall-error"), &syscall_error);
+
+ // set up debugging interface
+ // there are 16 integer registers
+ create_gdb_register_attrs (16, "4;5;8;9", & this->bx_cpu.eip);
+
+ this->add_attribute ("enable-warnings?", & warnings_enabled, "setting");
+ this->add_attribute ("memory-mode", & memory_mode, "setting");
+ this->add_attribute("verbose?", &this->verbose_p, "setting");
+}
+
+void x86_cpu::do_syscall()
+{
+ sid::host_int_4 tempAX = bx_cpu.gen_reg[0].erx;
+ sid::host_int_4 tempBX = bx_cpu.gen_reg[3].erx;
+ sid::host_int_4 tempCX = bx_cpu.gen_reg[1].erx;
+ sid::host_int_4 tempDX = bx_cpu.gen_reg[2].erx;
+
+ sidutil::cpu_trap_disposition whatnext = signal_trap(sidutil::cpu_trap_software, bx_cpu.gen_reg[0].erx);
+
+ switch (whatnext)
+ {
+ case sidutil::cpu_trap_unhandled:
+ cerr << "hw-cpu-x86: cpu syscall trap unhandled" << endl;
+ this->blocking_on_syscall = false;
+ return;
+ case sidutil::cpu_trap_reissue:
+ bx_cpu.gen_reg[0].erx = tempAX;
+ bx_cpu.gen_reg[3].erx = tempBX;
+ bx_cpu.gen_reg[1].erx = tempCX;
+ bx_cpu.gen_reg[2].erx = tempDX;
+ this->blocking_on_syscall = true;
+ return;
+ case sidutil::cpu_trap_skip:
+ /* fall-through */
+ case sidutil::cpu_trap_handled:
+ this->blocking_on_syscall = false;
+ return;
+ default:
+ abort ();
+ }
+ this->yield();
+ throw sidutil::cpu_exception();
+}
+
+void x86_cpu::do_breakpoint()
+{
+ sidutil::cpu_trap_disposition whatnext = signal_trap(sidutil::cpu_trap_breakpoint, 0);
+
+ switch (whatnext)
+ {
+ case sidutil::cpu_trap_unhandled:
+ cerr << "hw-cpu-x86: cpu breakpoint trap unhandled" << endl;
+ break;
+
+ case sidutil::cpu_trap_skip:
+ case sidutil::cpu_trap_handled:
+ case sidutil::cpu_trap_reissue:
+ break;
+
+ default:
+ abort();
+ }
+ this->yield();
+ throw sidutil::cpu_exception();
+}
+
+void x86_cpu::step_insns () {
+ try {
+ if (!this->blocking_on_syscall)
+ bx_cpu.cpu_loop(1);
+ else
+ do_syscall();
+ }
+ catch (sidutil::cpu_exception& t)
+ {
+ this->yield();
+ }
+
+ if (this->enable_step_trap_p)
+ this->signal_trap (sidutil::cpu_trap_stepped);
+}
+
+void x86_cpu::reset () {
+ bx_cpu.reset(BX_RESET_HARDWARE);
+
+ enter_protected_mode();
+}
+
+void x86_cpu::flush_icache () {
+ bx_cpu.invalidate_prefetch_q();
+}
+
+void x86_cpu::set_pc (sid::host_int_4 value) {
+ // FIXME: this should check if we're using the extended (32-bit)
+ // instruction pointer or the 16-bit one
+ bx_cpu.eip = value - bx_cpu.sregs[BX_SEG_REG_CS].cache.u.segment.base;
+}
+
+string x86_cpu::dbg_get_reg(unsigned int reg)
+{
+ string attr;
+ sid::host_int_4 val;
+ val = bx_cpu.dbg_get_reg(reg + 10);
+
+ // Change to "target endian".
+ sid::little_int_4 v = val;
+ for (unsigned i = 0; i < 4; i++)
+ attr += v.read_byte (i);
+
+ if (verbose_p)
+ cerr << "dbg_get_reg: reg = " << reg << endl;
+
+ return attr;
+}
+
+sid::component::status x86_cpu::dbg_set_reg(unsigned int reg, const string &attr)
+{
+ // change from "target endian"
+ sid::little_int_4 v;
+ for (unsigned i = 0; i < 4; i++)
+ v.write_byte (i, attr[i]);
+ sid::host_int_4 val = v;
+
+ if (verbose_p)
+ {
+ cerr << "dbg_set_reg: reg = " << reg;
+ fprintf(stderr, " val = %p\n", val);
+ }
+
+ if(bx_cpu.dbg_set_reg(reg + 10, val))
+ return sid::component::ok;
+ else
+ return sid::component::bad_value;
+}
+
--- /dev/null
+// x86.h - x86_cpu class declaration for the x86 sid component. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#ifndef __X86_H__
+#define __X86_H__ 1
+#include "sidcomp.h"
+#include "sidcpuutil.h"
+#include "bochs.h"
+#include "memory-sid.h"
+#include "cpu-sid.h"
+
+#define X86_CPU_DEBUG 0
+
+class x86_cpu : public sidutil::basic_bi_endian_cpu {
+ friend void sid_mem_c::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+ friend void sid_mem_c::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+ public:
+ sid_cpu_c bx_cpu;
+ sid_mem_c bx_mem;
+
+ sid::host_int_4 syscall_error;
+
+ bool warnings_enabled;
+ bool blocking_on_syscall;
+ bool verbose_p;
+
+ x86_cpu ();
+
+ void do_syscall();
+ void do_breakpoint();
+
+ void step_insns ();
+ void reset ();
+ void flush_icache ();
+ void set_pc (sid::host_int_4 value);
+ string dbg_get_reg(unsigned int);
+ sid::component::status dbg_set_reg(unsigned int, const string &);
+ private:
+ string memory_mode;
+
+ void enter_protected_mode();
+
+};
+
+#endif // __X86_H__
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+// if including from C parser, need basic types etc
+#include "config.h"
+#if BX_DEBUGGER
+#include "osdep.h"
+#endif
+#if BX_USE_LOADER
+#include "loader_misc.h"
+void bx_dbg_loader(char *path, bx_loader_misc_t *misc_ptr);
+#endif
+
+#if BX_DBG_ICOUNT_SIZE == 32
+ typedef Bit32u bx_dbg_icount_t;
+#elif BX_DBG_ICOUNT_SIZE == 64
+ typedef Bit64u bx_dbg_icount_t;
+#else
+# error "BX_DBG_ICOUNT_SIZE incorrect."
+#endif
+
+
+#define BX_DBG_NO_HANDLE 1000
+
+extern Bit32u dbg_cpu;
+
+unsigned long crc32(unsigned char *buf, int len);
+
+#if BX_DEBUGGER
+
+// some strict C declarations needed by the parser/lexer
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Flex defs
+extern int bxlex(void);
+extern char *bxtext; // Using the pointer option rather than array
+extern int bxwrap(void);
+void bx_add_lex_input(char *buf);
+
+// Yacc defs
+extern int bxparse(void);
+extern void bxerror(char *s);
+
+typedef struct {
+ Bit64s from;
+ Bit64s to;
+} bx_num_range;
+#define EMPTY_ARG (-1)
+
+bx_num_range make_num_range (Bit64s from, Bit64s to);
+char* bx_dbg_symbolic_address(Bit32u context, Bit32u eip, Bit32u base);
+void bx_dbg_symbol_command(char* filename, Boolean global, Bit32u offset);
+void bx_dbg_trace_on_command(void);
+void bx_dbg_trace_off_command(void);
+void bx_dbg_ptime_command(void);
+void bx_dbg_timebp_command(Boolean absolute, Bit64u time);
+void bx_dbg_diff_memory(void);
+void bx_dbg_always_check(Bit32u page_start, Boolean on);
+void bx_dbg_sync_memory(Boolean set);
+void bx_dbg_sync_cpu(Boolean set);
+void bx_dbg_fast_forward(Bit32u num);
+void bx_dbg_info_address(Bit32u seg_reg_num, Bit32u offset);
+#define MAX_CONCURRENT_BPS 5
+extern int timebp_timer;
+extern Bit64u timebp_queue[MAX_CONCURRENT_BPS];
+extern int timebp_queue_size;
+void bx_dbg_record_command(char*);
+void bx_dbg_playback_command(char*);
+void bx_dbg_modebp_command(char*); /* BW */
+void bx_dbg_where_command(void);
+void bx_dbg_print_string_command(Bit32u addr);
+void bx_dbg_show_command(char*); /* BW */
+void enter_playback_entry();
+void bx_dbg_print_stack_command(int nwords);
+void bx_dbg_watch(int read, Bit32u address);
+void bx_dbg_unwatch(int read, Bit32u address);
+void bx_dbg_continue_command(void);
+void bx_dbg_stepN_command(bx_dbg_icount_t count);
+void bx_dbg_set_command(char *p1, char *p2, char *p3);
+void bx_dbg_del_breakpoint_command(unsigned handle);
+void bx_dbg_vbreakpoint_command(Boolean specific, Bit32u cs, Bit32u eip);
+void bx_dbg_lbreakpoint_command(Boolean specific, Bit32u laddress);
+void bx_dbg_pbreakpoint_command(Boolean specific, Bit32u paddress);
+void bx_dbg_info_bpoints_command(void);
+void bx_dbg_quit_command(void);
+void bx_dbg_info_program_command(void);
+void bx_dbg_info_registers_command(void);
+void bx_dbg_info_dirty_command(void);
+void bx_dbg_info_idt_command(bx_num_range);
+void bx_dbg_info_gdt_command(bx_num_range);
+void bx_dbg_info_ldt_command(bx_num_range);
+void bx_dbg_info_tss_command(bx_num_range);
+void bx_dbg_info_control_regs_command(void);
+void bx_dbg_info_linux_command(void);
+void bx_dbg_examine_command(char *command, char *format, Boolean format_passed,
+ Bit32u addr, Boolean addr_passed, int simulator);
+void bx_dbg_setpmem_command(Bit32u addr, unsigned len, Bit32u val);
+void bx_dbg_set_symbol_command(char *symbol, Bit32u val);
+void bx_dbg_query_command(char *);
+void bx_dbg_take_command(char *, unsigned n);
+void bx_dbg_dump_cpu_command(void);
+void bx_dbg_set_cpu_command(void);
+void bx_dbg_disassemble_command(bx_num_range);
+void bx_dbg_instrument_command(char *);
+void bx_dbg_loader_command(char *);
+void bx_dbg_doit_command(unsigned);
+void bx_dbg_crc_command(Bit32u addr1, Bit32u addr2);
+void bx_dbg_maths_command(char *command, int data1, int data2);
+void bx_dbg_maths_expression_command(char *expr);
+void bx_dbg_v2l_command(unsigned seg_no, Bit32u offset);
+extern Boolean watchpoint_continue;
+void bx_dbg_linux_syscall ();
+
+#ifdef __cplusplus
+}
+#endif
+
+// the rest for C++
+#ifdef __cplusplus
+
+// (mch) Read/write watchpoint hack
+#define MAX_WRITE_WATCHPOINTS 16
+#define MAX_READ_WATCHPOINTS 16
+extern int num_write_watchpoints;
+extern Bit32u write_watchpoint[MAX_WRITE_WATCHPOINTS];
+extern int num_read_watchpoints;
+extern Bit32u read_watchpoint[MAX_READ_WATCHPOINTS];
+
+typedef enum {
+ STOP_NO_REASON = 0, STOP_TIME_BREAK_POINT, STOP_READ_WATCH_POINT, STOP_WRITE_WATCH_POINT, STOP_MAGIC_BREAK_POINT, STOP_TRACE, STOP_MODE_BREAK_POINT, STOP_CPU_HALTED
+} stop_reason_t;
+
+typedef enum {
+ BREAK_POINT_MAGIC, BREAK_POINT_READ, BREAK_POINT_WRITE, BREAK_POINT_TIME
+} break_point_t;
+#endif // __cplusplus
+#endif // BX_DEBUGGER
+#ifdef __cplusplus
+#define BX_DBG_REG_EAX 10
+#define BX_DBG_REG_ECX 11
+#define BX_DBG_REG_EDX 12
+#define BX_DBG_REG_EBX 13
+#define BX_DBG_REG_ESP 14
+#define BX_DBG_REG_EBP 15
+#define BX_DBG_REG_ESI 16
+#define BX_DBG_REG_EDI 17
+#define BX_DBG_REG_EIP 18
+#define BX_DBG_REG_EFLAGS 19
+#define BX_DBG_REG_CS 20
+#define BX_DBG_REG_SS 21
+#define BX_DBG_REG_DS 22
+#define BX_DBG_REG_ES 23
+#define BX_DBG_REG_FS 24
+#define BX_DBG_REG_GS 25
+#endif // __cplusplus
+#if BX_DEBUGGER
+#ifdef __cplusplus
+#define BX_DBG_PENDING_DMA 1
+#define BX_DBG_PENDING_IRQ 2
+
+
+
+
+void bx_dbg_exit(int code);
+#if BX_DBG_EXTENSIONS
+ int bx_dbg_extensions(char *command);
+#else
+#define bx_dbg_extensions(command) 0
+#endif
+
+
+//
+// code for guards...
+//
+
+#define BX_DBG_GUARD_INSTR_BEGIN 0x0001
+#define BX_DBG_GUARD_INSTR_END 0x0002
+#define BX_DBG_GUARD_EXCEP_BEGIN 0x0004
+#define BX_DBG_GUARD_EXCEP_END 0x0008
+#define BX_DBG_GUARD_INTER_BEGIN 0x0010
+#define BX_DBG_GUARD_INTER_END 0x0020
+#define BX_DBG_GUARD_INSTR_MAP 0x0040
+
+// following 3 go along with BX_DBG_GUARD_INSTR_BEGIN
+// to provide breakpointing
+#define BX_DBG_GUARD_IADDR_VIR 0x0080
+#define BX_DBG_GUARD_IADDR_LIN 0x0100
+#define BX_DBG_GUARD_IADDR_PHY 0x0200
+#define BX_DBG_GUARD_IADDR_ALL (BX_DBG_GUARD_IADDR_VIR | \
+ BX_DBG_GUARD_IADDR_LIN | \
+ BX_DBG_GUARD_IADDR_PHY)
+
+#define BX_DBG_GUARD_ICOUNT 0x0400
+#define BX_DBG_GUARD_CTRL_C 0x0800
+
+
+typedef struct {
+ unsigned long guard_for;
+
+ // instruction address breakpoints
+ struct {
+#if BX_DBG_SUPPORT_VIR_BPOINT
+ unsigned num_virtual;
+ struct {
+ Bit32u cs; // only use 16 bits
+ Bit32u eip;
+ unsigned bpoint_id;
+ } vir[BX_DBG_MAX_VIR_BPOINTS];
+#endif
+
+#if BX_DBG_SUPPORT_LIN_BPOINT
+ unsigned num_linear;
+ struct {
+ Bit32u addr;
+ unsigned bpoint_id;
+ } lin[BX_DBG_MAX_LIN_BPOINTS];
+#endif
+
+#if BX_DBG_SUPPORT_PHY_BPOINT
+ unsigned num_physical;
+ struct {
+ Bit32u addr;
+ unsigned bpoint_id;
+ } phy[BX_DBG_MAX_PHY_BPOINTS];
+#endif
+ } iaddr;
+
+ bx_dbg_icount_t icount; // stop after completing this many instructions
+
+ // user typed Ctrl-C, requesting simulator stop at next convient spot
+ volatile Boolean interrupt_requested;
+
+ // booleans to control whether simulator should report events
+ // to debug controller
+ struct {
+ Boolean irq;
+ Boolean a20;
+ Boolean io;
+ Boolean ucmem;
+ Boolean dma;
+ } report;
+
+ struct {
+ Boolean irq; // should process IRQs asynchronously
+ Boolean dma; // should process DMAs asynchronously
+ } async;
+
+#define BX_DBG_ASYNC_PENDING_A20 0x01
+#define BX_DBG_ASYNC_PENDING_RESET 0x02
+#define BX_DBG_ASYNC_PENDING_NMI 0x04
+
+ // Asynchronous changes which are pending. These are Q'd by
+ // the debugger, as the master simulator is notified of a pending
+ // async change. At the simulator's next point, where it checks for
+ // such events, it notifies the debugger with acknowlegement. This
+ // field contains a logically or'd list of all events which should
+ // be checked, and ack'd.
+ struct {
+ unsigned which; // logical OR of above constants
+ Boolean a20;
+ Boolean reset;
+ Boolean nmi;
+ } async_changes_pending;
+ } bx_guard_t;
+
+// working information for each simulator to update when a guard
+// is reached (found)
+typedef struct bx_guard_found_t {
+ unsigned long guard_found;
+ unsigned iaddr_index;
+ bx_dbg_icount_t icount; // number of completed instructions
+ Bit32u cs; // cs:eip and linear addr of instruction at guard point
+ Bit32u eip;
+ Bit32u laddr;
+ Boolean is_32bit_code; // CS seg size at guard point
+ Boolean ctrl_c; // simulator stopped due to Ctrl-C request
+ } bx_guard_found_t;
+
+extern bx_guard_t bx_guard;
+
+
+
+
+
+int bx_dbg_main(int argc, char *argv[]);
+void bx_dbg_user_input_loop(void);
+
+
+typedef struct {
+ Bit16u sel;
+ Bit32u des_l, des_h, valid;
+ } bx_dbg_sreg_t;
+
+typedef struct {
+ Bit32u eax;
+ Bit32u ebx;
+ Bit32u ecx;
+ Bit32u edx;
+ Bit32u ebp;
+ Bit32u esi;
+ Bit32u edi;
+ Bit32u esp;
+ Bit32u eflags;
+ Bit32u eip;
+ bx_dbg_sreg_t cs;
+ bx_dbg_sreg_t ss;
+ bx_dbg_sreg_t ds;
+ bx_dbg_sreg_t es;
+ bx_dbg_sreg_t fs;
+ bx_dbg_sreg_t gs;
+ bx_dbg_sreg_t ldtr;
+ bx_dbg_sreg_t tr;
+ struct { Bit32u base, limit; } gdtr;
+ struct { Bit32u base, limit; } idtr;
+ Bit32u dr0, dr1, dr2, dr3, dr6, dr7;
+ Bit32u tr3, tr4, tr5, tr6, tr7;
+ Bit32u cr0, cr1, cr2, cr3, cr4;
+ unsigned inhibit_mask;
+ } bx_dbg_cpu_t;
+
+
+
+
+typedef struct {
+ // call back functions specific to each simulator
+ Boolean (*setphymem)(Bit32u addr, unsigned len, Bit8u *buf);
+ Boolean (*getphymem)(Bit32u addr, unsigned len, Bit8u *buf);
+ void (*xlate_linear2phy)(Bit32u linear, Bit32u *phy, Boolean *valid);
+ Boolean (*set_reg)(unsigned reg, Bit32u val);
+ Bit32u (*get_reg)(unsigned reg);
+ Boolean (*get_sreg)(bx_dbg_sreg_t *sreg, unsigned sreg_no);
+ Boolean (*set_cpu)(bx_dbg_cpu_t *cpu);
+ Boolean (*get_cpu)(bx_dbg_cpu_t *cpu);
+ unsigned dirty_page_tbl_size;
+ unsigned char *dirty_page_tbl;
+ void (*atexit)(void);
+ unsigned (*query_pending)(void);
+ void (*execute)(void);
+ void (*take_irq)(void);
+ void (*take_dma)(void);
+ void (*reset_cpu)(unsigned source);
+ void (*init_mem)(int size_in_bytes);
+ void (*load_ROM)(const char *path, Bit32u romaddress);
+
+ // for asynchronous environment handling
+ void (*set_A20)(unsigned val);
+ void (*set_NMI)(unsigned val);
+ void (*set_RESET)(unsigned val);
+ void (*set_INTR)(unsigned val);
+ void (*force_interrupt)(unsigned vector);
+
+#if BX_INSTRUMENTATION
+ void (*instr_start)(void);
+ void (*instr_stop)(void);
+ void (*instr_reset)(void);
+ void (*instr_print)(void);
+#endif
+#if BX_USE_LOADER
+ void (*loader)(char *path, bx_loader_misc_t *misc_ptr);
+#endif
+ Boolean (*crc32)(unsigned long (*f)(unsigned char *buf, int len),
+ Bit32u addr1, Bit32u addr2, Bit32u *crc);
+ } bx_dbg_callback_t;
+
+extern bx_dbg_callback_t bx_dbg_callback[BX_NUM_SIMULATORS];
+
+void BX_SIM1_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
+#ifdef BX_SIM2_INIT
+void BX_SIM2_INIT(bx_dbg_callback_t *, int argc, char *argv[]);
+#endif
+
+
+void bx_dbg_dma_report(Bit32u addr, unsigned len, unsigned what, Bit32u val);
+void bx_dbg_iac_report(unsigned vector, unsigned irq);
+void bx_dbg_a20_report(unsigned val);
+void bx_dbg_io_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
+void bx_dbg_ucmem_report(Bit32u addr, unsigned size, unsigned op, Bit32u val);
+
+Bit8u bx_dbg_ucmem_read(Bit32u addr);
+void bx_dbg_ucmem_write(Bit32u addr, Bit8u value);
+void bx_dbg_async_pin_request(unsigned what, Boolean val);
+void bx_dbg_async_pin_ack(unsigned what, Boolean val);
+Bit32u bx_dbg_inp(Bit16u addr, unsigned len);
+void bx_dbg_outp(Bit16u addr, Bit32u value, unsigned len);
+void bx_dbg_raise_HLDA(void);
+Bit8u bx_dbg_IAC(void);
+void bx_dbg_set_INTR(Boolean b);
+
+int bx_dbg_symbolic_output(void); /* BW */
+#endif // #ifdef __cplusplus
+#endif // #if BX_DEBUGGER
--- /dev/null
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+## component/bochs bochs/fpu bochs/fpu/stubs
+INCLUDES = -I$(srcdir)/.. -I$(srcdir) -I$(srcdir)/stubs -DUSE_WITH_CPU_SIM -DPARANOID -DNO_ASSEMBLER
+
+noinst_LTLIBRARIES = libfpu.la
+
+libfpu_la_SOURCES = fpu.cc wmFPUemu_glue.cc fpu_entry.c errors.c reg_ld_str.c load_store.c fpu_arith.c fpu_aux.c fpu_etc.c fpu_tags.c fpu_trig.c poly_atan.c poly_l2.c poly_2xm1.c poly_sin.c poly_tan.c reg_add_sub.c reg_compare.c reg_constant.c reg_convert.c reg_divide.c reg_mul.c reg_u_add.c reg_u_div.c reg_u_mul.c reg_u_sub.c div_small.c reg_norm.c reg_round.c wm_shrx.c wm_sqrt.c div_Xsig.c polynom_Xsig.c round_Xsig.c shr_Xsig.c mul_Xsig.c
+
+
+libfpu_la_LDFLAGS = -no-undefined
--- /dev/null
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(srcdir)/.. -I$(srcdir) -I$(srcdir)/stubs -DUSE_WITH_CPU_SIM -DPARANOID -DNO_ASSEMBLER
+
+noinst_LTLIBRARIES = libfpu.la
+
+libfpu_la_SOURCES = fpu.cc wmFPUemu_glue.cc fpu_entry.c errors.c reg_ld_str.c load_store.c fpu_arith.c fpu_aux.c fpu_etc.c fpu_tags.c fpu_trig.c poly_atan.c poly_l2.c poly_2xm1.c poly_sin.c poly_tan.c reg_add_sub.c reg_compare.c reg_constant.c reg_convert.c reg_divide.c reg_mul.c reg_u_add.c reg_u_div.c reg_u_mul.c reg_u_sub.c div_small.c reg_norm.c reg_round.c wm_shrx.c wm_sqrt.c div_Xsig.c polynom_Xsig.c round_Xsig.c shr_Xsig.c mul_Xsig.c
+
+libfpu_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libfpu_la_LIBADD =
+libfpu_la_OBJECTS = fpu.lo wmFPUemu_glue.lo fpu_entry.lo errors.lo \
+reg_ld_str.lo load_store.lo fpu_arith.lo fpu_aux.lo fpu_etc.lo \
+fpu_tags.lo fpu_trig.lo poly_atan.lo poly_l2.lo poly_2xm1.lo \
+poly_sin.lo poly_tan.lo reg_add_sub.lo reg_compare.lo reg_constant.lo \
+reg_convert.lo reg_divide.lo reg_mul.lo reg_u_add.lo reg_u_div.lo \
+reg_u_mul.lo reg_u_sub.lo div_small.lo reg_norm.lo reg_round.lo \
+wm_shrx.lo wm_sqrt.lo div_Xsig.lo polynom_Xsig.lo round_Xsig.lo \
+shr_Xsig.lo mul_Xsig.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON = README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES = .deps/div_Xsig.P .deps/div_small.P .deps/errors.P \
+.deps/fpu.P .deps/fpu_arith.P .deps/fpu_aux.P .deps/fpu_entry.P \
+.deps/fpu_etc.P .deps/fpu_tags.P .deps/fpu_trig.P .deps/load_store.P \
+.deps/mul_Xsig.P .deps/poly_2xm1.P .deps/poly_atan.P .deps/poly_l2.P \
+.deps/poly_sin.P .deps/poly_tan.P .deps/polynom_Xsig.P \
+.deps/reg_add_sub.P .deps/reg_compare.P .deps/reg_constant.P \
+.deps/reg_convert.P .deps/reg_divide.P .deps/reg_ld_str.P \
+.deps/reg_mul.P .deps/reg_norm.P .deps/reg_round.P .deps/reg_u_add.P \
+.deps/reg_u_div.P .deps/reg_u_mul.P .deps/reg_u_sub.P \
+.deps/round_Xsig.P .deps/shr_Xsig.P .deps/wmFPUemu_glue.P \
+.deps/wm_shrx.P .deps/wm_sqrt.P
+SOURCES = $(libfpu_la_SOURCES)
+OBJECTS = $(libfpu_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign fpu/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libfpu.la: $(libfpu_la_OBJECTS) $(libfpu_la_DEPENDENCIES)
+ $(CXXLINK) $(libfpu_la_LDFLAGS) $(libfpu_la_OBJECTS) $(libfpu_la_LIBADD) $(LIBS)
+.cc.o:
+ $(CXXCOMPILE) -c $<
+.cc.lo:
+ $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = fpu
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign fpu/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cc
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cc
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Portable i387 emulator
+
+22 Nov 99 Version 2.02:
+
+First pseudo-portable version for little-endian machines.
+
+Beginning of big-endian support provided through the pre-processor
+symbol BIG_ENDIAN.
+
+Some of the code in fpu_entry.c and get_address.c is still in a
+non-portable form and these two files still contain assembler code.
+
+
--- /dev/null
+ +---------------------------------------------------------------------------+
+ | wm-FPU-emu an FPU emulator for 80386 and 80486SX microprocessors. |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1996,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | This program is free software; you can redistribute it and/or modify |
+ | it under the terms of the GNU General Public License version 2 as |
+ | published by the Free Software Foundation. |
+ | |
+ | This program is distributed in the hope that it will be useful, |
+ | but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ | GNU General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU General Public License |
+ | along with this program; if not, write to the Free Software |
+ | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
+ | |
+ +---------------------------------------------------------------------------+
+
+
+
+wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387
+which was my 80387 emulator for early versions of djgpp (gcc under
+msdos); wm-emu387 was in turn based upon emu387 which was written by
+DJ Delorie for djgpp. The interface to the Linux kernel is based upon
+the original Linux math emulator by Linus Torvalds.
+
+My target FPU for wm-FPU-emu is that described in the Intel486
+Programmer's Reference Manual (1992 edition). Unfortunately, numerous
+facets of the functioning of the FPU are not well covered in the
+Reference Manual. The information in the manual has been supplemented
+with measurements on real 80486's. Unfortunately, it is simply not
+possible to be sure that all of the peculiarities of the 80486 have
+been discovered, so there is always likely to be obscure differences
+in the detailed behaviour of the emulator and a real 80486.
+
+wm-FPU-emu does not implement all of the behaviour of the 80486 FPU,
+but is very close. See "Limitations" later in this file for a list of
+some differences.
+
+Please report bugs, etc to me at:
+ billm@melbpc.org.au
+or b.metzenthen@medoto.unimelb.edu.au
+
+For more information on the emulator and on floating point topics, see
+my web pages, currently at http://www.suburbia.net/~billm/
+
+
+--Bill Metzenthen
+ December 1999
+
+
+----------------------- Internals of wm-FPU-emu -----------------------
+
+Numeric algorithms:
+(1) Add, subtract, and multiply. Nothing remarkable in these.
+(2) Divide has been tuned to get reasonable performance. The algorithm
+ is not the obvious one which most people seem to use, but is designed
+ to take advantage of the characteristics of the 80386. I expect that
+ it has been invented many times before I discovered it, but I have not
+ seen it. It is based upon one of those ideas which one carries around
+ for years without ever bothering to check it out.
+(3) The sqrt function has been tuned to get good performance. It is based
+ upon Newton's classic method. Performance was improved by capitalizing
+ upon the properties of Newton's method, and the code is once again
+ structured taking account of the 80386 characteristics.
+(4) The trig, log, and exp functions are based in each case upon quasi-
+ "optimal" polynomial approximations. My definition of "optimal" was
+ based upon getting good accuracy with reasonable speed.
+(5) The argument reducing code for the trig function effectively uses
+ a value of pi which is accurate to more than 128 bits. As a consequence,
+ the reduced argument is accurate to more than 64 bits for arguments up
+ to a few pi, and accurate to more than 64 bits for most arguments,
+ even for arguments approaching 2^63. This is far superior to an
+ 80486, which uses a value of pi which is accurate to 66 bits.
+
+The code of the emulator is complicated slightly by the need to
+account for a limited form of re-entrancy. Normally, the emulator will
+emulate each FPU instruction to completion without interruption.
+However, it may happen that when the emulator is accessing the user
+memory space, swapping may be needed. In this case the emulator may be
+temporarily suspended while disk i/o takes place. During this time
+another process may use the emulator, thereby perhaps changing static
+variables. The code which accesses user memory is confined to five
+files:
+ fpu_entry.c
+ reg_ld_str.c
+ load_store.c
+ get_address.c
+ errors.c
+As from version 1.12 of the emulator, no static variables are used
+(apart from those in the kernel's per-process tables). The emulator is
+therefore now fully re-entrant, rather than having just the restricted
+form of re-entrancy which is required by the Linux kernel.
+
+----------------------- Limitations of wm-FPU-emu -----------------------
+
+There are a number of differences between the current wm-FPU-emu
+(version 2.05) and the 80486 FPU (apart from bugs). The differences
+are fewer than those which applied to the 1.xx series of the emulator.
+Some of the more important differences are listed below:
+
+The Roundup flag does not have much meaning for the transcendental
+functions and its 80486 value with these functions is likely to differ
+from its emulator value.
+
+In a few rare cases the Underflow flag obtained with the emulator will
+be different from that obtained with an 80486. This occurs when the
+following conditions apply simultaneously:
+(a) the operands have a higher precision than the current setting of the
+ precision control (PC) flags.
+(b) the underflow exception is masked.
+(c) the magnitude of the exact result (before rounding) is less than 2^-16382.
+(d) the magnitude of the final result (after rounding) is exactly 2^-16382.
+(e) the magnitude of the exact result would be exactly 2^-16382 if the
+ operands were rounded to the current precision before the arithmetic
+ operation was performed.
+If all of these apply, the emulator will set the Underflow flag but a real
+80486 will not.
+
+NOTE: Certain formats of Extended Real are UNSUPPORTED. They are
+unsupported by the 80486. They are the Pseudo-NaNs, Pseudoinfinities,
+and Unnormals. None of these will be generated by an 80486 or by the
+emulator. Do not use them. The emulator treats them differently in
+detail from the way an 80486 does.
+
+Self modifying code can cause the emulator to fail. An example of such
+code is:
+ movl %esp,[%ebx]
+ fld1
+The FPU instruction may be (usually will be) loaded into the pre-fetch
+queue of the CPU before the mov instruction is executed. If the
+destination of the 'movl' overlaps the FPU instruction then the bytes
+in the prefetch queue and memory will be inconsistent when the FPU
+instruction is executed. The emulator will be invoked but will not be
+able to find the instruction which caused the device-not-present
+exception. For this case, the emulator cannot emulate the behaviour of
+an 80486DX.
+
+Handling of the address size override prefix byte (0x67) has not been
+extensively tested yet. A major problem exists because using it in
+vm86 mode can cause a general protection fault. Address offsets
+greater than 0xffff appear to be illegal in vm86 mode but are quite
+acceptable (and work) in real mode. A small test program developed to
+check the addressing, and which runs successfully in real mode,
+crashes dosemu under Linux and also brings Windows down with a general
+protection fault message when run under the MS-DOS prompt of Windows
+3.1. (The program simply reads data from a valid address).
+
+The emulator supports 16-bit protected mode, with one difference from
+an 80486DX. A 80486DX will allow some floating point instructions to
+write a few bytes below the lowest address of the stack. The emulator
+will not allow this in 16-bit protected mode: no instructions are
+allowed to write outside the bounds set by the protection.
+
+----------------------- Performance of wm-FPU-emu -----------------------
+
+Speed.
+-----
+
+The speed of floating point computation with the emulator will depend
+upon instruction mix. Relative performance is best for the instructions
+which require most computation. The simple instructions are adversely
+affected by the FPU instruction trap overhead.
+
+
+Timing: Some simple timing tests have been made on the emulator functions.
+The times include load/store instructions. All times are in microseconds
+measured on a 33MHz 386 with 64k cache. The Turbo C tests were under
+ms-dos, the next two columns are for emulators running with the djgpp
+ms-dos extender. The final column is for wm-FPU-emu in Linux 0.97,
+using libm4.0 (hard).
+
+function Turbo C djgpp 1.06 WM-emu387 wm-FPU-emu
+
+ + 60.5 154.8 76.5 139.4
+ - 61.1-65.5 157.3-160.8 76.2-79.5 142.9-144.7
+ * 71.0 190.8 79.6 146.6
+ / 61.2-75.0 261.4-266.9 75.3-91.6 142.2-158.1
+
+ sin() 310.8 4692.0 319.0 398.5
+ cos() 284.4 4855.2 308.0 388.7
+ tan() 495.0 8807.1 394.9 504.7
+ atan() 328.9 4866.4 601.1 419.5-491.9
+
+ sqrt() 128.7 crashed 145.2 227.0
+ log() 413.1-419.1 5103.4-5354.21 254.7-282.2 409.4-437.1
+ exp() 479.1 6619.2 469.1 850.8
+
+
+The performance under Linux is improved by the use of look-ahead code.
+The following results show the improvement which is obtained under
+Linux due to the look-ahead code. Also given are the times for the
+original Linux emulator with the 4.1 'soft' lib.
+
+ [ Linus' note: I changed look-ahead to be the default under linux, as
+ there was no reason not to use it after I had edited it to be
+ disabled during tracing ]
+
+ wm-FPU-emu w original w
+ look-ahead 'soft' lib
+ + 106.4 190.2
+ - 108.6-111.6 192.4-216.2
+ * 113.4 193.1
+ / 108.8-124.4 700.1-706.2
+
+ sin() 390.5 2642.0
+ cos() 381.5 2767.4
+ tan() 496.5 3153.3
+ atan() 367.2-435.5 2439.4-3396.8
+
+ sqrt() 195.1 4732.5
+ log() 358.0-387.5 3359.2-3390.3
+ exp() 619.3 4046.4
+
+
+These figures are now somewhat out-of-date. The emulator has become
+progressively slower for most functions as more of the 80486 features
+have been implemented.
+
+
+----------------------- Accuracy of wm-FPU-emu -----------------------
+
+
+The accuracy of the emulator is in almost all cases equal to or better
+than that of an Intel 80486 FPU.
+
+The results of the basic arithmetic functions (+,-,*,/), and fsqrt
+match those of an 80486 FPU. They are the best possible; the error for
+these never exceeds 1/2 an lsb. The fprem and fprem1 instructions
+return exact results; they have no error.
+
+
+The following table compares the emulator accuracy for the sqrt(),
+trig and log functions against the Turbo C "emulator". For this table,
+each function was tested at about 400 points. Ideal worst-case results
+would be 64 bits. The reduced Turbo C accuracy of cos() and tan() for
+arguments greater than pi/4 can be thought of as being related to the
+precision of the argument x; e.g. an argument of pi/2-(1e-10) which is
+accurate to 64 bits can result in a relative accuracy in cos() of
+about 64 + log2(cos(x)) = 31 bits.
+
+
+Function Tested x range Worst result Turbo C
+ (relative bits)
+
+sqrt(x) 1 .. 2 64.1 63.2
+atan(x) 1e-10 .. 200 64.2 62.8
+cos(x) 0 .. pi/2-(1e-10) 64.4 (x <= pi/4) 62.4
+ 64.1 (x = pi/2-(1e-10)) 31.9
+sin(x) 1e-10 .. pi/2 64.0 62.8
+tan(x) 1e-10 .. pi/2-(1e-10) 64.0 (x <= pi/4) 62.1
+ 64.1 (x = pi/2-(1e-10)) 31.9
+exp(x) 0 .. 1 63.1 ** 62.9
+log(x) 1+1e-6 .. 2 63.8 ** 62.1
+
+** The accuracy for exp() and log() is low because the FPU (emulator)
+does not compute them directly; two operations are required.
+
+
+The emulator passes the "paranoia" tests (compiled with gcc 2.3.3 or
+later) for 'float' variables (24 bit precision numbers) when precision
+control is set to 24, 53 or 64 bits, and for 'double' variables (53
+bit precision numbers) when precision control is set to 53 bits (a
+properly performing FPU cannot pass the 'paranoia' tests for 'double'
+variables when precision control is set to 64 bits).
+
+The code for reducing the argument for the trig functions (fsin, fcos,
+fptan and fsincos) has been improved and now effectively uses a value
+for pi which is accurate to more than 128 bits precision. As a
+consequence, the accuracy of these functions for large arguments has
+been dramatically improved (and is now very much better than an 80486
+FPU). There is also now no degradation of accuracy for fcos and fptan
+for operands close to pi/2. Measured results are (note that the
+definition of accuracy has changed slightly from that used for the
+above table):
+
+Function Tested x range Worst result
+ (absolute bits)
+
+cos(x) 0 .. 9.22e+18 62.0
+sin(x) 1e-16 .. 9.22e+18 62.1
+tan(x) 1e-16 .. 9.22e+18 61.8
+
+It is possible with some effort to find very large arguments which
+give much degraded precision. For example, the integer number
+ 8227740058411162616.0
+is within about 10e-7 of a multiple of pi. To find the tan (for
+example) of this number to 64 bits precision it would be necessary to
+have a value of pi which had about 150 bits precision. The FPU
+emulator computes the result to about 42.6 bits precision (the correct
+result is about -9.739715e-8). On the other hand, an 80486 FPU returns
+0.01059, which in relative terms is hopelessly inaccurate.
+
+For arguments close to critical angles (which occur at multiples of
+pi/2) the emulator is more accurate than an 80486 FPU. For very large
+arguments, the emulator is far more accurate.
+
+
+Prior to version 1.20 of the emulator, the accuracy of the results for
+the transcendental functions (in their principal range) was not as
+good as the results from an 80486 FPU. From version 1.20, the accuracy
+has been considerably improved and these functions now give measured
+worst-case results which are better than the worst-case results given
+by an 80486 FPU.
+
+The following table gives the measured results for the emulator. The
+number of randomly selected arguments in each case is about half a
+million. The group of three columns gives the frequency of the given
+accuracy in number of times per million, thus the second of these
+columns shows that an accuracy of between 63.80 and 63.89 bits was
+found at a rate of 133 times per one million measurements for fsin.
+The results show that the fsin, fcos and fptan instructions return
+results which are in error (i.e. less accurate than the best possible
+result (which is 64 bits)) for about one per cent of all arguments
+between -pi/2 and +pi/2. The other instructions have a lower
+frequency of results which are in error. The last two columns give
+the worst accuracy which was found (in bits) and the approximate value
+of the argument which produced it.
+
+ frequency (per M)
+ ------------------- ---------------
+instr arg range # tests 63.7 63.8 63.9 worst at arg
+ bits bits bits bits
+----- ------------ ------- ---- ---- ----- ----- --------
+fsin (0,pi/2) 547756 0 133 10673 63.89 0.451317
+fcos (0,pi/2) 547563 0 126 10532 63.85 0.700801
+fptan (0,pi/2) 536274 11 267 10059 63.74 0.784876
+fpatan 4 quadrants 517087 0 8 1855 63.88 0.435121 (4q)
+fyl2x (0,20) 541861 0 0 1323 63.94 1.40923 (x)
+fyl2xp1 (-.293,.414) 520256 0 0 5678 63.93 0.408542 (x)
+f2xm1 (-1,1) 538847 4 481 6488 63.79 0.167709
+
+
+Tests performed on an 80486 FPU showed results of lower accuracy. The
+following table gives the results which were obtained with an AMD
+486DX2/66 (other tests indicate that an Intel 486DX produces
+identical results). The tests were basically the same as those used
+to measure the emulator (the values, being random, were in general not
+the same). The total number of tests for each instruction are given
+at the end of the table, in case each about 100k tests were performed.
+Another line of figures at the end of the table shows that most of the
+instructions return results which are in error for more than 10
+percent of the arguments tested.
+
+The numbers in the body of the table give the approx number of times a
+result of the given accuracy in bits (given in the left-most column)
+was obtained per one million arguments. For three of the instructions,
+two columns of results are given: * The second column for f2xm1 gives
+the number cases where the results of the first column were for a
+positive argument, this shows that this instruction gives better
+results for positive arguments than it does for negative. * In the
+cases of fcos and fptan, the first column gives the results when all
+cases where arguments greater than 1.5 were removed from the results
+given in the second column. Unlike the emulator, an 80486 FPU returns
+results of relatively poor accuracy for these instructions when the
+argument approaches pi/2. The table does not show those cases when the
+accuracy of the results were less than 62 bits, which occurs quite
+often for fsin and fptan when the argument approaches pi/2. This poor
+accuracy is discussed above in relation to the Turbo C "emulator", and
+the accuracy of the value of pi.
+
+
+bits f2xm1 f2xm1 fpatan fcos fcos fyl2x fyl2xp1 fsin fptan fptan
+62.0 0 0 0 0 437 0 0 0 0 925
+62.1 0 0 10 0 894 0 0 0 0 1023
+62.2 14 0 0 0 1033 0 0 0 0 945
+62.3 57 0 0 0 1202 0 0 0 0 1023
+62.4 385 0 0 10 1292 0 23 0 0 1178
+62.5 1140 0 0 119 1649 0 39 0 0 1149
+62.6 2037 0 0 189 1620 0 16 0 0 1169
+62.7 5086 14 0 646 2315 10 101 35 39 1402
+62.8 8818 86 0 984 3050 59 287 131 224 2036
+62.9 11340 1355 0 2126 4153 79 605 357 321 1948
+63.0 15557 4750 0 3319 5376 246 1281 862 808 2688
+63.1 20016 8288 0 4620 6628 511 2569 1723 1510 3302
+63.2 24945 11127 10 6588 8098 1120 4470 2968 2990 4724
+63.3 25686 12382 69 8774 10682 1906 6775 4482 5474 7236
+63.4 29219 14722 79 11109 12311 3094 9414 7259 8912 10587
+63.5 30458 14936 393 13802 15014 5874 12666 9609 13762 15262
+63.6 32439 16448 1277 17945 19028 10226 15537 14657 19158 20346
+63.7 35031 16805 4067 23003 23947 18910 20116 21333 25001 26209
+63.8 33251 15820 7673 24781 25675 24617 25354 24440 29433 30329
+63.9 33293 16833 18529 28318 29233 31267 31470 27748 29676 30601
+
+Per cent with error:
+ 30.9 3.2 18.5 9.8 13.1 11.6 17.4
+Total arguments tested:
+ 70194 70099 101784 100641 100641 101799 128853 114893 102675 102675
+
+
+------------------------- Contributors -------------------------------
+
+A number of people have contributed to the development of the
+emulator, often by just reporting bugs, sometimes with suggested
+fixes, and a few kind people have provided me with access in one way
+or another to an 80486 machine. Contributors include (to those people
+who I may have forgotten, please forgive me):
+
+Linus Torvalds
+Tommy.Thorn@daimi.aau.dk
+Andrew.Tridgell@anu.edu.au
+Nick Holloway, alfie@dcs.warwick.ac.uk
+Hermano Moura, moura@dcs.gla.ac.uk
+Jon Jagger, J.Jagger@scp.ac.uk
+Lennart Benschop
+Brian Gallew, geek+@CMU.EDU
+Thomas Staniszewski, ts3v+@andrew.cmu.edu
+Martin Howell, mph@plasma.apana.org.au
+M Saggaf, alsaggaf@athena.mit.edu
+Peter Barker, PETER@socpsy.sci.fau.edu
+tom@vlsivie.tuwien.ac.at
+Dan Russel, russed@rpi.edu
+Daniel Carosone, danielce@ee.mu.oz.au
+cae@jpmorgan.com
+Hamish Coleman, t933093@minyos.xx.rmit.oz.au
+Bruce Evans, bde@kralizec.zeta.org.au
+Timo Korvola, Timo.Korvola@hut.fi
+Rick Lyons, rick@razorback.brisnet.org.au
+Rick, jrs@world.std.com
+
+...and numerous others who responded to my request for help with
+a real 80486.
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | control_w.h |
+ | |
+ | Copyright (C) 1992,1993 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _CONTROLW_H_
+#define _CONTROLW_H_
+
+#ifdef __ASSEMBLY__
+#define _Const_(x) $##x
+#else
+#define _Const_(x) x
+#endif
+
+#define CW_RC _Const_(0x0C00) /* rounding control */
+#define CW_PC _Const_(0x0300) /* precision control */
+
+#define CW_Precision Const_(0x0020) /* loss of precision mask */
+#define CW_Underflow Const_(0x0010) /* underflow mask */
+#define CW_Overflow Const_(0x0008) /* overflow mask */
+#define CW_ZeroDiv Const_(0x0004) /* divide by zero mask */
+#define CW_Denormal Const_(0x0002) /* denormalized operand mask */
+#define CW_Invalid Const_(0x0001) /* invalid operation mask */
+
+#define CW_Exceptions _Const_(0x003f) /* all masks */
+
+#define RC_RND _Const_(0x0000)
+#define RC_DOWN _Const_(0x0400)
+#define RC_UP _Const_(0x0800)
+#define RC_CHOP _Const_(0x0C00)
+
+/* p 15-5: Precision control bits affect only the following:
+ ADD, SUB(R), MUL, DIV(R), and SQRT */
+#define PR_24_BITS _Const_(0x000)
+#define PR_53_BITS _Const_(0x200)
+#define PR_64_BITS _Const_(0x300)
+#define PR_RESERVED_BITS _Const_(0x100)
+/* FULL_PRECISION simulates all exceptions masked */
+#define FULL_PRECISION (PR_64_BITS | RC_RND | 0x3f)
+
+#endif /* _CONTROLW_H_ */
--- /dev/null
+ .file "div_Xsig.S"
+/*---------------------------------------------------------------------------+
+ | div_Xsig.S |
+ | |
+ | Division subroutine for 96 bit quantities |
+ | |
+ | Copyright (C) 1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Divide the 96 bit quantity pointed to by a, by that pointed to by b, and |
+ | put the 96 bit result at the location d. |
+ | |
+ | The result may not be accurate to 96 bits. It is intended for use where |
+ | a result better than 64 bits is required. The result should usually be |
+ | good to at least 94 bits. |
+ | The returned result is actually divided by one half. This is done to |
+ | prevent overflow. |
+ | |
+ | .aaaaaaaaaaaaaa / .bbbbbbbbbbbbb -> .dddddddddddd |
+ | |
+ | void div_Xsig(Xsig *a, Xsig *b, Xsig *dest) |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#define XsigLL(x) (x)
+#define XsigL(x) 4(x)
+#define XsigH(x) 8(x)
+
+
+#ifndef NON_REENTRANT_FPU
+/*
+ Local storage on the stack:
+ Accumulator: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ */
+#define FPU_accum_3 -4(%ebp)
+#define FPU_accum_2 -8(%ebp)
+#define FPU_accum_1 -12(%ebp)
+#define FPU_accum_0 -16(%ebp)
+#define FPU_result_3 -20(%ebp)
+#define FPU_result_2 -24(%ebp)
+#define FPU_result_1 -28(%ebp)
+
+#else
+.data
+/*
+ Local storage in a static area:
+ Accumulator: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ */
+ .align 4,0
+FPU_accum_3:
+ .long 0
+FPU_accum_2:
+ .long 0
+FPU_accum_1:
+ .long 0
+FPU_accum_0:
+ .long 0
+FPU_result_3:
+ .long 0
+FPU_result_2:
+ .long 0
+FPU_result_1:
+ .long 0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(div_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+ subl $28,%esp
+#endif /* NON_REENTRANT_FPU */
+
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* pointer to num */
+ movl PARAM2,%ebx /* pointer to denom */
+
+#ifdef PARANOID
+ testl $0x80000000, XsigH(%ebx) /* Divisor */
+ je L_bugged
+#endif /* PARANOID */
+
+
+/*---------------------------------------------------------------------------+
+ | Divide: Return arg1/arg2 to arg3. |
+ | |
+ | The maximum returned value is (ignoring exponents) |
+ | .ffffffff ffffffff |
+ | ------------------ = 1.ffffffff fffffffe |
+ | .80000000 00000000 |
+ | and the minimum is |
+ | .80000000 00000000 |
+ | ------------------ = .80000000 00000001 (rounded) |
+ | .ffffffff ffffffff |
+ | |
+ +---------------------------------------------------------------------------*/
+
+ /* Save extended dividend in local register */
+
+ /* Divide by 2 to prevent overflow */
+ clc
+ movl XsigH(%esi),%eax
+ rcrl %eax
+ movl %eax,FPU_accum_3
+ movl XsigL(%esi),%eax
+ rcrl %eax
+ movl %eax,FPU_accum_2
+ movl XsigLL(%esi),%eax
+ rcrl %eax
+ movl %eax,FPU_accum_1
+ movl $0,%eax
+ rcrl %eax
+ movl %eax,FPU_accum_0
+
+ movl FPU_accum_2,%eax /* Get the current num */
+ movl FPU_accum_3,%edx
+
+/*----------------------------------------------------------------------*/
+/* Initialization done.
+ Do the first 32 bits. */
+
+ /* We will divide by a number which is too large */
+ movl XsigH(%ebx),%ecx
+ addl $1,%ecx
+ jnc LFirst_div_not_1
+
+ /* here we need to divide by 100000000h,
+ i.e., no division at all.. */
+ mov %edx,%eax
+ jmp LFirst_div_done
+
+LFirst_div_not_1:
+ divl %ecx /* Divide the numerator by the augmented
+ denom ms dw */
+
+LFirst_div_done:
+ movl %eax,FPU_result_3 /* Put the result in the answer */
+
+ mull XsigH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,FPU_accum_2 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_3
+
+ movl FPU_result_3,%eax /* Get the result back */
+ mull XsigL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+ sbbl $0,FPU_accum_3
+ je LDo_2nd_32_bits /* Must check for non-zero result here */
+
+#ifdef PARANOID
+ jb L_bugged_1
+#endif /* PARANOID */
+
+ /* need to subtract another once of the denom */
+ incl FPU_result_3 /* Correct the answer */
+
+ movl XsigL(%ebx),%eax
+ movl XsigH(%ebx),%edx
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+
+#ifdef PARANOID
+ sbbl $0,FPU_accum_3
+ jne L_bugged_1 /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* Half of the main problem is done, there is just a reduced numerator
+ to handle now.
+ Work with the second 32 bits, FPU_accum_0 not used from now on */
+LDo_2nd_32_bits:
+ movl FPU_accum_2,%edx /* get the reduced num */
+ movl FPU_accum_1,%eax
+
+ /* need to check for possible subsequent overflow */
+ cmpl XsigH(%ebx),%edx
+ jb LDo_2nd_div
+ ja LPrevent_2nd_overflow
+
+ cmpl XsigL(%ebx),%eax
+ jb LDo_2nd_div
+
+LPrevent_2nd_overflow:
+/* The numerator is greater or equal, would cause overflow */
+ /* prevent overflow */
+ subl XsigL(%ebx),%eax
+ sbbl XsigH(%ebx),%edx
+ movl %edx,FPU_accum_2
+ movl %eax,FPU_accum_1
+
+ incl FPU_result_3 /* Reflect the subtraction in the answer */
+
+#ifdef PARANOID
+ je L_bugged_2 /* Can't bump the result to 1.0 */
+#endif /* PARANOID */
+
+LDo_2nd_div:
+ cmpl $0,%ecx /* augmented denom msw */
+ jnz LSecond_div_not_1
+
+ /* %ecx == 0, we are dividing by 1.0 */
+ mov %edx,%eax
+ jmp LSecond_div_done
+
+LSecond_div_not_1:
+ divl %ecx /* Divide the numerator by the denom ms dw */
+
+LSecond_div_done:
+ movl %eax,FPU_result_2 /* Put the result in the answer */
+
+ mull XsigH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif /* PARANOID */
+
+ movl FPU_result_2,%eax /* Get the result back */
+ mull XsigL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,FPU_accum_0 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl $0,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif /* PARANOID */
+
+ jz LDo_3rd_32_bits
+
+#ifdef PARANOID
+ cmpl $1,FPU_accum_2
+ jne L_bugged_2
+#endif /* PARANOID */
+
+ /* need to subtract another once of the denom */
+ movl XsigL(%ebx),%eax
+ movl XsigH(%ebx),%edx
+ subl %eax,FPU_accum_0 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_1
+ sbbl $0,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+ jne L_bugged_2
+#endif /* PARANOID */
+
+ addl $1,FPU_result_2 /* Correct the answer */
+ adcl $0,FPU_result_3
+
+#ifdef PARANOID
+ jc L_bugged_2 /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* The division is essentially finished here, we just need to perform
+ tidying operations.
+ Deal with the 3rd 32 bits */
+LDo_3rd_32_bits:
+ /* We use an approximation for the third 32 bits.
+ To take account of the 3rd 32 bits of the divisor
+ (call them del), we subtract del * (a/b) */
+
+ movl FPU_result_3,%eax /* a/b */
+ mull XsigLL(%ebx) /* del */
+
+ subl %edx,FPU_accum_1
+
+ /* A borrow indicates that the result is negative */
+ jnb LTest_over
+
+ movl XsigH(%ebx),%edx
+ addl %edx,FPU_accum_1
+
+ subl $1,FPU_result_2 /* Adjust the answer */
+ sbbl $0,FPU_result_3
+
+ /* The above addition might not have been enough, check again. */
+ movl FPU_accum_1,%edx /* get the reduced num */
+ cmpl XsigH(%ebx),%edx /* denom */
+ jb LDo_3rd_div
+
+ movl XsigH(%ebx),%edx
+ addl %edx,FPU_accum_1
+
+ subl $1,FPU_result_2 /* Adjust the answer */
+ sbbl $0,FPU_result_3
+ jmp LDo_3rd_div
+
+LTest_over:
+ movl FPU_accum_1,%edx /* get the reduced num */
+
+ /* need to check for possible subsequent overflow */
+ cmpl XsigH(%ebx),%edx /* denom */
+ jb LDo_3rd_div
+
+ /* prevent overflow */
+ subl XsigH(%ebx),%edx
+ movl %edx,FPU_accum_1
+
+ addl $1,FPU_result_2 /* Reflect the subtraction in the answer */
+ adcl $0,FPU_result_3
+
+LDo_3rd_div:
+ movl FPU_accum_0,%eax
+ movl FPU_accum_1,%edx
+ divl XsigH(%ebx)
+
+ movl %eax,FPU_result_1 /* Rough estimate of third word */
+
+ movl PARAM3,%esi /* pointer to answer */
+
+ movl FPU_result_1,%eax
+ movl %eax,XsigLL(%esi)
+ movl FPU_result_2,%eax
+ movl %eax,XsigL(%esi)
+ movl FPU_result_3,%eax
+ movl %eax,XsigH(%esi)
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+
+ leave
+ ret
+
+
+#ifdef PARANOID
+/* The logic is wrong if we got here */
+L_bugged:
+ pushl EX_INTERNAL|0x240
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_1:
+ pushl EX_INTERNAL|0x241
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_2:
+ pushl EX_INTERNAL|0x242
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+#endif /* PARANOID */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | div_Xsig.S |
+ | |
+ | Division subroutine for 96 bit quantities |
+ | |
+ | Copyright (C) 1994,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Divide the 96 bit quantity pointed to by a, by that pointed to by b, and |
+ | put the 96 bit result at the location d. |
+ | |
+ | The result may not be accurate to 96 bits. It is intended for use where |
+ | a result better than 64 bits is required. The result should usually be |
+ | good to at least 94 bits. |
+ | The returned result is actually divided by one half. This is done to |
+ | prevent overflow. |
+ | |
+ | .aaaaaaaaaaaaaa / .bbbbbbbbbbbbb -> .dddddddddddd |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void div_Xsig(const Xsig *aa, const Xsig *b, Xsig *dest)
+{
+ Xsig a = *aa, xpr, result;
+ u32 prodh, prodl, den, wd;
+ u64 num, prod;
+
+#ifdef PARANOID
+ if ( (b->msw & 0x80000000) == 0 )
+ {
+ EXCEPTION(EX_INTERNAL|0x240);
+ return;
+ }
+#endif
+
+ /* Shift a right */
+ a.lsw >>= 1;
+ if ( a.midw & 1 )
+ a.lsw |= 0x80000000;
+ a.midw >>= 1;
+ if ( a.msw & 1 )
+ a.midw |= 0x80000000;
+ a.msw >>= 1;
+
+ num = a.msw;
+ num <<= 32;
+ num |= a.midw;
+
+ den = b->msw + 1;
+ if ( den )
+ {
+ result.msw = num / den;
+ }
+ else
+ result.msw = a.msw;
+
+ xpr = *b;
+ mul32_Xsig(&xpr, result.msw);
+ a.msw -= xpr.msw;
+ wd = a.midw;
+ a.midw -= xpr.midw;
+ if ( a.midw > wd )
+ a.msw --;
+ wd = a.lsw;
+ a.lsw -= xpr.lsw;
+ if ( a.lsw > wd )
+ {
+ a.midw --;
+ if ( a.midw == 0xffffffff )
+ a.msw --;
+ }
+
+#ifdef PARANOID
+ if ( a.msw > 1 )
+ {
+ EXCEPTION(EX_INTERNAL|0x241);
+ }
+#endif
+
+ while ( (a.msw != 0) || (a.midw > b->msw) )
+ {
+ wd = a.midw;
+ a.midw -= b->msw;
+ if ( a.midw > wd )
+ a.msw --;
+ wd = a.lsw;
+ a.lsw -= b->midw;
+ if ( a.lsw > wd )
+ {
+ a.midw --;
+ if ( a.midw == 0xffffffff )
+ a.msw --;
+ }
+ result.msw ++;
+ }
+
+ /* Whew! result.msw is now done. */
+
+ num = a.midw;
+ num <<= 32;
+ num |= a.lsw;
+
+ if ( den )
+ {
+ result.midw = num / den;
+ }
+ else
+ result.midw = a.midw;
+
+ prod = result.midw;
+ prod *= b->msw;
+ a.midw -= prod >> 32;
+ prodl = prod;
+ wd = a.lsw;
+ a.lsw -= prodl;
+ if ( a.lsw > wd )
+ a.midw --;
+
+ prod = result.midw;
+ prod *= b->midw;
+ prodh = prod >> 32;
+ wd = a.lsw;
+ a.lsw -= prodh;
+ if ( a.lsw > wd )
+ a.midw --;
+
+#ifdef PARANOID
+ if ( a.midw > 1 )
+ {
+ EXCEPTION(EX_INTERNAL|0x242);
+ }
+#endif
+
+ while ( (a.midw != 0) || (a.lsw > b->msw) )
+ {
+ wd = a.lsw;
+ a.lsw -= b->msw;
+ if ( a.lsw > wd )
+ a.midw --;
+ result.midw ++;
+ }
+
+
+ /* Now result.msw is done, the lsw is next... */
+
+ num = a.lsw;
+ num <<= 32;
+
+ if ( den )
+ {
+ result.lsw = num / den;
+ }
+ else
+ result.lsw = a.lsw;
+
+ prod = result.lsw;
+ prod *= b->msw;
+ a.lsw -= prod >> 32;
+
+#ifdef PARANOID
+ if ( a.lsw > 2 )
+ {
+ EXCEPTION(EX_INTERNAL|0x243);
+ }
+#endif
+
+ result.lsw -= a.lsw;
+
+ /* Hey! we're done. */
+
+ *dest = result;
+
+}
+
--- /dev/null
+ .file "div_small.S"
+/*---------------------------------------------------------------------------+
+ | div_small.S |
+ | |
+ | Divide a 64 bit integer by a 32 bit integer & return remainder. |
+ | |
+ | Copyright (C) 1992,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | unsigned long FPU_div_small(unsigned long long *x, unsigned long y) |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(FPU_div_small)
+ pushl %ebp
+ movl %esp,%ebp
+
+ pushl %esi
+
+ movl PARAM1,%esi /* pointer to num */
+ movl PARAM2,%ecx /* The denominator */
+
+ movl 4(%esi),%eax /* Get the current num msw */
+ xorl %edx,%edx
+ divl %ecx
+
+ movl %eax,4(%esi)
+
+ movl (%esi),%eax /* Get the num lsw */
+ divl %ecx
+
+ movl %eax,(%esi)
+
+ movl %edx,%eax /* Return the remainder in eax */
+
+ popl %esi
+
+ leave
+ ret
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | div_small.S |
+ | |
+ | Divide a 64 bit integer by a 32 bit integer & return remainder. |
+ | |
+ | Copyright (C) 1992,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+
+u32 FPU_div_small(u64 *x, u32 y)
+{
+ u32 retval;
+
+ retval = *x % y;
+
+ *x /= y;
+
+ return retval;
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | errors.c |
+ | |
+ | The error handling functions for wm-FPU-emu |
+ | |
+ | Copyright (C) 1992,1993,1994,1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+#include <linux/signal.h>
+#include <asm/uaccess.h>
+#include <stdio.h>
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "reg_constant.h"
+#include "version.h"
+
+/* */
+#undef PRINT_MESSAGES
+/* */
+
+
+#ifndef USE_WITH_CPU_SIM
+void Un_impl(void)
+{
+ u_char byte1, FPU_modrm;
+ u32 address = FPU_ORIG_EIP;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* No need to verify_area(), we have previously fetched these bytes. */
+ printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
+ if ( FPU_CS == __USER_CS )
+ {
+ while ( 1 )
+ {
+ FPU_get_user(byte1, (u_char *) address);
+ if ( (byte1 & 0xf8) == 0xd8 ) break;
+ printk("[%02x]", byte1);
+ address++;
+ }
+ printk("%02x ", byte1);
+ FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+
+ if (FPU_modrm >= 0300)
+ printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+ else
+ printk("/%d\n", (FPU_modrm >> 3) & 7);
+ }
+ else
+ {
+ printk("cs selector = %04x\n", FPU_CS);
+ }
+
+ RE_ENTRANT_CHECK_ON;
+
+ EXCEPTION(EX_Invalid);
+
+}
+#endif
+
+
+/*
+ Called for opcodes which are illegal and which are known to result in a
+ SIGILL with a real 80486.
+ */
+void FPU_illegal(void)
+{
+ math_abort(FPU_info,SIGILL);
+}
+
+
+
+#ifndef USE_WITH_CPU_SIM
+void FPU_printall(void)
+{
+ int i;
+ static const char *tag_desc[] = { "Valid", "Zero", "ERROR", "Empty",
+ "DeNorm", "Inf", "NaN" };
+ u_char byte1, FPU_modrm;
+ u32 address = FPU_ORIG_EIP;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* No need to verify_area(), we have previously fetched these bytes. */
+ printk("At %p:", (void *) address);
+ if ( FPU_CS == __USER_CS )
+ {
+#define MAX_PRINTED_BYTES 20
+ for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
+ {
+ FPU_get_user(byte1, (u_char *) address);
+ if ( (byte1 & 0xf8) == 0xd8 )
+ {
+ printk(" %02x", byte1);
+ break;
+ }
+ printk(" [%02x]", byte1);
+ address++;
+ }
+ if ( i == MAX_PRINTED_BYTES )
+ printk(" [more..]\n");
+ else
+ {
+ FPU_get_user(FPU_modrm, 1 + (u_char *) address);
+
+ if (FPU_modrm >= 0300)
+ printk(" %02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
+ else
+ printk(" /%d, mod=%d rm=%d\n",
+ (FPU_modrm >> 3) & 7, (FPU_modrm >> 6) & 3, FPU_modrm & 7);
+ }
+ }
+ else
+ {
+ printk("%04x\n", FPU_CS);
+ }
+
+ partial_status = status_word();
+
+
+ printk(" SW: b=%d st=%ld es=%d sf=%d cc=%d%d%d%d ef=%d%d%d%d%d%d\n",
+ partial_status & 0x8000 ? 1 : 0, /* busy */
+ (partial_status & 0x3800) >> 11, /* stack top pointer */
+ partial_status & 0x80 ? 1 : 0, /* Error summary status */
+ partial_status & 0x40 ? 1 : 0, /* Stack flag */
+ partial_status & SW_C3?1:0, partial_status & SW_C2?1:0, /* cc */
+ partial_status & SW_C1?1:0, partial_status & SW_C0?1:0, /* cc */
+ partial_status & SW_Precision?1:0, partial_status & SW_Underflow?1:0,
+ partial_status & SW_Overflow?1:0, partial_status & SW_Zero_Div?1:0,
+ partial_status & SW_Denorm_Op?1:0, partial_status & SW_Invalid?1:0);
+
+printk(" CW: ic=%d rc=%ld%ld pc=%ld%ld iem=%d ef=%d%d%d%d%d%d\n",
+ control_word & 0x1000 ? 1 : 0,
+ (control_word & 0x800) >> 11, (control_word & 0x400) >> 10,
+ (control_word & 0x200) >> 9, (control_word & 0x100) >> 8,
+ control_word & 0x80 ? 1 : 0,
+ control_word & SW_Precision?1:0, control_word & SW_Underflow?1:0,
+ control_word & SW_Overflow?1:0, control_word & SW_Zero_Div?1:0,
+ control_word & SW_Denorm_Op?1:0, control_word & SW_Invalid?1:0);
+
+ for ( i = 0; i < 8; i++ )
+ {
+ FPU_REG *r = &st(i);
+ u_char tagi = FPU_gettagi(i);
+ switch (tagi)
+ {
+ case TAG_Empty:
+ continue;
+ break;
+ case TAG_Zero:
+ case TAG_Special:
+ tagi = FPU_Special(r);
+ case TAG_Valid:
+ printk("st(%d) %c .%04lx %04lx %04lx %04lx e%+-6d ", i,
+ getsign(r) ? '-' : '+',
+ (s32)(r->sigh >> 16),
+ (s32)(r->sigh & 0xFFFF),
+ (s32)(r->sigl >> 16),
+ (s32)(r->sigl & 0xFFFF),
+ exponent(r) - EXP_BIAS + 1);
+ break;
+ default:
+ printk("Whoops! Error in errors.c: tag%d is %d ", i, tagi);
+ continue;
+ break;
+ }
+ printk("%s\n", tag_desc[(int) (unsigned) tagi]);
+ }
+
+ RE_ENTRANT_CHECK_ON;
+
+}
+#endif
+
+static struct {
+ int type;
+ const char *name;
+} exception_names[] = {
+ { EX_StackOver, "stack overflow" },
+ { EX_StackUnder, "stack underflow" },
+ { EX_Precision, "loss of precision" },
+ { EX_Underflow, "underflow" },
+ { EX_Overflow, "overflow" },
+ { EX_ZeroDiv, "divide by zero" },
+ { EX_Denormal, "denormalized operand" },
+ { EX_Invalid, "invalid operation" },
+ { EX_INTERNAL, "INTERNAL BUG in "FPU_VERSION },
+ { 0, NULL }
+};
+
+/*
+ EX_INTERNAL is always given with a code which indicates where the
+ error was detected.
+
+ Internal error types:
+ 0x14 in fpu_etc.c
+ 0x1nn in a *.c file:
+ 0x101 in reg_add_sub.c
+ 0x102 in reg_mul.c
+ 0x104 in poly_atan.c
+ 0x105 in reg_mul.c
+ 0x107 in fpu_trig.c
+ 0x108 in reg_compare.c
+ 0x109 in reg_compare.c
+ 0x110 in reg_add_sub.c
+ 0x111 in fpe_entry.c
+ 0x112 in fpu_trig.c
+ 0x113 in errors.c
+ 0x115 in fpu_trig.c
+ 0x116 in fpu_trig.c
+ 0x117 in fpu_trig.c
+ 0x118 in fpu_trig.c
+ 0x119 in fpu_trig.c
+ 0x120 in poly_atan.c
+ 0x121 in reg_compare.c
+ 0x122 in reg_compare.c
+ 0x123 in reg_compare.c
+ 0x125 in fpu_trig.c
+ 0x126 in fpu_entry.c
+ 0x127 in poly_2xm1.c
+ 0x128 in fpu_entry.c
+ 0x129 in fpu_entry.c
+ 0x130 in get_address.c
+ 0x131 in get_address.c
+ 0x132 in get_address.c
+ 0x133 in get_address.c
+ 0x140 in load_store.c
+ 0x141 in load_store.c
+ 0x150 in poly_sin.c
+ 0x151 in poly_sin.c
+ 0x160 in reg_ld_str.c
+ 0x161 in reg_ld_str.c
+ 0x162 in reg_ld_str.c
+ 0x163 in reg_ld_str.c
+ 0x164 in reg_ld_str.c
+ 0x170 in fpu_tags.c
+ 0x171 in fpu_tags.c
+ 0x172 in fpu_tags.c
+ 0x180 in reg_convert.c
+ 0x2nn in an *.S file:
+ 0x201 in reg_u_add.S
+ 0x202 in reg_u_div.S
+ 0x203 in reg_u_div.S
+ 0x204 in reg_u_div.S
+ 0x205 in reg_u_mul.S
+ 0x206 in reg_u_sub.S
+ 0x207 in wm_sqrt.S
+ 0x208 in reg_div.S
+ 0x209 in reg_u_sub.S
+ 0x210 in reg_u_sub.S
+ 0x211 in reg_u_sub.S
+ 0x212 in reg_u_sub.S
+ 0x213 in wm_sqrt.S
+ 0x214 in wm_sqrt.S
+ 0x215 in wm_sqrt.S
+ 0x220 in reg_norm.S
+ 0x221 in reg_norm.S
+ 0x230 in reg_round.S
+ 0x231 in reg_round.S
+ 0x232 in reg_round.S
+ 0x233 in reg_round.S
+ 0x234 in reg_round.S
+ 0x235 in reg_round.S
+ 0x236 in reg_round.S
+ 0x240 in div_Xsig.S
+ 0x241 in div_Xsig.S
+ 0x242 in div_Xsig.S
+ */
+
+void FPU_exception(int n)
+{
+ int i, int_type;
+
+ int_type = 0; /* Needed only to stop compiler warnings */
+ if ( n & EX_INTERNAL )
+ {
+ int_type = n - EX_INTERNAL;
+ n = EX_INTERNAL;
+ /* Set lots of exception bits! */
+ partial_status |= (SW_Exc_Mask | SW_Summary | SW_Backward);
+ }
+ else
+ {
+ /* Extract only the bits which we use to set the status word */
+ n &= (SW_Exc_Mask);
+ /* Set the corresponding exception bit */
+ partial_status |= n;
+ /* Set summary bits iff exception isn't masked */
+ if ( partial_status & ~control_word & CW_Exceptions )
+ partial_status |= (SW_Summary | SW_Backward);
+ if ( n & (SW_Stack_Fault | EX_Precision) )
+ {
+ if ( !(n & SW_C1) )
+ /* This bit distinguishes over- from underflow for a stack fault,
+ and roundup from round-down for precision loss. */
+ partial_status &= ~SW_C1;
+ }
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ if ( (~control_word & n & CW_Exceptions) || (n == EX_INTERNAL) )
+ {
+#ifdef PRINT_MESSAGES
+ /* My message from the sponsor */
+ printk(FPU_VERSION" "__DATE__" (C) W. Metzenthen.\n");
+#endif /* PRINT_MESSAGES */
+
+ /* Get a name string for error reporting */
+ for (i=0; exception_names[i].type; i++)
+ if ( (exception_names[i].type & n) == exception_names[i].type )
+ break;
+
+ if (exception_names[i].type)
+ {
+#ifdef PRINT_MESSAGES
+ printk("FP Exception: %s!\n", exception_names[i].name);
+#endif /* PRINT_MESSAGES */
+ }
+ else
+ printk("FPU emulator: Unknown Exception: 0x%04x!\n", n);
+
+ if ( n == EX_INTERNAL )
+ {
+ printk("FPU emulator: Internal error type 0x%04x\n", int_type);
+ FPU_printall();
+ }
+#ifdef PRINT_MESSAGES
+ else
+ FPU_printall();
+#endif /* PRINT_MESSAGES */
+
+ /*
+ * The 80486 generates an interrupt on the next non-control FPU
+ * instruction. So we need some means of flagging it.
+ * We use the ES (Error Summary) bit for this.
+ */
+ }
+ RE_ENTRANT_CHECK_ON;
+
+
+}
+
+
+/* Real operation attempted on a NaN. */
+/* Returns < 0 if the exception is unmasked */
+int real_1op_NaN(FPU_REG *a)
+{
+ int signalling, isNaN;
+
+ isNaN = (exponent(a) == EXP_OVER) && (a->sigh & 0x80000000);
+
+ /* The default result for the case of two "equal" NaNs (signs may
+ differ) is chosen to reproduce 80486 behaviour */
+ signalling = isNaN && !(a->sigh & 0x40000000);
+
+ if ( !signalling )
+ {
+ if ( !isNaN ) /* pseudo-NaN, or other unsupported? */
+ {
+ if ( control_word & CW_Invalid )
+ {
+ /* Masked response */
+ reg_copy(&CONST_QNaN, a);
+ }
+ EXCEPTION(EX_Invalid);
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+ }
+ return TAG_Special;
+ }
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ if ( !(a->sigh & 0x80000000) ) /* pseudo-NaN ? */
+ {
+ reg_copy(&CONST_QNaN, a);
+ }
+ /* ensure a Quiet NaN */
+ a->sigh |= 0x40000000;
+ }
+
+ EXCEPTION(EX_Invalid);
+
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+}
+
+
+/* Real operation attempted on two operands, one a NaN. */
+/* Returns < 0 if the exception is unmasked */
+int real_2op_NaN(FPU_REG const *b, u_char tagb,
+ int deststnr,
+ FPU_REG const *defaultNaN)
+{
+ FPU_REG *dest = &st(deststnr);
+ FPU_REG const *a = dest;
+ u_char taga = FPU_gettagi(deststnr);
+ FPU_REG const *x;
+ int signalling, unsupported;
+
+ if ( taga == TAG_Special )
+ taga = FPU_Special(a);
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+
+ /* TW_NaN is also used for unsupported data types. */
+ unsupported = ((taga == TW_NaN)
+ && !((exponent(a) == EXP_OVER) && (a->sigh & 0x80000000)))
+ || ((tagb == TW_NaN)
+ && !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)));
+ if ( unsupported )
+ {
+ if ( control_word & CW_Invalid )
+ {
+ /* Masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+ }
+ EXCEPTION(EX_Invalid);
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+ }
+
+ if (taga == TW_NaN)
+ {
+ x = a;
+ if (tagb == TW_NaN)
+ {
+ signalling = !(a->sigh & b->sigh & 0x40000000);
+ if ( significand(b) > significand(a) )
+ x = b;
+ else if ( significand(b) == significand(a) )
+ {
+ /* The default result for the case of two "equal" NaNs (signs may
+ differ) is chosen to reproduce 80486 behaviour */
+ x = defaultNaN;
+ }
+ }
+ else
+ {
+ /* return the quiet version of the NaN in a */
+ signalling = !(a->sigh & 0x40000000);
+ }
+ }
+ else
+#ifdef PARANOID
+ if (tagb == TW_NaN)
+#endif /* PARANOID */
+ {
+ signalling = !(b->sigh & 0x40000000);
+ x = b;
+ }
+#ifdef PARANOID
+ else
+ {
+ signalling = 0;
+ EXCEPTION(EX_INTERNAL|0x113);
+ x = &CONST_QNaN;
+ }
+#endif /* PARANOID */
+
+ if ( (!signalling) || (control_word & CW_Invalid) )
+ {
+ if ( ! x )
+ x = b;
+
+ if ( !(x->sigh & 0x80000000) ) /* pseudo-NaN ? */
+ x = &CONST_QNaN;
+
+ FPU_copy_to_regi(x, TAG_Special, deststnr);
+
+ if ( !signalling )
+ return TAG_Special;
+
+ /* ensure a Quiet NaN */
+ dest->sigh |= 0x40000000;
+ }
+
+ EXCEPTION(EX_Invalid);
+
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Special;
+}
+
+
+/* Invalid arith operation on Valid registers */
+/* Returns < 0 if the exception is unmasked */
+asmlinkage int arith_invalid(int deststnr)
+{
+
+ EXCEPTION(EX_Invalid);
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, deststnr);
+ }
+
+ return (!(control_word & CW_Invalid) ? FPU_Exception : 0) | TAG_Valid;
+
+}
+
+
+/* Divide a finite number by zero */
+asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign)
+{
+ FPU_REG *dest = &st(deststnr);
+ int tag = TAG_Valid;
+
+ if ( control_word & CW_ZeroDiv )
+ {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_INF, TAG_Special, deststnr);
+ setsign(dest, sign);
+ tag = TAG_Special;
+ }
+
+ EXCEPTION(EX_ZeroDiv);
+
+ return (!(control_word & CW_ZeroDiv) ? FPU_Exception : 0) | tag;
+
+}
+
+
+/* This may be called often, so keep it lean */
+int set_precision_flag(int flags)
+{
+ if ( control_word & CW_Precision )
+ {
+ partial_status &= ~(SW_C1 & flags);
+ partial_status |= flags; /* The masked response */
+ return 0;
+ }
+ else
+ {
+ EXCEPTION(flags);
+ return 1;
+ }
+}
+
+
+/* This may be called often, so keep it lean */
+asmlinkage void set_precision_flag_up(void)
+{
+ if ( control_word & CW_Precision )
+ partial_status |= (SW_Precision | SW_C1); /* The masked response */
+ else
+ EXCEPTION(EX_Precision | SW_C1);
+}
+
+
+/* This may be called often, so keep it lean */
+asmlinkage void set_precision_flag_down(void)
+{
+ if ( control_word & CW_Precision )
+ { /* The masked response */
+ partial_status &= ~SW_C1;
+ partial_status |= SW_Precision;
+ }
+ else
+ EXCEPTION(EX_Precision);
+}
+
+
+asmlinkage int denormal_operand(void)
+{
+ if ( control_word & CW_Denormal )
+ { /* The masked response */
+ partial_status |= SW_Denorm_Op;
+ return TAG_Special;
+ }
+ else
+ {
+ EXCEPTION(EX_Denormal);
+ return TAG_Special | FPU_Exception;
+ }
+}
+
+
+asmlinkage int arith_overflow(FPU_REG *dest)
+{
+ int tag = TAG_Valid;
+
+ if ( control_word & CW_Overflow )
+ {
+ /* The masked response */
+ reg_copy(&CONST_INF, dest);
+ tag = TAG_Special;
+ }
+ else
+ {
+ /* Subtract the magic number from the exponent */
+ addexponent(dest, (-3 * (1 << 13)));
+ }
+
+ EXCEPTION(EX_Overflow);
+ if ( control_word & CW_Overflow )
+ {
+ /* The overflow exception is masked. */
+ /* By definition, precision is lost.
+ The roundup bit (C1) is also set because we have
+ "rounded" upwards to Infinity. */
+ EXCEPTION(EX_Precision | SW_C1);
+ return tag;
+ }
+
+ return tag;
+
+}
+
+
+asmlinkage int arith_round_overflow(FPU_REG *dest, u8 sign)
+{
+ int tag = TAG_Valid;
+ int largest;
+
+ if ( control_word & CW_Overflow )
+ {
+ /* The masked response */
+ /* The response here depends upon the rounding mode */
+ switch ( control_word & CW_RC )
+ {
+ case RC_CHOP: /* Truncate */
+ largest = 1;
+ break;
+ case RC_UP: /* Towards +infinity */
+ largest = (sign == SIGN_NEG);
+ break;
+ case RC_DOWN: /* Towards -infinity */
+ largest = (sign == SIGN_POS);
+ break;
+ default:
+ largest = 0;
+ break;
+ }
+ if ( ! largest )
+ {
+ reg_copy(&CONST_INF, dest);
+ tag = TAG_Special;
+ }
+ else
+ {
+ dest->exp = EXTENDED_Ebias+EXP_OVER-1;
+ switch ( control_word & CW_PC )
+ {
+ case 01:
+ case PR_64_BITS:
+ significand(dest) = BX_CONST64(0xffffffffffffffff);
+ break;
+ case PR_53_BITS:
+ significand(dest) = BX_CONST64(0xfffffffffffff800);
+ break;
+ case PR_24_BITS:
+ significand(dest) = BX_CONST64(0xffffff0000000000);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Subtract the magic number from the exponent */
+ addexponent(dest, (-3 * (1 << 13)));
+ largest = 0;
+ }
+
+ EXCEPTION(EX_Overflow);
+ if ( control_word & CW_Overflow )
+ {
+ /* The overflow exception is masked. */
+ if ( largest )
+ {
+ EXCEPTION(EX_Precision);
+ }
+ else
+ {
+ /* By definition, precision is lost.
+ The roundup bit (C1) is also set because we have
+ "rounded" upwards to Infinity. */
+ EXCEPTION(EX_Precision | SW_C1);
+ }
+ return tag;
+ }
+
+ return tag;
+
+}
+
+
+asmlinkage int arith_underflow(FPU_REG *dest)
+{
+ int tag = TAG_Valid;
+
+ if ( control_word & CW_Underflow )
+ {
+ /* The masked response */
+ if ( exponent16(dest) <= EXP_UNDER - 63 )
+ {
+ reg_copy(&CONST_Z, dest);
+ partial_status &= ~SW_C1; /* Round down. */
+ tag = TAG_Zero;
+ }
+ else
+ {
+ stdexp(dest);
+ }
+ }
+ else
+ {
+ /* Add the magic number to the exponent. */
+ addexponent(dest, (3 * (1 << 13)) + EXTENDED_Ebias);
+ }
+
+ EXCEPTION(EX_Underflow);
+ if ( control_word & CW_Underflow )
+ {
+ /* The underflow exception is masked. */
+ EXCEPTION(EX_Precision);
+ return tag;
+ }
+
+ return tag;
+
+}
+
+
+void FPU_stack_overflow(void)
+{
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ top--;
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
+
+ EXCEPTION(EX_StackOver);
+
+ return;
+
+}
+
+
+void FPU_stack_underflow(void)
+{
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
+
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
+
+
+void FPU_stack_underflow_i(int i)
+{
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+ }
+
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
+
+
+void FPU_stack_underflow_pop(int i)
+{
+
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_copy_to_regi(&CONST_QNaN, TAG_Special, i);
+ FPU_pop();
+ }
+
+ EXCEPTION(EX_StackUnder);
+
+ return;
+
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | exception.h |
+ | |
+ | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+
+#ifdef __ASSEMBLY__
+#define Const_(x) $##x
+#else
+#define Const_(x) x
+#endif
+
+#ifndef SW_C1
+#include "fpu_emu.h"
+#endif /* SW_C1 */
+
+#define FPU_BUSY Const_(0x8000) /* FPU busy bit (8087 compatibility) */
+#define EX_ErrorSummary Const_(0x0080) /* Error summary status */
+/* Special exceptions: */
+#define EX_INTERNAL Const_(0x8000) /* Internal error in wm-FPU-emu */
+#define EX_StackOver Const_(0x0041|SW_C1) /* stack overflow */
+#define EX_StackUnder Const_(0x0041) /* stack underflow */
+/* Exception flags: */
+#define EX_Precision Const_(0x0020) /* loss of precision */
+#define EX_Underflow Const_(0x0010) /* underflow */
+#define EX_Overflow Const_(0x0008) /* overflow */
+#define EX_ZeroDiv Const_(0x0004) /* divide by zero */
+#define EX_Denormal Const_(0x0002) /* denormalized operand */
+#define EX_Invalid Const_(0x0001) /* invalid operation */
+
+
+#define PRECISION_LOST_UP Const_((EX_Precision | SW_C1))
+#define PRECISION_LOST_DOWN Const_(EX_Precision)
+
+
+#ifndef __ASSEMBLY__
+
+#define EXCEPTION(x) FPU_exception(x)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _EXCEPTION_H_ */
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+#include "bochs.h"
+
+#define LOG_THIS genlog->
+
+// Nomenclature used to signify argument types
+//
+// Es = single real
+// El = double real
+// Ea = 14/28 bytes 98/108b bytes (FRSTOR,FSAVE)???
+// Ew = word integer (2 bytes)
+// Ed = dword integer (4 bytes) (short int)
+// Et = extended real
+// Eb = packed BCD
+// Eq = quadword integer (8 bytes) (long integer)
+
+
+
+ void
+BX_CPU_C::ESC0(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC0 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC1(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC1 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC2(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC2 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC3(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+
+//BX_DEBUG(( "CS:EIP = %04x:%08x\n",
+// BX_CPU.sregs[BX_SEG_REG_CS].selector.value, BX_CPU.prev_eip));
+
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC3 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC4(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC4 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC5(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC5 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC6(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC6 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::ESC7(BxInstruction_t *i)
+{
+ if ( BX_CPU_THIS_PTR cr0.em || BX_CPU_THIS_PTR cr0.ts ) {
+ exception(BX_NM_EXCEPTION, 0, 0);
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("ESC7 not implemented\n"));
+#endif
+}
+
+ void
+BX_CPU_C::FWAIT(BxInstruction_t *i)
+{
+#if BX_CPU_LEVEL < 3
+ // WAIT doesn't generate single steps on 8086.
+ // The same goes for prefix instructions, and instructions which
+ // modify segment registers. (pg4-16)
+ // single_step_event = 0;
+ BX_PANIC(("WAIT: not implemented for < 386\n"));
+#else // BX_CPU_LEVEL >= 3
+
+ if ( BX_CPU_THIS_PTR cr0.ts && BX_CPU_THIS_PTR cr0.mp ) {
+ exception(BX_NM_EXCEPTION, 0, 0); // no error
+ }
+#if BX_SUPPORT_FPU
+ fpu_execute(i);
+#else
+ BX_INFO(("FWAIT: no FPU\n"));
+#endif
+
+#endif
+}
+
+
+#if BX_SUPPORT_FPU==0
+ // if supporting FPU, this function in glue logic file
+ void
+BX_CPU_C::fpu_init(void)
+{
+}
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_arith.c |
+ | |
+ | Code to implement the FPU register/register arithmetic instructions |
+ | |
+ | Copyright (C) 1992,1993,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+void fadd__()
+{
+ /* fadd st,st(i) */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_add(&st(i), FPU_gettagi(i), 0, control_word);
+}
+
+
+void fmul__()
+{
+ /* fmul st,st(i) */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_mul(&st(i), FPU_gettagi(i), 0, control_word);
+}
+
+
+
+void fsub__()
+{
+ /* fsub st,st(i) */
+ clear_C1();
+ FPU_sub(0, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fsubr_()
+{
+ /* fsubr st,st(i) */
+ clear_C1();
+ FPU_sub(REV, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdiv__()
+{
+ /* fdiv st,st(i) */
+ clear_C1();
+ FPU_div(0, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdivr_()
+{
+ /* fdivr st,st(i) */
+ clear_C1();
+ FPU_div(REV, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+
+void fadd_i()
+{
+ /* fadd st(i),st */
+ int i = FPU_rm;
+ clear_C1();
+ FPU_add(&st(i), FPU_gettagi(i), i, control_word);
+}
+
+
+void fmul_i()
+{
+ /* fmul st(i),st */
+ clear_C1();
+ FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word);
+}
+
+
+void fsubri()
+{
+ /* fsubr st(i),st */
+ clear_C1();
+ FPU_sub(DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fsub_i()
+{
+ /* fsub st(i),st */
+ clear_C1();
+ FPU_sub(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdivri()
+{
+ /* fdivr st(i),st */
+ clear_C1();
+ FPU_div(DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+void fdiv_i()
+{
+ /* fdiv st(i),st */
+ clear_C1();
+ FPU_div(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word);
+}
+
+
+
+void faddp_()
+{
+ /* faddp st(i),st */
+ int i = FPU_rm;
+ clear_C1();
+ if ( FPU_add(&st(i), FPU_gettagi(i), i, control_word) >= 0 )
+ FPU_pop();
+}
+
+
+void fmulp_()
+{
+ /* fmulp st(i),st */
+ clear_C1();
+ if ( FPU_mul(&st(0), FPU_gettag0(), FPU_rm, control_word) >= 0 )
+ FPU_pop();
+}
+
+
+
+void fsubrp()
+{
+ /* fsubrp st(i),st */
+ clear_C1();
+ if ( FPU_sub(DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+ FPU_pop();
+}
+
+
+void fsubp_()
+{
+ /* fsubp st(i),st */
+ clear_C1();
+ if ( FPU_sub(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+ FPU_pop();
+}
+
+
+void fdivrp()
+{
+ /* fdivrp st(i),st */
+ clear_C1();
+ if ( FPU_div(DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+ FPU_pop();
+}
+
+
+void fdivp_()
+{
+ /* fdivp st(i),st */
+ clear_C1();
+ if ( FPU_div(REV|DEST_RM, REGNO2PTR(FPU_rm), control_word) >= 0 )
+ FPU_pop();
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_asm.h |
+ | |
+ | Copyright (C) 1992,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _FPU_ASM_H_
+#define _FPU_ASM_H_
+
+#include <linux/linkage.h>
+
+#define EXCEPTION SYMBOL_NAME(FPU_exception)
+
+
+#define PARAM1 8(%ebp)
+#define PARAM2 12(%ebp)
+#define PARAM3 16(%ebp)
+#define PARAM4 20(%ebp)
+#define PARAM5 24(%ebp)
+#define PARAM6 28(%ebp)
+#define PARAM7 32(%ebp)
+
+#define SIGL_OFFSET 0
+#define EXP(x) 8(x)
+#define SIG(x) SIGL_OFFSET##(x)
+#define SIGL(x) SIGL_OFFSET##(x)
+#define SIGH(x) 4(x)
+
+#endif /* _FPU_ASM_H_ */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_aux.c |
+ | |
+ | Code to implement some of the FPU auxiliary instructions. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+
+
+static void fnop(void)
+{
+}
+
+void fclex(void)
+{
+ partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
+ SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
+ SW_Invalid);
+ no_ip_update = 1;
+}
+
+/* Needs to be externally visible */
+void finit()
+{
+ control_word = 0x037f;
+ partial_status = 0;
+ top = 0; /* We don't keep top in the status word internally. */
+ fpu_tag_word = 0xffff;
+ /* The behaviour is different from that detailed in
+ Section 15.1.6 of the Intel manual */
+ operand_address.offset = 0;
+ operand_address.selector = 0;
+ instruction_address.offset = 0;
+ instruction_address.selector = 0;
+ instruction_address.opcode = 0;
+ no_ip_update = 1;
+}
+
+/*
+ * These are nops on the i387..
+ */
+#define feni fnop
+#define fdisi fnop
+#define fsetpm fnop
+
+static FUNC const finit_table[] = {
+ feni, fdisi, fclex, finit,
+ fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void finit_()
+{
+ (finit_table[FPU_rm])();
+}
+
+
+static void fstsw_ax(void)
+{
+ SET_AX(status_word()); // KPL
+ no_ip_update = 1;
+}
+
+static FUNC const fstsw_table[] = {
+ fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
+ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void fstsw_()
+{
+ (fstsw_table[FPU_rm])();
+}
+
+
+static FUNC const fp_nop_table[] = {
+ fnop, FPU_illegal, FPU_illegal, FPU_illegal,
+ FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
+};
+
+void fp_nop()
+{
+ (fp_nop_table[FPU_rm])();
+}
+
+
+void fld_i_()
+{
+ FPU_REG *st_new_ptr;
+ int i;
+ u_char tag;
+
+ if ( STACK_OVERFLOW )
+ { FPU_stack_overflow(); return; }
+
+ /* fld st(i) */
+ i = FPU_rm;
+ if ( NOT_EMPTY(i) )
+ {
+ reg_copy(&st(i), st_new_ptr);
+ tag = FPU_gettagi(i);
+ push();
+ FPU_settag0(tag);
+ }
+ else
+ {
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_stack_underflow();
+ }
+ else
+ EXCEPTION(EX_StackUnder);
+ }
+
+}
+
+
+void fxch_i()
+{
+ /* fxch st(i) */
+ FPU_REG t;
+ int i = FPU_rm;
+ FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
+ s32 tag_word = fpu_tag_word;
+ int regnr = top & 7, regnri = ((regnr + i) & 7);
+ u_char st0_tag = (tag_word >> (regnr*2)) & 3;
+ u_char sti_tag = (tag_word >> (regnri*2)) & 3;
+
+ if ( st0_tag == TAG_Empty )
+ {
+ if ( sti_tag == TAG_Empty )
+ {
+ FPU_stack_underflow();
+ FPU_stack_underflow_i(i);
+ return;
+ }
+ if ( control_word & CW_Invalid )
+ {
+ /* Masked response */
+ FPU_copy_to_reg0(sti_ptr, sti_tag);
+ }
+ FPU_stack_underflow_i(i);
+ return;
+ }
+ if ( sti_tag == TAG_Empty )
+ {
+ if ( control_word & CW_Invalid )
+ {
+ /* Masked response */
+ FPU_copy_to_regi(st0_ptr, st0_tag, i);
+ }
+ FPU_stack_underflow();
+ return;
+ }
+ clear_C1();
+
+ reg_copy(st0_ptr, &t);
+ reg_copy(sti_ptr, st0_ptr);
+ reg_copy(&t, sti_ptr);
+
+ tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
+ tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
+ fpu_tag_word = tag_word;
+}
+
+
+void ffree_()
+{
+ /* ffree st(i) */
+ FPU_settagi(FPU_rm, TAG_Empty);
+}
+
+
+void ffreep()
+{
+ /* ffree st(i) + pop - unofficial code */
+ FPU_settagi(FPU_rm, TAG_Empty);
+ FPU_pop();
+}
+
+
+void fst_i_()
+{
+ /* fst st(i) */
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+}
+
+
+void fstp_i()
+{
+ /* fstp st(i) */
+ FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
+ FPU_pop();
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_emu.h |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+#ifndef _FPU_EMU_H_
+#define _FPU_EMU_H_
+
+/*
+ * Define PECULIAR_486 to get a closer approximation to 80486 behaviour,
+ * rather than behaviour which appears to be cleaner.
+ * This is a matter of opinion: for all I know, the 80486 may simply
+ * be complying with the IEEE spec. Maybe one day I'll get to see the
+ * spec...
+ */
+#define PECULIAR_486
+
+// change a pointer to an int, with type conversions that make it legal.
+// On machines with 64-bit pointers, compilers complain when you typecast
+// a 64-bit pointer into a 32-bit integer.
+#define PTR2INT(x) ((bx_ptr_equiv_t)(void *)(x))
+
+#ifdef __ASSEMBLY__
+#include "fpu_asm.h"
+#define Const(x) $##x
+#else
+#include <asm/types.h>
+#define Const(x) x
+#endif
+
+#define EXP_BIAS Const(0)
+#define EXP_OVER Const(0x4000) /* smallest invalid large exponent */
+#define EXP_UNDER Const(-0x3fff) /* largest invalid small exponent */
+#define EXP_WAY_UNDER Const(-0x6000) /* Below the smallest denormal, but
+ still a 16 bit nr. */
+#define EXP_Infinity EXP_OVER
+#define EXP_NaN EXP_OVER
+
+#define EXTENDED_Ebias Const(0x3fff)
+#define EXTENDED_Emin (-0x3ffe) /* smallest valid exponent */
+
+#define SIGN_POS Const(0)
+#define SIGN_NEG Const(0x80)
+
+#define SIGN_Positive Const(0)
+#define SIGN_Negative Const(0x8000)
+
+
+/* Keep the order TAG_Valid, TAG_Zero, TW_Denormal */
+/* The following fold to 2 (Special) in the Tag Word */
+#define TW_Denormal Const(4) /* De-normal */
+#define TW_Infinity Const(5) /* + or - infinity */
+#define TW_NaN Const(6) /* Not a Number */
+#define TW_Unsupported Const(7) /* Not supported by an 80486 */
+
+#define TAG_Valid Const(0) /* valid */
+#define TAG_Zero Const(1) /* zero */
+#define TAG_Special Const(2) /* De-normal, + or - infinity,
+ or Not a Number */
+#define TAG_Empty Const(3) /* empty */
+
+#define LOADED_DATA Const(10101) /* Special st() number to identify
+ loaded data (not on stack). */
+
+/* A few flags (must be >= 0x10). */
+#define REV 0x10
+#define DEST_RM 0x20
+#define LOADED 0x40
+
+#define FPU_Exception Const(0x80000000) /* Added to tag returns. */
+
+
+#ifndef __ASSEMBLY__
+
+#include "fpu_system.h"
+
+#include <asm/sigcontext.h> /* for struct _fpstate */
+#include <asm/math_emu.h>
+#include <linux/linkage.h>
+
+/*
+#define RE_ENTRANT_CHECKING
+ */
+
+#ifdef RE_ENTRANT_CHECKING
+extern u_char emulating;
+# define RE_ENTRANT_CHECK_OFF emulating = 0
+# define RE_ENTRANT_CHECK_ON emulating = 1
+#else
+# define RE_ENTRANT_CHECK_OFF
+# define RE_ENTRANT_CHECK_ON
+#endif /* ifdef RE_ENTRANT_CHECKING */
+
+#define FWAIT_OPCODE 0x9b
+#define OP_SIZE_PREFIX 0x66
+#define ADDR_SIZE_PREFIX 0x67
+#define PREFIX_CS 0x2e
+#define PREFIX_DS 0x3e
+#define PREFIX_ES 0x26
+#define PREFIX_SS 0x36
+#define PREFIX_FS 0x64
+#define PREFIX_GS 0x65
+#define PREFIX_REPE 0xf3
+#define PREFIX_REPNE 0xf2
+#define PREFIX_LOCK 0xf0
+#define PREFIX_CS_ 1
+#define PREFIX_DS_ 2
+#define PREFIX_ES_ 3
+#define PREFIX_FS_ 4
+#define PREFIX_GS_ 5
+#define PREFIX_SS_ 6
+#define PREFIX_DEFAULT 7
+
+struct address {
+ u32 offset;
+#ifdef EMU_BIG_ENDIAN
+ u32 empty:5;
+ u32 opcode:11;
+ u32 selector:16;
+#else
+ u32 selector:16;
+ u32 opcode:11;
+ u32 empty:5;
+#endif
+} GCC_ATTRIBUTE((packed));
+
+struct fpu__reg {
+#ifdef EMU_BIG_ENDIAN
+ u32 sigh;
+ u32 sigl;
+ s16 exp; /* Signed quantity used in internal arithmetic. */
+#else
+ u32 sigl;
+ u32 sigh;
+ s16 exp; /* Signed quantity used in internal arithmetic. */
+#endif
+} GCC_ATTRIBUTE((aligned(16), packed));
+
+#ifdef EMU_BIG_ENDIAN
+#define MAKE_REG(s,e,l,h) { h, l, \
+ ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
+#else
+#define MAKE_REG(s,e,l,h) { l, h, \
+ ((EXTENDED_Ebias+(e)) | ((SIGN_##s != 0)*0x8000)) }
+#endif
+
+typedef void (*FUNC)(void);
+typedef struct fpu__reg FPU_REG;
+typedef void (*FUNC_ST0)(FPU_REG *st0_ptr, u_char st0_tag);
+typedef struct { u_char address_size, operand_size, segment; }
+ GCC_ATTRIBUTE((packed)) overrides;
+/* This structure is 32 bits: */
+typedef struct { overrides override;
+ u_char default_mode; }
+ GCC_ATTRIBUTE((packed)) fpu_addr_modes;
+/* PROTECTED has a restricted meaning in the emulator; it is used
+ to signal that the emulator needs to do special things to ensure
+ that protection is respected in a segmented model. */
+#define PROTECTED 4
+#define SIXTEEN 1 /* We rely upon this being 1 (true) */
+#define VM86 SIXTEEN
+#define PM16 (SIXTEEN | PROTECTED)
+#define SEG32 PROTECTED
+extern u_char const data_sizes_16[32];
+
+#define register_base ((u_char *) registers )
+#define fpu_register(x) ( * ((FPU_REG *)( register_base + sizeof(FPU_REG) * (x & 7) )) )
+#define st(x) ( * ((FPU_REG *)( register_base + sizeof(FPU_REG) * ((top+x) & 7) )) )
+
+#define STACK_OVERFLOW (FPU_stackoverflow(&st_new_ptr))
+#define NOT_EMPTY(i) (!FPU_empty_i(i))
+
+#define NOT_EMPTY_ST0 (st0_tag ^ TAG_Empty)
+
+#define poppop() { FPU_pop(); FPU_pop(); }
+
+/* push() does not affect the tags */
+#define push() { top--; }
+
+#ifdef EMU_BIG_ENDIAN
+#define signbyte(a) (((u_char *)(a))[8])
+#else
+#define signbyte(a) (((u_char *)(a))[9])
+#endif
+#define getsign(a) (signbyte(a) & 0x80)
+#define setsign(a,b) { if (b) signbyte(a) |= 0x80; else signbyte(a) &= 0x7f; }
+#define copysign(a,b) { if (getsign(a)) signbyte(b) |= 0x80; \
+ else signbyte(b) &= 0x7f; }
+#define changesign(a) { signbyte(a) ^= 0x80; }
+#define setpositive(a) { signbyte(a) &= 0x7f; }
+#define setnegative(a) { signbyte(a) |= 0x80; }
+#define signpositive(a) ( (signbyte(a) & 0x80) == 0 )
+#define signnegative(a) (signbyte(a) & 0x80)
+
+#ifdef EMU_BIG_ENDIAN
+#define significand(x) ( ((u64 *)&((x)->sigh))[0] )
+#else
+#define significand(x) ( ((u64 *)&((x)->sigl))[0] )
+#endif
+
+BX_C_INLINE
+void reg_copy(FPU_REG const *x, FPU_REG *y)
+{
+ y->exp = x->exp;
+ significand(y) = significand(x);
+}
+
+#define exponent(x) (((x)->exp & 0x7fff) - EXTENDED_Ebias)
+#define setexponentpos(x,y) { (x)->exp = ((y) + EXTENDED_Ebias) & 0x7fff; }
+#define exponent16(x) (x)->exp
+#define setexponent16(x,y) { (x)->exp = (y); }
+#define addexponent(x,y) { (x)->exp += (y); }
+#define stdexp(x) { (x)->exp += EXTENDED_Ebias; }
+
+#define isdenormal(ptr) (exponent(ptr) == EXP_BIAS+EXP_UNDER)
+
+/*----- Prototypes for functions written in assembler -----*/
+/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
+
+asmlinkage int FPU_normalize_nuo(FPU_REG *x, int bias);
+asmlinkage int FPU_u_sub(FPU_REG const *arg1, FPU_REG const *arg2,
+ FPU_REG *answ, u16 control_w, u_char sign,
+ s32 expa, s32 expb);
+asmlinkage int FPU_u_mul(FPU_REG const *arg1, FPU_REG const *arg2,
+ FPU_REG *answ, u16 control_w, u_char sign,
+ s32 expon);
+asmlinkage int FPU_u_div(FPU_REG const *arg1, FPU_REG const *arg2,
+ FPU_REG *answ, u16 control_w, u_char sign);
+asmlinkage int FPU_u_add(FPU_REG const *arg1, FPU_REG const *arg2,
+ FPU_REG *answ, u16 control_w, u_char sign,
+ s32 expa, s32 expb);
+asmlinkage int wm_sqrt(FPU_REG *n, int dummy1, int dummy2,
+ u16 control_w, u_char sign);
+asmlinkage u32 FPU_shrx(void *l, u32 x);
+asmlinkage u32 FPU_shrxs(void *v, u32 x);
+asmlinkage u32 FPU_div_small(u64 *x, u32 y);
+asmlinkage int FPU_round(FPU_REG *arg, u32 extent, int dummy,
+ u16 control_w, u_char sign);
+
+#ifndef MAKING_PROTO
+#include "fpu_proto.h"
+#endif
+
+#endif /* defined __ASSEMBLY__ */
+
+#endif /* !defined _FPU_EMU_H_ */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_entry.c |
+ | |
+ | The entry functions for wm-FPU-emu |
+ | |
+ | Copyright (C) 1992,1993,1994,1996,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | See the files "README" and "COPYING" for further copyright and warranty |
+ | information. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | math_emulate(), restore_i387_soft() and save_i387_soft() are the only |
+ | entry points for wm-FPU-emu. |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+#include "status_w.h"
+
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+
+#define __BAD__ FPU_illegal /* Illegal on an 80486, causes SIGILL */
+
+#ifndef NO_UNDOC_CODE /* Un-documented FPU op-codes supported by default. */
+
+/* WARNING: These codes are not documented by Intel in their 80486 manual
+ and may not work on FPU clones or later Intel FPUs. */
+
+/* Changes to support the un-doc codes provided by Linus Torvalds. */
+
+#define _d9_d8_ fstp_i /* unofficial code (19) */
+#define _dc_d0_ fcom_st /* unofficial code (14) */
+#define _dc_d8_ fcompst /* unofficial code (1c) */
+#define _dd_c8_ fxch_i /* unofficial code (0d) */
+#define _de_d0_ fcompst /* unofficial code (16) */
+#define _df_c0_ ffreep /* unofficial code (07) ffree + pop */
+#define _df_c8_ fxch_i /* unofficial code (0f) */
+#define _df_d0_ fstp_i /* unofficial code (17) */
+#define _df_d8_ fstp_i /* unofficial code (1f) */
+
+static FUNC const st_instr_table[64] = {
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, _df_c0_,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, _dd_c8_, fmulp_, _df_c8_,
+ fcom_st, fp_nop, __BAD__, __BAD__, _dc_d0_, fst_i_, _de_d0_, _df_d0_,
+ fcompst, _d9_d8_, __BAD__, __BAD__, _dc_d8_, fstp_i, fcompp, _df_d8_,
+ fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+};
+
+#else /* Support only documented FPU op-codes */
+
+static FUNC const st_instr_table[64] = {
+ fadd__, fld_i_, __BAD__, __BAD__, fadd_i, ffree_, faddp_, __BAD__,
+ fmul__, fxch_i, __BAD__, __BAD__, fmul_i, __BAD__, fmulp_, __BAD__,
+ fcom_st, fp_nop, __BAD__, __BAD__, __BAD__, fst_i_, __BAD__, __BAD__,
+ fcompst, __BAD__, __BAD__, __BAD__, __BAD__, fstp_i, fcompp, __BAD__,
+ fsub__, FPU_etc, __BAD__, finit_, fsubri, fucom_, fsubrp, fstsw_,
+ fsubr_, fconst, fucompp, __BAD__, fsub_i, fucomp, fsubp_, __BAD__,
+ fdiv__, FPU_triga, __BAD__, __BAD__, fdivri, __BAD__, fdivrp, __BAD__,
+ fdivr_, FPU_trigb, __BAD__, __BAD__, fdiv_i, __BAD__, fdivp_, __BAD__,
+};
+
+#endif /* NO_UNDOC_CODE */
+
+
+#define _NONE_ 0 /* Take no special action */
+#define _REG0_ 1 /* Need to check for not empty st(0) */
+#define _REGI_ 2 /* Need to check for not empty st(0) and st(rm) */
+#define _REGi_ 0 /* Uses st(rm) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
+#define _REGIi 5 /* Uses st(0) and st(rm), result to st(rm) */
+#define _REGIp 6 /* Uses st(0) and st(rm), result to st(rm) then pop */
+#define _REGIc 0 /* Compare st(0) and st(rm) */
+#define _REGIn 0 /* Uses st(0) and st(rm), but handle checks later */
+
+#ifndef NO_UNDOC_CODE
+
+/* Un-documented FPU op-codes supported by default. (see above) */
+
+static u_char const type_table[64] = {
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _REGi_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _REGI_, _REGIp, _REGI_,
+ _REGIc, _NONE_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGIc, _REG0_, _null_, _null_, _REGIc, _REG0_, _REGIc, _REG0_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+
+#else /* Support only documented FPU op-codes */
+
+static u_char const type_table[64] = {
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _REGi_, _REGIp, _null_,
+ _REGI_, _REGIn, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGIc, _NONE_, _null_, _null_, _null_, _REG0_, _null_, _null_,
+ _REGIc, _null_, _null_, _null_, _null_, _REG0_, _REGIc, _null_,
+ _REGI_, _NONE_, _null_, _NONE_, _REGIi, _REGIc, _REGIp, _NONE_,
+ _REGI_, _NONE_, _REGIc, _null_, _REGIi, _REGIc, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_,
+ _REGI_, _NONE_, _null_, _null_, _REGIi, _null_, _REGIp, _null_
+};
+
+#endif /* NO_UNDOC_CODE */
+
+
+#ifndef USE_WITH_CPU_SIM
+
+
+#ifdef RE_ENTRANT_CHECKING
+u_char emulating=0;
+#endif /* RE_ENTRANT_CHECKING */
+
+static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+ overrides *override);
+
+asmlinkage void math_emulate(long arg)
+{
+ u_char FPU_modrm, byte1;
+ unsigned short code;
+ fpu_addr_modes addr_modes;
+ int unmasked;
+ FPU_REG loaded_data;
+ FPU_REG *st0_ptr;
+ u_char loaded_tag, st0_tag;
+ void *data_address;
+ struct address data_sel_off;
+ struct address entry_sel_off;
+ u32 code_base = 0;
+ u32 code_limit = 0; /* Initialized to stop compiler warnings */
+ struct desc_struct code_descriptor;
+
+#ifdef RE_ENTRANT_CHECKING
+ if ( emulating )
+ {
+ printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n");
+ }
+ RE_ENTRANT_CHECK_ON;
+#endif /* RE_ENTRANT_CHECKING */
+
+ if (!current->used_math)
+ {
+ finit();
+ current->used_math = 1;
+ }
+
+ SETUP_DATA_AREA(arg);
+
+ FPU_ORIG_EIP = FPU_EIP;
+
+ if ( (FPU_EFLAGS & 0x00020000) != 0 )
+ {
+ /* Virtual 8086 mode */
+ addr_modes.default_mode = VM86;
+ FPU_EIP += code_base = FPU_CS << 4;
+ code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
+ }
+ else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
+ {
+ addr_modes.default_mode = 0;
+ }
+ else if ( FPU_CS == __KERNEL_CS )
+ {
+ printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
+ panic("Math emulation needed in kernel");
+ }
+ else
+ {
+
+ if ( (FPU_CS & 4) != 4 ) /* Must be in the LDT */
+ {
+ /* Can only handle segmented addressing via the LDT
+ for now, and it must be 16 bit */
+ printk("FPU emulator: Unsupported addressing mode\n");
+ math_abort(FPU_info, SIGILL);
+ }
+
+ if ( SEG_D_SIZE(code_descriptor = LDT_DESCRIPTOR(FPU_CS)) )
+ {
+ /* The above test may be wrong, the book is not clear */
+ /* Segmented 32 bit protected mode */
+ addr_modes.default_mode = SEG32;
+ }
+ else
+ {
+ /* 16 bit protected mode */
+ addr_modes.default_mode = PM16;
+ }
+ FPU_EIP += code_base = SEG_BASE_ADDR(code_descriptor);
+ code_limit = code_base
+ + (SEG_LIMIT(code_descriptor)+1) * SEG_GRANULARITY(code_descriptor)
+ - 1;
+ if ( code_limit < code_base ) code_limit = 0xffffffff;
+ }
+
+ FPU_lookahead = 1;
+ if (current->flags & PF_PTRACED)
+ FPU_lookahead = 0;
+
+ if ( !valid_prefix(&byte1, (u_char **)&FPU_EIP,
+ &addr_modes.override) )
+ {
+ RE_ENTRANT_CHECK_OFF;
+ printk("FPU emulator: Unknown prefix byte 0x%02x, probably due to\n"
+ "FPU emulator: self-modifying code! (emulation impossible)\n",
+ byte1);
+ RE_ENTRANT_CHECK_ON;
+ EXCEPTION(EX_INTERNAL|0x126);
+ math_abort(FPU_info,SIGILL);
+ }
+
+do_another_FPU_instruction:
+
+ no_ip_update = 0;
+
+ FPU_EIP++; /* We have fetched the prefix and first code bytes. */
+
+ if ( addr_modes.default_mode )
+ {
+ /* This checks for the minimum instruction bytes.
+ We also need to check any extra (address mode) code access. */
+ if ( FPU_EIP > code_limit )
+ math_abort(FPU_info,SIGSEGV);
+ }
+
+ if ( (byte1 & 0xf8) != 0xd8 )
+ {
+ if ( byte1 == FWAIT_OPCODE )
+ {
+ if (partial_status & SW_Summary)
+ goto do_the_FPU_interrupt;
+ else
+ goto FPU_fwait_done;
+ }
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL|0x128);
+ math_abort(FPU_info,SIGILL);
+#endif /* PARANOID */
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(FPU_modrm, (u_char *) FPU_EIP);
+ RE_ENTRANT_CHECK_ON;
+ FPU_EIP++;
+
+ if (partial_status & SW_Summary)
+ {
+ /* Ignore the error for now if the current instruction is a no-wait
+ control instruction */
+ /* The 80486 manual contradicts itself on this topic,
+ but a real 80486 uses the following instructions:
+ fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
+ */
+ code = (FPU_modrm << 8) | byte1;
+ if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
+ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
+ fnstsw */
+ ((code & 0xc000) != 0xc000))) ) )
+ {
+ /*
+ * We need to simulate the action of the kernel to FPU
+ * interrupts here.
+ */
+ do_the_FPU_interrupt:
+
+ FPU_EIP = FPU_ORIG_EIP; /* Point to current FPU instruction. */
+
+ RE_ENTRANT_CHECK_OFF;
+ current->tss.trap_no = 16;
+ current->tss.error_code = 0;
+ send_sig(SIGFPE, current, 1);
+ return;
+ }
+ }
+
+ entry_sel_off.offset = FPU_ORIG_EIP;
+ entry_sel_off.selector = FPU_CS;
+ entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
+
+ FPU_rm = FPU_modrm & 7;
+
+ if ( FPU_modrm < 0300 )
+ {
+ /* All of these instructions use the mod/rm byte to get a data address */
+
+ if ( (addr_modes.default_mode & SIXTEEN)
+ ^ (addr_modes.override.address_size == ADDR_SIZE_PREFIX) )
+ data_address = FPU_get_address_16(FPU_modrm, (u32 *)&FPU_EIP, &data_sel_off,
+ addr_modes);
+ else
+ data_address = FPU_get_address(FPU_modrm, (u32 *)&FPU_EIP, &data_sel_off,
+ addr_modes);
+
+ if ( addr_modes.default_mode )
+ {
+ if ( FPU_EIP-1 > code_limit )
+ math_abort(FPU_info,SIGSEGV);
+ }
+
+ if ( !(byte1 & 1) )
+ {
+ unsigned short status1 = partial_status;
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+
+ /* Stack underflow has priority */
+ if ( NOT_EMPTY_ST0 )
+ {
+ if ( addr_modes.default_mode & PROTECTED )
+ {
+ /* This table works for 16 and 32 bit protected mode */
+ if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
+ math_abort(FPU_info,SIGSEGV);
+ }
+
+ unmasked = 0; /* Do this here to stop compiler warnings. */
+ switch ( (byte1 >> 1) & 3 )
+ {
+ case 0:
+ unmasked = FPU_load_single((float *)data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 1:
+ loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data); // bbd: was (u32*)
+ break;
+ case 2:
+ unmasked = FPU_load_double((double *)data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 3:
+ default: /* Used here to suppress gcc warnings. */
+ loaded_tag = FPU_load_int16((short *)data_address, &loaded_data);
+ break;
+ }
+
+ /* No more access to user memory, it is safe
+ to use static data now */
+
+ /* NaN operands have the next priority. */
+ /* We have to delay looking at st(0) until after
+ loading the data, because that data might contain an SNaN */
+ if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
+ ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
+ {
+ /* Restore the status word; we might have loaded a
+ denormal. */
+ partial_status = status1;
+ if ( (FPU_modrm & 0x30) == 0x10 )
+ {
+ /* fcom or fcomp */
+ EXCEPTION(EX_Invalid);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+ FPU_pop(); /* fcomp, masked, so we pop. */
+ }
+ else
+ {
+ if ( loaded_tag == TAG_Special )
+ loaded_tag = FPU_Special(&loaded_data);
+#ifdef PECULIAR_486
+ /* This is not really needed, but gives behaviour
+ identical to an 80486 */
+ if ( (FPU_modrm & 0x28) == 0x20 )
+ /* fdiv or fsub */
+ real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
+ else
+#endif /* PECULIAR_486 */
+ /* fadd, fdivr, fmul, or fsubr */
+ real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
+ }
+ goto reg_mem_instr_done;
+ }
+
+ if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
+ {
+ /* Is not a comparison instruction. */
+ if ( (FPU_modrm & 0x38) == 0x38 )
+ {
+ /* fdivr */
+ if ( (st0_tag == TAG_Zero) &&
+ ((loaded_tag == TAG_Valid)
+ || (loaded_tag == TAG_Special
+ && isdenormal(&loaded_data))) )
+ {
+ if ( FPU_divide_by_zero(0, getsign(&loaded_data))
+ < 0 )
+ {
+ /* We use the fact here that the unmasked
+ exception in the loaded data was for a
+ denormal operand */
+ /* Restore the state of the denormal op bit */
+ partial_status &= ~SW_Denorm_Op;
+ partial_status |= status1 & SW_Denorm_Op;
+ }
+ else
+ setsign(st0_ptr, getsign(&loaded_data));
+ }
+ }
+ goto reg_mem_instr_done;
+ }
+
+ switch ( (FPU_modrm >> 3) & 7 )
+ {
+ case 0: /* fadd */
+ clear_C1();
+ FPU_add(&loaded_data, loaded_tag, 0, control_word);
+ break;
+ case 1: /* fmul */
+ clear_C1();
+ FPU_mul(&loaded_data, loaded_tag, 0, control_word);
+ break;
+ case 2: /* fcom */
+ FPU_compare_st_data(&loaded_data, loaded_tag);
+ break;
+ case 3: /* fcomp */
+ if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
+ && !unmasked )
+ FPU_pop();
+ break;
+ case 4: /* fsub */
+ clear_C1();
+ // bbd: loaded_data used to be typecast to an int, but
+ // this corrupted the pointer on 64-bit machines.
+ // Now FPU_sub and similar take a FPU_REG* here instead.
+ FPU_sub(LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 5: /* fsubr */
+ clear_C1();
+ FPU_sub(REV|LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 6: /* fdiv */
+ clear_C1();
+ FPU_div(LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 7: /* fdivr */
+ clear_C1();
+ if ( st0_tag == TAG_Zero )
+ partial_status = status1; /* Undo any denorm tag,
+ zero-divide has priority. */
+ FPU_div(REV|LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ }
+ }
+ else
+ {
+ if ( (FPU_modrm & 0x30) == 0x10 )
+ {
+ /* The instruction is fcom or fcomp */
+ EXCEPTION(EX_StackUnder);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+ FPU_pop(); /* fcomp */
+ }
+ else
+ FPU_stack_underflow();
+ }
+ reg_mem_instr_done:
+ operand_address = data_sel_off;
+ }
+ else
+ {
+ if ( !(no_ip_update =
+ FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
+ addr_modes, data_address)) )
+ {
+ operand_address = data_sel_off;
+ }
+ }
+
+ }
+ else
+ {
+ /* None of these instructions access user memory */
+ u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
+
+#ifdef PECULIAR_486
+ /* This is supposed to be undefined, but a real 80486 seems
+ to do this: */
+ operand_address.offset = 0;
+ operand_address.selector = FPU_DS;
+#endif /* PECULIAR_486 */
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+ switch ( type_table[(int) instr_index] )
+ {
+ case _NONE_: /* also _REGIc: _REGIn */
+ break;
+ case _REG0_:
+ if ( !NOT_EMPTY_ST0 )
+ {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIi:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow_i(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIp:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow_pop(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGI_:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _PUSH_: /* Only used by the fld st(i) instruction */
+ break;
+ case _null_:
+ FPU_illegal();
+ goto FPU_instruction_done;
+ default:
+ EXCEPTION(EX_INTERNAL|0x111);
+ goto FPU_instruction_done;
+ }
+ (*st_instr_table[(int) instr_index])();
+
+FPU_instruction_done:
+ ;
+ }
+
+ if ( ! no_ip_update )
+ instruction_address = entry_sel_off;
+
+FPU_fwait_done:
+
+ if (FPU_lookahead && !current->need_resched)
+ {
+ FPU_ORIG_EIP = FPU_EIP - code_base;
+ if ( valid_prefix(&byte1, (u_char **)&FPU_EIP,
+ &addr_modes.override) )
+ goto do_another_FPU_instruction;
+ }
+
+ if ( addr_modes.default_mode )
+ FPU_EIP -= code_base;
+
+ RE_ENTRANT_CHECK_OFF;
+}
+
+
+/* Support for prefix bytes is not yet complete. To properly handle
+ all prefix bytes, further changes are needed in the emulator code
+ which accesses user address space. Access to separate segments is
+ important for msdos emulation. */
+static int valid_prefix(u_char *Byte, u_char **fpu_eip,
+ overrides *override)
+{
+ u_char byte;
+ u_char *ip = *fpu_eip;
+
+ *override = (overrides) { 0, 0, PREFIX_DEFAULT }; /* defaults */
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(byte, ip);
+ RE_ENTRANT_CHECK_ON;
+
+ while ( 1 )
+ {
+ switch ( byte )
+ {
+ case ADDR_SIZE_PREFIX:
+ override->address_size = ADDR_SIZE_PREFIX;
+ goto do_next_byte;
+
+ case OP_SIZE_PREFIX:
+ override->operand_size = OP_SIZE_PREFIX;
+ goto do_next_byte;
+
+ case PREFIX_CS:
+ override->segment = PREFIX_CS_;
+ goto do_next_byte;
+ case PREFIX_ES:
+ override->segment = PREFIX_ES_;
+ goto do_next_byte;
+ case PREFIX_SS:
+ override->segment = PREFIX_SS_;
+ goto do_next_byte;
+ case PREFIX_FS:
+ override->segment = PREFIX_FS_;
+ goto do_next_byte;
+ case PREFIX_GS:
+ override->segment = PREFIX_GS_;
+ goto do_next_byte;
+ case PREFIX_DS:
+ override->segment = PREFIX_DS_;
+ goto do_next_byte;
+
+/* lock is not a valid prefix for FPU instructions,
+ let the cpu handle it to generate a SIGILL. */
+/* case PREFIX_LOCK: */
+
+ /* rep.. prefixes have no meaning for FPU instructions */
+ case PREFIX_REPE:
+ case PREFIX_REPNE:
+
+ do_next_byte:
+ ip++;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(byte, ip);
+ RE_ENTRANT_CHECK_ON;
+ break;
+ case FWAIT_OPCODE:
+ *Byte = byte;
+ return 1;
+ default:
+ if ( (byte & 0xf8) == 0xd8 )
+ {
+ *Byte = byte;
+ *fpu_eip = ip;
+ return 1;
+ }
+ else
+ {
+ /* Not a valid sequence of prefix bytes followed by
+ an FPU instruction. */
+ *Byte = byte; /* Needed for error message. */
+ return 0;
+ }
+ }
+ }
+}
+
+
+void math_abort(struct info * info, unsigned int signal)
+{
+ FPU_EIP = FPU_ORIG_EIP;
+ current->tss.trap_no = 16;
+ current->tss.error_code = 0;
+ send_sig(signal,current,1);
+ RE_ENTRANT_CHECK_OFF;
+ __asm__("movl %0,%%esp ; ret": :"g" (((long) info)-4));
+#ifdef PARANOID
+ printk("ERROR: wm-FPU-emu math_abort failed!\n");
+#endif /* PARANOID */
+}
+
+
+
+#define S387 ((struct i387_soft_struct *)s387)
+#define sstatus_word() \
+ ((S387->swd & ~SW_Top & 0xffff) | ((S387->ftop << SW_Top_Shift) & SW_Top))
+
+int restore_i387_soft(void *s387, struct _fpstate *buf)
+{
+ u_char *d = (u_char *)buf;
+ int offset, other, i, tags, regnr, tag, newtop;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, d, 7*4 + 8*10);
+ if (__copy_from_user(&S387->cwd, d, 7*4))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ d += 7*4;
+
+ S387->ftop = (S387->swd >> SW_Top_Shift) & 7;
+ offset = (S387->ftop & 7) * 10;
+ other = 80 - offset;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* Copy all registers in stack order. */
+ if (__copy_from_user(((u_char *)&S387->st_space)+offset, d, other))
+ return -1;
+ if ( offset )
+ if (__copy_from_user((u_char *)&S387->st_space, d+other, offset))
+ return -1;
+ RE_ENTRANT_CHECK_ON;
+
+ /* The tags may need to be corrected now. */
+ tags = S387->twd;
+ newtop = S387->ftop;
+ for ( i = 0; i < 8; i++ )
+ {
+ regnr = (i+newtop) & 7;
+ if ( ((tags >> ((regnr & 7)*2)) & 3) != TAG_Empty )
+ {
+ /* The loaded data over-rides all other cases. */
+ tag = FPU_tagof((FPU_REG *)((u_char *)S387->st_space + 10*regnr));
+ tags &= ~(3 << (regnr*2));
+ tags |= (tag & 3) << (regnr*2);
+ }
+ }
+ S387->twd = tags;
+
+ return 0;
+}
+
+
+int save_i387_soft(void *s387, struct _fpstate * buf)
+{
+ u_char *d = (u_char *)buf;
+ int offset = (S387->ftop & 7) * 10, other = 80 - offset;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE, d, 7*4 + 8*10);
+#ifdef PECULIAR_486
+ S387->cwd &= ~0xe080;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ S387->cwd |= 0xffff0040;
+ S387->swd = sstatus_word() | 0xffff0000;
+ S387->twd |= 0xffff0000;
+ S387->fcs &= ~0xf8000000;
+ S387->fos |= 0xffff0000;
+#endif /* PECULIAR_486 */
+ __copy_to_user(d, &S387->cwd, 7*4);
+ RE_ENTRANT_CHECK_ON;
+
+ d += 7*4;
+
+ RE_ENTRANT_CHECK_OFF;
+ /* Copy all registers in stack order. */
+ if (__copy_to_user(d, ((u_char *)&S387->st_space)+offset, other))
+ return -1;
+ if ( offset )
+ if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset))
+ return -1
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+#else /* #ifndef USE_WITH_CPU_SIM */
+
+
+/* Note, this is a version of fpu_entry.c, modified to interface
+ * to a CPU simulator, rather than a kernel.
+ *
+ * Ported by Kevin Lawton Sep 20, 1999
+ */
+
+
+ asmlinkage void
+math_emulate2(fpu_addr_modes addr_modes,
+ u_char FPU_modrm,
+ u_char byte1,
+ void *data_address,
+ struct address data_sel_off,
+ struct address entry_sel_off)
+{
+ u16 code;
+ int unmasked;
+ FPU_REG loaded_data;
+ FPU_REG *st0_ptr;
+ u_char loaded_tag, st0_tag;
+
+
+ // assuming byte is 0xd8..0xdf or 0xdb==FWAIT
+
+ // lock is not a valid prefix for FPU instructions, +++
+ // let the cpu handle it to generate a SIGILL.
+
+
+ no_ip_update = 0;
+
+ if ( byte1 == FWAIT_OPCODE ) {
+ if (partial_status & SW_Summary)
+ goto do_the_FPU_interrupt;
+ else
+ goto FPU_fwait_done;
+ }
+
+ if (partial_status & SW_Summary) {
+ /* Ignore the error for now if the current instruction is a no-wait
+ control instruction */
+ /* The 80486 manual contradicts itself on this topic,
+ but a real 80486 uses the following instructions:
+ fninit, fnstenv, fnsave, fnstsw, fnstenv, fnclex.
+ */
+ code = (FPU_modrm << 8) | byte1;
+ if ( ! ( (((code & 0xf803) == 0xe003) || /* fnclex, fninit, fnstsw */
+ (((code & 0x3003) == 0x3001) && /* fnsave, fnstcw, fnstenv,
+ fnstsw */
+ ((code & 0xc000) != 0xc000))) ) ) {
+ /*
+ * We need to simulate the action of the kernel to FPU
+ * interrupts here.
+ */
+do_the_FPU_interrupt:
+
+ math_abort(FPU_info, SIGFPE);
+ }
+ }
+
+ entry_sel_off.opcode = (byte1 << 8) | FPU_modrm;
+
+ FPU_rm = FPU_modrm & 7;
+
+ if ( FPU_modrm < 0300 ) {
+ /* All of these instructions use the mod/rm byte to get a data address */
+
+ if ( !(byte1 & 1) ) {
+ u16 status1 = partial_status;
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+
+ /* Stack underflow has priority */
+ if ( NOT_EMPTY_ST0 ) {
+ if ( addr_modes.default_mode & PROTECTED )
+ {
+ /* This table works for 16 and 32 bit protected mode */
+ if ( access_limit < data_sizes_16[(byte1 >> 1) & 3] )
+ math_abort(FPU_info, SIGSEGV);
+ }
+
+ unmasked = 0; /* Do this here to stop compiler warnings. */
+ switch ( (byte1 >> 1) & 3 )
+ {
+ case 0:
+ unmasked = FPU_load_single((float *)data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 1:
+ loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data); // bbd: was (u32 *)
+ break;
+ case 2:
+ unmasked = FPU_load_double((double *)data_address,
+ &loaded_data);
+ loaded_tag = unmasked & 0xff;
+ unmasked &= ~0xff;
+ break;
+ case 3:
+ default: /* Used here to suppress gcc warnings. */
+ loaded_tag = FPU_load_int16((s16 *)data_address, &loaded_data);
+ break;
+ }
+
+ /* No more access to user memory, it is safe
+ to use static data now */
+
+ /* NaN operands have the next priority. */
+ /* We have to delay looking at st(0) until after
+ loading the data, because that data might contain an SNaN */
+ if ( ((st0_tag == TAG_Special) && isNaN(st0_ptr)) ||
+ ((loaded_tag == TAG_Special) && isNaN(&loaded_data)) )
+ {
+ /* Restore the status word; we might have loaded a
+ denormal. */
+ partial_status = status1;
+ if ( (FPU_modrm & 0x30) == 0x10 )
+ {
+ /* fcom or fcomp */
+ EXCEPTION(EX_Invalid);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+ FPU_pop(); /* fcomp, masked, so we pop. */
+ }
+ else
+ {
+ if ( loaded_tag == TAG_Special )
+ loaded_tag = FPU_Special(&loaded_data);
+#ifdef PECULIAR_486
+ /* This is not really needed, but gives behaviour
+ identical to an 80486 */
+ if ( (FPU_modrm & 0x28) == 0x20 )
+ /* fdiv or fsub */
+ real_2op_NaN(&loaded_data, loaded_tag, 0, &loaded_data);
+ else
+#endif /* PECULIAR_486 */
+ /* fadd, fdivr, fmul, or fsubr */
+ real_2op_NaN(&loaded_data, loaded_tag, 0, st0_ptr);
+ }
+ goto reg_mem_instr_done;
+ }
+
+ if ( unmasked && !((FPU_modrm & 0x30) == 0x10) )
+ {
+ /* Is not a comparison instruction. */
+ if ( (FPU_modrm & 0x38) == 0x38 )
+ {
+ /* fdivr */
+ if ( (st0_tag == TAG_Zero) &&
+ ((loaded_tag == TAG_Valid)
+ || (loaded_tag == TAG_Special
+ && isdenormal(&loaded_data))) )
+ {
+ if ( FPU_divide_by_zero(0, getsign(&loaded_data))
+ < 0 )
+ {
+ /* We use the fact here that the unmasked
+ exception in the loaded data was for a
+ denormal operand */
+ /* Restore the state of the denormal op bit */
+ partial_status &= ~SW_Denorm_Op;
+ partial_status |= status1 & SW_Denorm_Op;
+ }
+ else
+ setsign(st0_ptr, getsign(&loaded_data));
+ }
+ }
+ goto reg_mem_instr_done;
+ }
+
+ switch ( (FPU_modrm >> 3) & 7 )
+ {
+ case 0: /* fadd */
+ clear_C1();
+ FPU_add(&loaded_data, loaded_tag, 0, control_word);
+ break;
+ case 1: /* fmul */
+ clear_C1();
+ FPU_mul(&loaded_data, loaded_tag, 0, control_word);
+ break;
+ case 2: /* fcom */
+ FPU_compare_st_data(&loaded_data, loaded_tag);
+ break;
+ case 3: /* fcomp */
+ // bbd: used to typecase to int first, but this corrupted the
+ // pointer on 64 bit machines.
+ if ( !FPU_compare_st_data(&loaded_data, loaded_tag)
+ && !unmasked )
+ FPU_pop();
+ break;
+ case 4: /* fsub */
+ clear_C1();
+ FPU_sub(LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 5: /* fsubr */
+ clear_C1();
+ FPU_sub(REV|LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 6: /* fdiv */
+ clear_C1();
+ FPU_div(LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ case 7: /* fdivr */
+ clear_C1();
+ if ( st0_tag == TAG_Zero )
+ partial_status = status1; /* Undo any denorm tag,
+ zero-divide has priority. */
+ FPU_div(REV|LOADED|loaded_tag, &loaded_data, control_word);
+ break;
+ }
+ }
+ else
+ {
+ if ( (FPU_modrm & 0x30) == 0x10 )
+ {
+ /* The instruction is fcom or fcomp */
+ EXCEPTION(EX_StackUnder);
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if ( (FPU_modrm & 0x08) && (control_word & CW_Invalid) )
+ FPU_pop(); /* fcomp */
+ }
+ else
+ FPU_stack_underflow();
+ }
+ reg_mem_instr_done:
+ operand_address = data_sel_off;
+ }
+ else {
+ if ( !(no_ip_update =
+ FPU_load_store(((FPU_modrm & 0x38) | (byte1 & 6)) >> 1,
+ addr_modes, data_address)) )
+ {
+ operand_address = data_sel_off;
+ }
+ }
+ }
+ else {
+ /* None of these instructions access user memory */
+ u_char instr_index = (FPU_modrm & 0x38) | (byte1 & 7);
+
+#ifdef PECULIAR_486
+ /* This is supposed to be undefined, but a real 80486 seems
+ to do this: */
+ operand_address.offset = 0;
+ operand_address.selector = FPU_DS;
+#endif /* PECULIAR_486 */
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+ switch ( type_table[(int) instr_index] )
+ {
+ case _NONE_: /* also _REGIc: _REGIn */
+ break;
+ case _REG0_:
+ if ( !NOT_EMPTY_ST0 )
+ {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIi:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow_i(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGIp:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow_pop(FPU_rm);
+ goto FPU_instruction_done;
+ }
+ break;
+ case _REGI_:
+ if ( !NOT_EMPTY_ST0 || !NOT_EMPTY(FPU_rm) )
+ {
+ FPU_stack_underflow();
+ goto FPU_instruction_done;
+ }
+ break;
+ case _PUSH_: /* Only used by the fld st(i) instruction */
+ break;
+ case _null_:
+ FPU_illegal();
+ goto FPU_instruction_done;
+ default:
+ EXCEPTION(EX_INTERNAL|0x111);
+ goto FPU_instruction_done;
+ }
+ (*st_instr_table[(int) instr_index])();
+
+FPU_instruction_done:
+ ;
+ }
+
+ if ( ! no_ip_update )
+ instruction_address = entry_sel_off;
+
+FPU_fwait_done:
+
+#ifdef DEBUG
+ FPU_printall();
+#endif /* DEBUG */
+#ifdef BX_NO_BLANK_LABELS
+ if(0);
+#endif
+}
+
+#endif /* #ifndef USE_WITH_CPU_SIM */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_etc.c |
+ | |
+ | Implement a few FPU instructions. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "reg_constant.h"
+
+
+static void fchs(FPU_REG *st0_ptr, u_char st0tag)
+{
+ if ( st0tag ^ TAG_Empty )
+ {
+ signbyte(st0_ptr) ^= SIGN_NEG;
+ clear_C1();
+ }
+ else
+ FPU_stack_underflow();
+}
+
+
+static void fpu_fabs(FPU_REG *st0_ptr, u_char st0tag)
+{
+ if ( st0tag ^ TAG_Empty )
+ {
+ setpositive(st0_ptr);
+ clear_C1();
+ }
+ else
+ FPU_stack_underflow();
+}
+
+
+static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
+{
+ switch (st0tag)
+ {
+ case TAG_Zero:
+ setcc(SW_C3);
+ break;
+ case TAG_Valid:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ break;
+ case TAG_Special:
+ switch ( FPU_Special(st0_ptr) )
+ {
+ case TW_Denormal:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ if ( denormal_operand() < 0 )
+ {
+#ifdef PECULIAR_486
+ /* This is weird! */
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(SW_C3);
+#endif /* PECULIAR_486 */
+ return;
+ }
+ break;
+ case TW_NaN:
+ setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_Invalid);
+ break;
+ case TW_Infinity:
+ if (getsign(st0_ptr) == SIGN_POS)
+ setcc(0);
+ else
+ setcc(SW_C0);
+ break;
+ default:
+ setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */
+ EXCEPTION(EX_INTERNAL|0x14);
+ break;
+ }
+ break;
+ case TAG_Empty:
+ setcc(SW_C0|SW_C2|SW_C3);
+ EXCEPTION(EX_StackUnder);
+ break;
+ }
+}
+
+
+static void fxam(FPU_REG *st0_ptr, u_char st0tag)
+{
+ int c = 0;
+ switch (st0tag)
+ {
+ case TAG_Empty:
+ c = SW_C3|SW_C0;
+ break;
+ case TAG_Zero:
+ c = SW_C3;
+ break;
+ case TAG_Valid:
+ c = SW_C2;
+ break;
+ case TAG_Special:
+ switch ( FPU_Special(st0_ptr) )
+ {
+ case TW_Denormal:
+ c = SW_C2|SW_C3; /* Denormal */
+ break;
+ case TW_NaN:
+ /* We also use NaN for unsupported types. */
+ if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) )
+ c = SW_C0;
+ break;
+ case TW_Infinity:
+ c = SW_C2|SW_C0;
+ break;
+ }
+ }
+ if ( getsign(st0_ptr) == SIGN_NEG )
+ c |= SW_C1;
+ setcc(c);
+}
+
+
+static FUNC_ST0 const fp_etc_table[] = {
+ fchs, fpu_fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
+ ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
+};
+
+void FPU_etc()
+{
+ (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
+}
--- /dev/null
+#ifndef _FPU_PROTO_H
+#define _FPU_PROTO_H
+
+/* errors.c */
+extern void Un_impl(void);
+extern void FPU_illegal(void);
+extern void FPU_printall(void);
+asmlinkage void FPU_exception(int n);
+extern int real_1op_NaN(FPU_REG *a);
+extern int real_2op_NaN(FPU_REG const *b, u_char tagb, int deststnr,
+ FPU_REG const *defaultNaN);
+extern int arith_invalid(int deststnr);
+extern int FPU_divide_by_zero(int deststnr, u_char sign);
+extern int set_precision_flag(int flags);
+extern void set_precision_flag_up(void);
+extern void set_precision_flag_down(void);
+extern int denormal_operand(void);
+extern int arith_overflow(FPU_REG *dest);
+extern int arith_round_overflow(FPU_REG *dest, u8 sign);
+extern int arith_underflow(FPU_REG *dest);
+extern void FPU_stack_overflow(void);
+extern void FPU_stack_underflow(void);
+extern void FPU_stack_underflow_i(int i);
+extern void FPU_stack_underflow_pop(int i);
+/* fpu_arith.c */
+extern void fadd__(void);
+extern void fmul__(void);
+extern void fsub__(void);
+extern void fsubr_(void);
+extern void fdiv__(void);
+extern void fdivr_(void);
+extern void fadd_i(void);
+extern void fmul_i(void);
+extern void fsubri(void);
+extern void fsub_i(void);
+extern void fdivri(void);
+extern void fdiv_i(void);
+extern void faddp_(void);
+extern void fmulp_(void);
+extern void fsubrp(void);
+extern void fsubp_(void);
+extern void fdivrp(void);
+extern void fdivp_(void);
+/* fpu_aux.c */
+extern void fclex(void);
+extern void finit(void);
+extern void finit_(void);
+extern void fstsw_(void);
+extern void fp_nop(void);
+extern void fld_i_(void);
+extern void fxch_i(void);
+extern void ffree_(void);
+extern void ffreep(void);
+extern void fst_i_(void);
+extern void fstp_i(void);
+/* fpu_entry.c */
+extern void math_emulate(long arg);
+extern void math_abort(struct info *info, unsigned int signal);
+/* fpu_etc.c */
+extern void FPU_etc(void);
+/* fpu_tags.c */
+extern int FPU_gettag0(void);
+extern int FPU_gettagi(int stnr);
+extern int FPU_gettag(int regnr);
+extern void FPU_settag0(int tag);
+extern void FPU_settagi(int stnr, int tag);
+extern void FPU_settag(int regnr, int tag);
+extern int FPU_Special(FPU_REG const *ptr);
+extern int isNaN(FPU_REG const *ptr);
+extern void FPU_pop(void);
+extern int FPU_empty_i(int stnr);
+extern int FPU_stackoverflow(FPU_REG **st_new_ptr);
+extern void FPU_sync_tags(void);
+extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr);
+extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag);
+extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag);
+/* fpu_trig.c */
+extern void FPU_triga(void);
+extern void FPU_trigb(void);
+/* get_address.c */
+extern void *FPU_get_address(u_char FPU_modrm, u32 *fpu_eip,
+ struct address *addr, fpu_addr_modes addr_modes);
+extern void *FPU_get_address_16(u_char FPU_modrm, u32 *fpu_eip,
+ struct address *addr, fpu_addr_modes addr_modes);
+/* load_store.c */
+extern int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
+ void *data_address);
+/* poly_2xm1.c */
+extern int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result);
+/* poly_atan.c */
+extern void poly_atan(FPU_REG *st0_ptr, u_char st0_tag, FPU_REG *st1_ptr,
+ u_char st1_tag);
+/* poly_l2.c */
+extern void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign);
+extern int poly_l2p1(u_char s0, u_char s1, FPU_REG *r0, FPU_REG *r1,
+ FPU_REG *d);
+/* poly_sin.c */
+extern void poly_sine(FPU_REG *st0_ptr);
+extern void poly_cos(FPU_REG *st0_ptr);
+/* poly_tan.c */
+extern void poly_tan(FPU_REG *st0_ptr, int flag);
+/* reg_add_sub.c */
+extern int FPU_add(FPU_REG const *b, u_char tagb, int destrnr, u16 control_w);
+extern int FPU_sub(int flags, FPU_REG *rm, u16 control_w); // bbd: changed arg2 from int to FPU_REG*
+/* reg_compare.c */
+extern int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag);
+extern void fcom_st(void);
+extern void fcompst(void);
+extern void fcompp(void);
+extern void fucom_(void);
+extern void fucomp(void);
+extern void fucompp(void);
+/* reg_constant.c */
+extern void fconst(void);
+/* reg_ld_str.c */
+extern int FPU_load_extended(long double *s, int stnr);
+extern int FPU_load_double(double *dfloat, FPU_REG *loaded_data);
+extern int FPU_load_single(float *single, FPU_REG *loaded_data);
+extern int FPU_load_int64(s64 *_s);
+extern int FPU_load_int32(s32 *_s, FPU_REG *loaded_data);
+extern int FPU_load_int16(s16 *_s, FPU_REG *loaded_data);
+extern int FPU_load_bcd(u_char *s);
+extern int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
+ long double *d);
+extern int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat);
+extern int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single);
+extern int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, s64 *d);
+extern int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, s32 *d);
+extern int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, s16 *d);
+extern int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d);
+extern int FPU_round_to_int(FPU_REG *r, u_char tag);
+extern u_char *fldenv(fpu_addr_modes addr_modes, u_char *s);
+extern void frstor(fpu_addr_modes addr_modes, u_char *data_address);
+extern u_char *fstenv(fpu_addr_modes addr_modes, u_char *d);
+extern void fsave(fpu_addr_modes addr_modes, u_char *data_address);
+extern int FPU_tagof(FPU_REG *ptr);
+/* reg_mul.c */
+extern int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w);
+
+extern int FPU_div(int flags, FPU_REG *regrm, int control_w); // bbd: changed arg2 from int to FPU_REG*
+/* reg_convert.c */
+extern int FPU_to_exp16(FPU_REG const *a, FPU_REG *x);
+#endif /* _FPU_PROTO_H */
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_system.h |
+ | |
+ | Copyright (C) 1992,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _FPU_SYSTEM_H
+#define _FPU_SYSTEM_H
+
+#ifndef USE_WITH_CPU_SIM
+
+/* system dependent definitions */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+/* This sets the pointer FPU_info to point to the argument part
+ of the stack frame of math_emulate() */
+#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg
+
+#define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->segments)[(s) >> 3])
+#define SEG_D_SIZE(x) ((x).b & (3 << 21))
+#define SEG_G_BIT(x) ((x).b & (1 << 23))
+#define SEG_GRANULARITY(x) (((x).b & (1 << 23)) ? 4096 : 1)
+#define SEG_286_MODE(x) ((x).b & ( 0xff000000 | 0xf0000 | (1 << 23)))
+#define SEG_BASE_ADDR(s) (((s).b & 0xff000000) \
+ | (((s).b & 0xff) << 16) | ((s).a >> 16))
+#define SEG_LIMIT(s) (((s).b & 0xff0000) | ((s).a & 0xffff))
+#define SEG_EXECUTE_ONLY(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 11))
+#define SEG_WRITE_PERM(s) (((s).b & ((1 << 11) | (1 << 9))) == (1 << 9))
+#define SEG_EXPAND_DOWN(s) (((s).b & ((1 << 11) | (1 << 10))) \
+ == (1 << 10))
+
+#define I387 (current->tss.i387)
+#define FPU_info (I387.soft.info)
+
+#define FPU_CS (*(u16 *) &(FPU_info->___cs))
+#define FPU_SS (*(u16 *) &(FPU_info->___ss))
+#define FPU_DS (*(u16 *) &(FPU_info->___ds))
+#define FPU_EAX (FPU_info->___eax)
+#define FPU_EFLAGS (FPU_info->___eflags)
+#define FPU_EIP (FPU_info->___eip)
+#define FPU_ORIG_EIP (FPU_info->___orig_eip)
+
+#define FPU_lookahead (I387.soft.lookahead)
+
+#define SET_AX(val16) *(s16 *) &FPU_EAX = val16
+
+/* nz if ip_offset and cs_selector are not to be set for the current
+ instruction. */
+#define no_ip_update (*(u_char *)&(I387.soft.no_update))
+#define FPU_rm (*(u_char *)&(I387.soft.rm))
+
+/* Number of bytes of data which can be legally accessed by the current
+ instruction. This only needs to hold a number <= 108, so a byte will do. */
+#define access_limit (*(u_char *)&(I387.soft.alimit))
+
+#define partial_status (I387.soft.swd)
+#define control_word (I387.soft.cwd)
+#define fpu_tag_word (I387.soft.twd)
+#define registers (I387.soft.st_space)
+#define top (I387.soft.ftop)
+
+#define instruction_address (*(struct address *)&I387.soft.fip)
+#define operand_address (*(struct address *)&I387.soft.foo)
+
+#define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \
+ math_abort(FPU_info,SIGSEGV)
+
+#undef FPU_IGNORE_CODE_SEGV
+#ifdef FPU_IGNORE_CODE_SEGV
+/* verify_area() is very expensive, and causes the emulator to run
+ about 20% slower if applied to the code. Anyway, errors due to bad
+ code addresses should be much rarer than errors due to bad data
+ addresses. */
+#define FPU_code_verify_area(z)
+#else
+/* A simpler test than verify_area() can probably be done for
+ FPU_code_verify_area() because the only possible error is to step
+ past the upper boundary of a legal code area. */
+#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void *)FPU_EIP,z)
+#endif
+
+#define FPU_get_user(x,y) get_user((x),(y))
+#define FPU_put_user(x,y) put_user((x),(y))
+
+#else /* USE_WITH_CPU_SIM */
+
+/* -----------------------------------------------------------
+ * Slimmed down version used to compile against a CPU simulator
+ * rather than a kernel (ported by Kevin Lawton)
+ * ------------------------------------------------------------ */
+
+/* Get data sizes from config.h generated from simulator's
+ * configure script
+ */
+#include "config.h"
+typedef Bit8u u8;
+typedef Bit8s s8;
+typedef Bit16u u16;
+typedef Bit16s s16;
+typedef Bit32u u32;
+typedef Bit32s s32;
+typedef Bit64u u64;
+typedef Bit64s s64;
+
+/* bbd: include ported linux headers after config.h for GCC_ATTRIBUTE macro */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/math_emu.h>
+#include <linux/types.h>
+
+#ifndef WORDS_BIGENDIAN
+#error "WORDS_BIGENDIAN not defined in config.h"
+#elif WORDS_BIGENDIAN == 1
+#define EMU_BIG_ENDIAN 1
+#else
+/* Nothing needed. Lack of defining EMU_BIG_ENDIAN means
+ * small endian
+ */
+#endif
+
+
+extern unsigned fpu_get_user(void *ptr, unsigned len);
+extern void fpu_put_user(unsigned val, void *ptr, unsigned len);
+
+extern void fpu_verify_area(unsigned what, void *ptr, unsigned n);
+extern void math_emulate_init(void);
+extern unsigned fpu_get_ds(void);
+extern void fpu_set_ax(u16);
+
+#ifndef __ASSEMBLY__
+
+struct info {
+#ifdef BX_NO_EMPTY_STRUCTS
+ unsigned char donotindexme;
+#endif
+ };
+
+#define FPU_info ((struct info *) NULL)
+
+
+//
+// Minimal i387 structure, pruned from the linux headers. Only
+// the fields which were necessary are included.
+//
+typedef struct {
+ struct {
+ s32 cwd;
+ s32 swd;
+ s32 twd;
+ s32 fip;
+ s32 fcs;
+ s32 foo;
+ s32 fos;
+ u32 fill0; /* to make sure the following aligns on an 8byte boundary */
+ u64 st_space[16]; /* 8*16 bytes per FP-reg (aligned) = 128 bytes */
+ unsigned char ftop;
+ unsigned char no_update;
+ unsigned char rm;
+ unsigned char alimit;
+ } GCC_ATTRIBUTE((aligned(16), packed)) soft;
+ } i387_t;
+
+extern i387_t i387;
+
+
+#endif
+
+#define SIGSEGV 11
+
+#define I387 i387
+
+
+#define SET_AX(val16) fpu_set_ax(val16);
+
+#define no_ip_update (*(u_char *)&(I387.soft.no_update))
+#define FPU_rm (*(u_char *)&(I387.soft.rm))
+
+
+/* Number of bytes of data which can be legally accessed by the current
+ instruction. This only needs to hold a number <= 108, so a byte will do. */
+#define access_limit (*(u_char *)&(I387.soft.alimit))
+
+#define partial_status (I387.soft.swd)
+#define control_word (I387.soft.cwd)
+#define fpu_tag_word (I387.soft.twd)
+#define registers (I387.soft.st_space)
+#define top (I387.soft.ftop)
+
+#define instruction_address (*(struct address *)&I387.soft.fip)
+#define operand_address (*(struct address *)&I387.soft.foo)
+
+#define FPU_verify_area(x,y,z) fpu_verify_area(x,y,z)
+#define FPU_get_user(x,y) ((x) = fpu_get_user((y), sizeof(*(y))))
+#define FPU_put_user(val,ptr) fpu_put_user((val),(ptr),sizeof(*(ptr)))
+
+#define FPU_DS (fpu_get_ds())
+
+#endif /* USE_WITH_CPU_SIM */
+
+// bbd: Change a pointer to an int, with type conversions that make it legal.
+// First make it a void pointer, then convert to an integer of the same
+// size as the pointer. Otherwise, on machines with 64-bit pointers,
+// compilers complain when you typecast a 64-bit pointer into a 32-bit integer.
+#define PTR2INT(x) ((bx_ptr_equiv_t)(void *)(x))
+
+// bbd: Change an int to a pointer, with type conversions that make it legal.
+// Same strategy as PTR2INT: change to bx_ptr_equiv_t which is an integer
+// type of the same size as FPU_REG*. Then the conversion to pointer
+// is legal.
+#define REGNO2PTR(x) ((FPU_REG*)((bx_ptr_equiv_t)(x)))
+
+#endif
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_tags.c |
+ | |
+ | Set FPU register tags. |
+ | |
+ | Copyright (C) 1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "exception.h"
+
+
+void FPU_pop(void)
+{
+ fpu_tag_word |= 3 << ((top & 7)*2);
+ top++;
+}
+
+
+int FPU_gettag0(void)
+{
+ return (fpu_tag_word >> ((top & 7)*2)) & 3;
+}
+
+
+int FPU_gettagi(int stnr)
+{
+ return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3;
+}
+
+
+int FPU_gettag(int regnr)
+{
+ return (fpu_tag_word >> ((regnr & 7)*2)) & 3;
+}
+
+
+void FPU_settag0(int tag)
+{
+ int regnr = top;
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr*2));
+ fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+void FPU_settagi(int stnr, int tag)
+{
+ int regnr = stnr+top;
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr*2));
+ fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+void FPU_settag(int regnr, int tag)
+{
+ regnr &= 7;
+ fpu_tag_word &= ~(3 << (regnr*2));
+ fpu_tag_word |= (tag & 3) << (regnr*2);
+}
+
+
+int FPU_Special(FPU_REG const *ptr)
+{
+ int exp = exponent(ptr);
+
+ if ( exp == EXP_BIAS+EXP_UNDER )
+ return TW_Denormal;
+ else if ( exp != EXP_BIAS+EXP_OVER )
+ return TW_NaN;
+ else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) )
+ return TW_Infinity;
+ return TW_NaN;
+}
+
+
+int isNaN(FPU_REG const *ptr)
+{
+ return ( (exponent(ptr) == EXP_BIAS+EXP_OVER)
+ && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) );
+}
+
+
+int FPU_empty_i(int stnr)
+{
+ int regnr = (top+stnr) & 7;
+
+ return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty;
+}
+
+
+int FPU_stackoverflow(FPU_REG **st_new_ptr)
+{
+ *st_new_ptr = &st(-1);
+
+ return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty;
+}
+
+
+void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
+{
+ reg_copy(r, &st(stnr));
+ FPU_settagi(stnr, tag);
+}
+
+void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
+{
+ reg_copy(r, &st(1));
+ FPU_settagi(1, tag);
+}
+
+void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
+{
+ int regnr = top;
+ regnr &= 7;
+
+ reg_copy(r, &st(0));
+
+ fpu_tag_word &= ~(3 << (regnr*2));
+ fpu_tag_word |= (tag & 3) << (regnr*2);
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | fpu_trig.c |
+ | |
+ | Implementation of the FPU "transcendental" functions. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "reg_constant.h"
+
+static void rem_kernel(u64 st0, u64 *y, u64 st1, u64 q, int n);
+
+#define BETTER_THAN_486
+
+#define FCOS 4
+#define FPTAN 8
+
+/* Used only by fptan, fsin, fcos, and fsincos. */
+/* This routine produces very accurate results, similar to
+ using a value of pi with more than 128 bits precision. */
+/* Limited measurements show no results worse than 64 bit precision
+ except for the results for arguments close to 2^63, where the
+ precision of the result sometimes degrades to about 63.9 bits */
+static int trig_arg(FPU_REG *st0_ptr, int flags)
+{
+ FPU_REG tmp;
+ u_char tmptag;
+ u64 q;
+ int old_cw = control_word, saved_status = partial_status;
+ int tag, st0_tag = TAG_Valid;
+
+ if ( exponent(st0_ptr) >= 63 )
+ {
+ partial_status |= SW_C2; /* Reduction incomplete. */
+ return -1;
+ }
+
+ if ( flags & FPTAN )
+ st0_ptr->exp ++; /* Effectively base the following upon pi/4 */
+
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+
+ setpositive(st0_ptr);
+ tag = FPU_u_div(st0_ptr,
+ &CONST_PI2,
+ &tmp, PR_64_BITS | RC_CHOP | 0x3f, SIGN_POS);
+
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow
+ to 2^64 */
+ q = significand(&tmp);
+
+ if ( q )
+ {
+ rem_kernel(significand(st0_ptr),
+ &significand(&tmp),
+ significand(&CONST_PI2),
+ q, exponent(st0_ptr) - exponent(&CONST_PI2));
+ setexponent16(&tmp, exponent(&CONST_PI2));
+ st0_tag = FPU_normalize_nuo(&tmp,
+ EXTENDED_Ebias); /* No underflow or overflow
+ is possible */
+
+ FPU_copy_to_reg0(&tmp, st0_tag);
+ }
+
+ if ( ((flags & FCOS) && !(q & 1)) || (!(flags & FCOS) && (q & 1)) )
+ {
+ st0_tag = FPU_sub(REV|LOADED|TAG_Valid, &CONST_PI2, FULL_PRECISION); //bbd: arg2 used to typecast to (int)
+
+#ifdef BETTER_THAN_486
+ /* So far, the results are exact but based upon a 64 bit
+ precision approximation to pi/2. The technique used
+ now is equivalent to using an approximation to pi/2 which
+ is accurate to about 128 bits. */
+ if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) )
+ {
+ /* This code gives the effect of having pi/2 to better than
+ 128 bits precision. */
+
+ significand(&tmp) = q + 1;
+ setexponent16(&tmp, 63);
+ FPU_normalize_nuo(&tmp,
+ EXTENDED_Ebias); /* No underflow or overflow
+ is possible */
+ tmptag =
+ FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
+ exponent(&CONST_PI2extra) + exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
+ st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
+ if ( signnegative(st0_ptr) && !(flags & FPTAN) )
+ {
+ /* CONST_PI2extra is negative, so the result of the addition
+ can be negative. This means that the argument is actually
+ in a different quadrant. The correction is always < pi/2,
+ so it can't overflow into yet another quadrant. */
+ /* The function is even, so we need just adjust the sign
+ and q. */
+ setpositive(st0_ptr);
+ q++;
+ }
+ }
+#endif /* BETTER_THAN_486 */
+ }
+#ifdef BETTER_THAN_486
+ else
+ {
+ /* So far, the results are exact but based upon a 64 bit
+ precision approximation to pi/2. The technique used
+ now is equivalent to using an approximation to pi/2 which
+ is accurate to about 128 bits. */
+ if ( ((q > 0)
+ && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
+ || (q > 1) )
+ {
+ /* This code gives the effect of having p/2 to better than
+ 128 bits precision. */
+
+ significand(&tmp) = q;
+ setexponent16(&tmp, 63);
+ FPU_normalize_nuo(&tmp,
+ EXTENDED_Ebias); /* No underflow or overflow
+ is possible.
+ This must return TAG_Valid */
+ tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
+ SIGN_POS,
+ exponent(&CONST_PI2extra) + exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
+ st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), &tmp,
+ FULL_PRECISION);
+ if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
+ ((st0_ptr->sigh > CONST_PI2.sigh)
+ || ((st0_ptr->sigh == CONST_PI2.sigh)
+ && (st0_ptr->sigl > CONST_PI2.sigl))) )
+ {
+ /* CONST_PI2extra is negative, so the result of the
+ subtraction can be larger than pi/2. This means
+ that the argument is actually in a different quadrant.
+ The correction is always < pi/2, so it can't overflow
+ into yet another quadrant.
+ bbd: arg2 used to typecast to (int), corrupting 64-bit ptrs
+ */
+ st0_tag = FPU_sub(REV|LOADED|TAG_Valid, &CONST_PI2,
+ FULL_PRECISION);
+ q++;
+ }
+ }
+ }
+#endif /* BETTER_THAN_486 */
+
+ FPU_settag0(st0_tag);
+ control_word = old_cw;
+ partial_status = saved_status & ~SW_C2; /* Reduction complete. */
+
+ if ( flags & FPTAN )
+ {
+ st0_ptr->exp --;
+ return q & 7;
+ }
+
+ return (q & 3) | (flags & FCOS);
+}
+
+
+/* Convert a s32 to register */
+static void convert_l2reg(s32 const *arg, int deststnr)
+{
+ int tag;
+ s32 num = *arg;
+ u_char sign;
+ FPU_REG *dest = &st(deststnr);
+
+ if (num == 0)
+ {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ return;
+ }
+
+ if (num > 0)
+ { sign = SIGN_POS; }
+ else
+ { num = -num; sign = SIGN_NEG; }
+
+ dest->sigh = num;
+ dest->sigl = 0;
+ setexponent16(dest, 31);
+ tag = FPU_normalize_nuo(dest,
+ EXTENDED_Ebias); /* No underflow or overflow
+ is possible */
+ FPU_settagi(deststnr, tag);
+ setsign(dest, sign);
+ return;
+}
+
+
+static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ if ( st0_tag == TAG_Empty )
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ else if ( st0_tag == TW_NaN )
+ real_1op_NaN(st0_ptr); /* return with a NaN in st(0) */
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL|0x0112);
+#endif /* PARANOID */
+}
+
+
+static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ int isNaN;
+
+ switch ( st0_tag )
+ {
+ case TW_NaN:
+ isNaN = (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000);
+ if ( isNaN && !(st0_ptr->sigh & 0x40000000) ) /* Signaling ? */
+ {
+ EXCEPTION(EX_Invalid);
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ /* Convert to a QNaN */
+ st0_ptr->sigh |= 0x40000000;
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ }
+ }
+ else if ( isNaN )
+ {
+ /* A QNaN */
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ }
+ else
+ {
+ /* pseudoNaN or other unsupported */
+ EXCEPTION(EX_Invalid);
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ push();
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ }
+ }
+ break; /* return with a NaN in st(0) */
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x0112);
+#endif /* PARANOID */
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static void f2xm1(FPU_REG *st0_ptr, u_char tag)
+{
+ FPU_REG a;
+
+ clear_C1();
+
+ if ( tag == TAG_Valid )
+ {
+ /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
+ if ( exponent(st0_ptr) < 0 )
+ {
+ denormal_arg:
+
+ FPU_to_exp16(st0_ptr, &a);
+
+ /* poly_2xm1(x) requires 0 < st(0) < 1. */
+ poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+ }
+ set_precision_flag_up(); /* 80486 appears to always do this */
+ return;
+ }
+
+ if ( tag == TAG_Zero )
+ return;
+
+ if ( tag == TAG_Special )
+ tag = FPU_Special(st0_ptr);
+
+ switch ( tag )
+ {
+ case TW_Denormal:
+ if ( denormal_operand() < 0 )
+ return;
+ goto denormal_arg;
+ case TW_Infinity:
+ if ( signnegative(st0_ptr) )
+ {
+ /* -infinity gives -1 (p16-10) */
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setnegative(st0_ptr);
+ }
+ return;
+ default:
+ single_arg_error(st0_ptr, tag);
+ }
+}
+
+
+static void fptan(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st_new_ptr;
+ u32 q;
+ u_char arg_sign = getsign(st0_ptr);
+ int invert[] = { 0, 1, 1, 0, 0, 1, 1, 0 };
+
+ /* Stack underflow has higher priority */
+ if ( st0_tag == TAG_Empty )
+ {
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ if ( control_word & CW_Invalid )
+ {
+ st_new_ptr = &st(-1);
+ push();
+ FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ }
+ return;
+ }
+
+ if ( STACK_OVERFLOW )
+ { FPU_stack_overflow(); return; }
+
+ if ( st0_tag == TAG_Valid )
+ {
+ if ( exponent(st0_ptr) > -40 )
+ {
+ if ( (q = trig_arg(st0_ptr, FPTAN)) == -1 )
+ {
+ /* Operand is out of range */
+ return;
+ }
+
+ poly_tan(st0_ptr, invert[q]);
+ setsign(st0_ptr, ((q & 2) != 0) ^ (arg_sign != 0));
+ set_precision_flag_up(); /* We do not really know if up or down */
+ }
+ else
+ {
+ /* For a small arg, the result == the argument */
+ /* Underflow may happen */
+
+ denormal_arg:
+
+ FPU_to_exp16(st0_ptr, st0_ptr);
+
+ st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+ FPU_settag0(st0_tag);
+ }
+ push();
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ return;
+ }
+
+ if ( st0_tag == TAG_Zero )
+ {
+ push();
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setcc(0);
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+
+ if ( st0_tag == TW_Denormal )
+ {
+ if ( denormal_operand() < 0 )
+ return;
+
+ goto denormal_arg;
+ }
+
+ if ( st0_tag == TW_Infinity )
+ {
+ /* The 80486 treats infinity as an invalid operand */
+ if ( arith_invalid(0) >= 0 )
+ {
+ st_new_ptr = &st(-1);
+ push();
+ arith_invalid(0);
+ }
+ return;
+ }
+
+ single_arg_2_error(st0_ptr, st0_tag);
+}
+
+
+static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st_new_ptr;
+ u_char sign;
+ register FPU_REG *st1_ptr = st0_ptr; /* anticipate */
+
+ if ( STACK_OVERFLOW )
+ { FPU_stack_overflow(); return; }
+
+ clear_C1();
+
+ if ( st0_tag == TAG_Valid )
+ {
+ s32 e;
+
+ push();
+ sign = getsign(st1_ptr);
+ reg_copy(st1_ptr, st_new_ptr);
+ setexponent16(st_new_ptr, exponent(st_new_ptr));
+
+ denormal_arg:
+
+ e = exponent16(st_new_ptr);
+ convert_l2reg(&e, 1);
+ setexponentpos(st_new_ptr, 0);
+ setsign(st_new_ptr, sign);
+ FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
+ return;
+ }
+ else if ( st0_tag == TAG_Zero )
+ {
+ sign = getsign(st0_ptr);
+
+ if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 )
+ return;
+
+ push();
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(st_new_ptr, sign);
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+
+ if ( st0_tag == TW_Denormal )
+ {
+ if (denormal_operand() < 0 )
+ return;
+
+ push();
+ sign = getsign(st1_ptr);
+ FPU_to_exp16(st1_ptr, st_new_ptr);
+ goto denormal_arg;
+ }
+ else if ( st0_tag == TW_Infinity )
+ {
+ sign = getsign(st0_ptr);
+ setpositive(st0_ptr);
+ push();
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ setsign(st_new_ptr, sign);
+ return;
+ }
+ else if ( st0_tag == TW_NaN )
+ {
+ if ( real_1op_NaN(st0_ptr) < 0 )
+ return;
+
+ push();
+ FPU_copy_to_reg0(st0_ptr, TAG_Special);
+ return;
+ }
+ else if ( st0_tag == TAG_Empty )
+ {
+ /* Is this the correct behaviour? */
+ if ( control_word & EX_Invalid )
+ {
+ FPU_stack_underflow();
+ push();
+ FPU_stack_underflow();
+ }
+ else
+ EXCEPTION(EX_StackUnder);
+ }
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL | 0x119);
+#endif /* PARANOID */
+}
+
+
+static void fdecstp(void)
+{
+ clear_C1();
+ top--;
+}
+
+static void fincstp(void)
+{
+ clear_C1();
+ top++;
+}
+
+
+static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ int expon;
+
+ clear_C1();
+
+ if ( st0_tag == TAG_Valid )
+ {
+ u_char tag;
+
+ if (signnegative(st0_ptr))
+ {
+ arith_invalid(0); /* sqrt(negative) is invalid */
+ return;
+ }
+
+ /* make st(0) in [1.0 .. 4.0) */
+ expon = exponent(st0_ptr);
+
+ denormal_arg:
+
+ setexponent16(st0_ptr, (expon & 1));
+
+ /* Do the computation, the sign of the result will be positive. */
+ tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
+ addexponent(st0_ptr, expon >> 1);
+ FPU_settag0(tag);
+ return;
+ }
+
+ if ( st0_tag == TAG_Zero )
+ return;
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+
+ if ( st0_tag == TW_Infinity )
+ {
+ if ( signnegative(st0_ptr) )
+ arith_invalid(0); /* sqrt(-Infinity) is invalid */
+ return;
+ }
+ else if ( st0_tag == TW_Denormal )
+ {
+ if (signnegative(st0_ptr))
+ {
+ arith_invalid(0); /* sqrt(negative) is invalid */
+ return;
+ }
+
+ if ( denormal_operand() < 0 )
+ return;
+
+ FPU_to_exp16(st0_ptr, st0_ptr);
+
+ expon = exponent16(st0_ptr);
+
+ goto denormal_arg;
+ }
+
+ single_arg_error(st0_ptr, st0_tag);
+
+}
+
+
+static void frndint_(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ int flags, tag;
+
+ if ( st0_tag == TAG_Valid )
+ {
+ u_char sign;
+
+ denormal_arg:
+
+ sign = getsign(st0_ptr);
+
+ if (exponent(st0_ptr) > 63)
+ return;
+
+ if ( st0_tag == TW_Denormal )
+ {
+ if (denormal_operand() < 0 )
+ return;
+ }
+
+ /* Fortunately, this can't overflow to 2^64 */
+ if ( (flags = FPU_round_to_int(st0_ptr, st0_tag)) )
+ set_precision_flag(flags);
+
+ setexponent16(st0_ptr, 63);
+ tag = FPU_normalize_nuo(st0_ptr,
+ EXTENDED_Ebias); /* No underflow or overflow
+ is possible */
+ setsign(st0_ptr, sign);
+ FPU_settag0(tag);
+ return;
+ }
+
+ if ( st0_tag == TAG_Zero )
+ return;
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+
+ if ( st0_tag == TW_Denormal )
+ goto denormal_arg;
+ else if ( st0_tag == TW_Infinity )
+ return;
+ else
+ single_arg_error(st0_ptr, st0_tag);
+}
+
+
+static int fsin(FPU_REG *st0_ptr, u_char tag)
+{
+ u_char arg_sign = getsign(st0_ptr);
+
+ if ( tag == TAG_Valid )
+ {
+ u32 q;
+
+ if ( exponent(st0_ptr) > -40 )
+ {
+ if ( (q = trig_arg(st0_ptr, 0)) == -1 )
+ {
+ /* Operand is out of range */
+ return 1;
+ }
+
+ poly_sine(st0_ptr);
+
+ if (q & 2)
+ changesign(st0_ptr);
+
+ setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
+
+ /* We do not really know if up or down */
+ set_precision_flag_up();
+ return 0;
+ }
+ else
+ {
+ /* For a small arg, the result == the argument */
+ set_precision_flag_up(); /* Must be up. */
+ return 0;
+ }
+ }
+
+ if ( tag == TAG_Zero )
+ {
+ setcc(0);
+ return 0;
+ }
+
+ if ( tag == TAG_Special )
+ tag = FPU_Special(st0_ptr);
+
+ if ( tag == TW_Denormal )
+ {
+ if ( denormal_operand() < 0 )
+ return 1;
+
+ /* For a small arg, the result == the argument */
+ /* Underflow may happen */
+ FPU_to_exp16(st0_ptr, st0_ptr);
+
+ tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+
+ FPU_settag0(tag);
+
+ return 0;
+ }
+ else if ( tag == TW_Infinity )
+ {
+ /* The 80486 treats infinity as an invalid operand */
+ arith_invalid(0);
+ return 1;
+ }
+ else
+ {
+ single_arg_error(st0_ptr, tag);
+ return 1;
+ }
+}
+
+
+static int f_cos(FPU_REG *st0_ptr, u_char tag)
+{
+ u_char st0_sign;
+
+ st0_sign = getsign(st0_ptr);
+
+ if ( tag == TAG_Valid )
+ {
+ u32 q;
+
+ if ( exponent(st0_ptr) > -40 )
+ {
+ if ( (exponent(st0_ptr) < 0)
+ || ((exponent(st0_ptr) == 0)
+ && (significand(st0_ptr) <= BX_CONST64(0xc90fdaa22168c234))) )
+ {
+ poly_cos(st0_ptr);
+
+ /* We do not really know if up or down */
+ set_precision_flag_down();
+
+ return 0;
+ }
+ else if ( (q = trig_arg(st0_ptr, FCOS)) != -1 )
+ {
+ poly_sine(st0_ptr);
+
+ if ((q+1) & 2)
+ changesign(st0_ptr);
+
+ /* We do not really know if up or down */
+ set_precision_flag_down();
+
+ return 0;
+ }
+ else
+ {
+ /* Operand is out of range */
+ return 1;
+ }
+ }
+ else
+ {
+ denormal_arg:
+
+ setcc(0);
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+#ifdef PECULIAR_486
+ set_precision_flag_down(); /* 80486 appears to do this. */
+#else
+ set_precision_flag_up(); /* Must be up. */
+#endif /* PECULIAR_486 */
+ return 0;
+ }
+ }
+ else if ( tag == TAG_Zero )
+ {
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ setcc(0);
+ return 0;
+ }
+
+ if ( tag == TAG_Special )
+ tag = FPU_Special(st0_ptr);
+
+ if ( tag == TW_Denormal )
+ {
+ if ( denormal_operand() < 0 )
+ return 1;
+
+ goto denormal_arg;
+ }
+ else if ( tag == TW_Infinity )
+ {
+ /* The 80486 treats infinity as an invalid operand */
+ arith_invalid(0);
+ return 1;
+ }
+ else
+ {
+ single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
+ return 1;
+ }
+}
+
+
+static void fcos(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ f_cos(st0_ptr, st0_tag);
+}
+
+
+static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st_new_ptr;
+ FPU_REG arg;
+ u_char tag;
+
+ /* Stack underflow has higher priority */
+ if ( st0_tag == TAG_Empty )
+ {
+ FPU_stack_underflow(); /* Puts a QNaN in st(0) */
+ if ( control_word & CW_Invalid )
+ {
+ st_new_ptr = &st(-1);
+ push();
+ FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */
+ }
+ return;
+ }
+
+ if ( STACK_OVERFLOW )
+ { FPU_stack_overflow(); return; }
+
+ if ( st0_tag == TAG_Special )
+ tag = FPU_Special(st0_ptr);
+ else
+ tag = st0_tag;
+
+ if ( tag == TW_NaN )
+ {
+ single_arg_2_error(st0_ptr, TW_NaN);
+ return;
+ }
+ else if ( tag == TW_Infinity )
+ {
+ /* The 80486 treats infinity as an invalid operand */
+ if ( arith_invalid(0) >= 0 )
+ {
+ /* Masked response */
+ push();
+ arith_invalid(0);
+ }
+ return;
+ }
+
+ reg_copy(st0_ptr, &arg);
+ if ( !fsin(st0_ptr, st0_tag) )
+ {
+ push();
+ FPU_copy_to_reg0(&arg, st0_tag);
+ f_cos(&st(0), st0_tag);
+ }
+ else
+ {
+ /* An error, so restore st(0) */
+ FPU_copy_to_reg0(&arg, st0_tag);
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* The following all require two arguments: st(0) and st(1) */
+
+/* A lean, mean kernel for the fprem instructions. This relies upon
+ the division and rounding to an integer in do_fprem giving an
+ exact result. Because of this, rem_kernel() needs to deal only with
+ the least significant 64 bits, the more significant bits of the
+ result must be zero.
+ */
+static void rem_kernel(u64 st0, u64 *y, u64 st1, u64 q, int n)
+{
+ u64 x;
+
+#ifdef NO_ASSEMBLER
+ u64 work;
+
+ x = st0 << n;
+
+ work = (u32)st1;
+ work *= (u32)q;
+ x -= work;
+
+ work = st1 >> 32;
+ work *= (u32)q;
+ x -= work;
+
+ work = (u32)st1;
+ work *= q >> 32;
+ x -= work;
+
+#else
+ int dummy;
+
+ x = st0 << n;
+
+ /* Do the required multiplication and subtraction in the one operation */
+
+ /* lsw x -= lsw st1 * lsw q */
+ asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
+ :"=m" (((u32 *)&x)[0]), "=m" (((u32 *)&x)[1]),
+ "=a" (dummy)
+ :"2" (((u32 *)&st1)[0]), "m" (((u32 *)&q)[0])
+ :"%dx");
+ /* msw x -= msw st1 * lsw q */
+ asm volatile ("mull %3; subl %%eax,%0"
+ :"=m" (((u32 *)&x)[1]), "=a" (dummy)
+ :"1" (((u32 *)&st1)[1]), "m" (((u32 *)&q)[0])
+ :"%dx");
+ /* msw x -= lsw st1 * msw q */
+ asm volatile ("mull %3; subl %%eax,%0"
+ :"=m" (((u32 *)&x)[1]), "=a" (dummy)
+ :"1" (((u32 *)&st1)[0]), "m" (((u32 *)&q)[1])
+ :"%dx");
+#endif
+
+ *y = x;
+}
+
+
+/* Remainder of st(0) / st(1) */
+/* This routine produces exact results, i.e. there is never any
+ rounding or truncation, etc of the result. */
+static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
+{
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+
+ if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+ {
+ FPU_REG tmp, st0, st1;
+ u_char st0_sign, st1_sign;
+ u_char tmptag;
+ int tag;
+ int old_cw;
+ int expdif;
+ s64 q;
+ u16 saved_status;
+ int cc;
+
+ fprem_valid:
+ /* Convert registers for internal use. */
+ st0_sign = FPU_to_exp16(st0_ptr, &st0);
+ st1_sign = FPU_to_exp16(st1_ptr, &st1);
+ expdif = exponent16(&st0) - exponent16(&st1);
+
+ old_cw = control_word;
+ cc = 0;
+
+ /* We want the status following the denorm tests, but don't want
+ the status changed by the arithmetic operations. */
+ saved_status = partial_status;
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+
+ if ( expdif < 64 )
+ {
+ /* This should be the most common case */
+
+ if ( expdif > -2 )
+ {
+ u_char sign = st0_sign ^ st1_sign;
+ tag = FPU_u_div(&st0, &st1, &tmp,
+ PR_64_BITS | RC_CHOP | 0x3f,
+ sign);
+ setsign(&tmp, sign);
+
+ if ( exponent(&tmp) >= 0 )
+ {
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
+ overflow to 2^64 */
+ q = significand(&tmp);
+
+ rem_kernel(significand(&st0),
+ &significand(&tmp),
+ significand(&st1),
+ q, expdif);
+
+ setexponent16(&tmp, exponent16(&st1));
+ }
+ else
+ {
+ reg_copy(&st0, &tmp);
+ q = 0;
+ }
+
+ if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
+ {
+ /* We may need to subtract st(1) once more,
+ to get a result <= 1/2 of st(1). */
+ u64 x;
+ expdif = exponent16(&st1) - exponent16(&tmp);
+ if ( expdif <= 1 )
+ {
+ if ( expdif == 0 )
+ x = significand(&st1) - significand(&tmp);
+ else /* expdif is 1 */
+ x = (significand(&st1) << 1) - significand(&tmp);
+ if ( (x < significand(&tmp)) ||
+ /* or equi-distant (from 0 & st(1)) and q is odd */
+ ((x == significand(&tmp)) && (q & 1) ) )
+ {
+ st0_sign = ! st0_sign;
+ significand(&tmp) = x;
+ q++;
+ }
+ }
+ }
+
+ if (q & 4) cc |= SW_C0;
+ if (q & 2) cc |= SW_C3;
+ if (q & 1) cc |= SW_C1;
+ }
+ else
+ {
+ control_word = old_cw;
+ setcc(0);
+ return;
+ }
+ }
+ else
+ {
+ /* There is a large exponent difference ( >= 64 ) */
+ /* To make much sense, the code in this section should
+ be done at high precision. */
+ int exp_1, N;
+ u_char sign;
+
+ /* prevent overflow here */
+ /* N is 'a number between 32 and 63' (p26-113) */
+ reg_copy(&st0, &tmp);
+ tmptag = st0_tag;
+ N = (expdif & 0x0000001f) + 32; /* This choice gives results
+ identical to an AMD 486 */
+ setexponent16(&tmp, N);
+ exp_1 = exponent16(&st1);
+ setexponent16(&st1, 0);
+ expdif -= N;
+
+ sign = getsign(&tmp) ^ st1_sign;
+ tag = FPU_u_div(&tmp, &st1, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
+ sign);
+ setsign(&tmp, sign);
+
+ FPU_round_to_int(&tmp, tag); /* Fortunately, this can't
+ overflow to 2^64 */
+
+ rem_kernel(significand(&st0),
+ &significand(&tmp),
+ significand(&st1),
+ significand(&tmp),
+ exponent(&tmp)
+ );
+ setexponent16(&tmp, exp_1 + expdif);
+
+ /* It is possible for the operation to be complete here.
+ What does the IEEE standard say? The Intel 80486 manual
+ implies that the operation will never be completed at this
+ point, and the behaviour of a real 80486 confirms this.
+ */
+ if ( !(tmp.sigh | tmp.sigl) )
+ {
+ /* The result is zero */
+ control_word = old_cw;
+ partial_status = saved_status;
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(&st0, st0_sign);
+#ifdef PECULIAR_486
+ setcc(SW_C2);
+#else
+ setcc(0);
+#endif /* PECULIAR_486 */
+ return;
+ }
+ cc = SW_C2;
+ }
+
+ control_word = old_cw;
+ partial_status = saved_status;
+ tag = FPU_normalize_nuo(&tmp, 0);
+ reg_copy(&tmp, st0_ptr);
+
+ /* The only condition to be looked for is underflow,
+ and it can occur here only if underflow is unmasked. */
+ if ( (exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
+ && !(control_word & CW_Underflow) )
+ {
+ setcc(cc);
+ tag = arith_underflow(st0_ptr);
+ setsign(st0_ptr, st0_sign);
+ FPU_settag0(tag);
+ return;
+ }
+ else if ( (exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero) )
+ {
+ stdexp(st0_ptr);
+ setsign(st0_ptr, st0_sign);
+ }
+ else
+ {
+ tag = FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
+ }
+ FPU_settag0(tag);
+ setcc(cc);
+
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st1_tag == TAG_Special )
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+ {
+ if ( denormal_operand() < 0 )
+ return;
+ goto fprem_valid;
+ }
+ else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+ {
+ FPU_stack_underflow();
+ return;
+ }
+ else if ( st0_tag == TAG_Zero )
+ {
+ if ( st1_tag == TAG_Valid )
+ {
+ setcc(0); return;
+ }
+ else if ( st1_tag == TW_Denormal )
+ {
+ if ( denormal_operand() < 0 )
+ return;
+ setcc(0); return;
+ }
+ else if ( st1_tag == TAG_Zero )
+ { arith_invalid(0); return; } /* fprem(?,0) always invalid */
+ else if ( st1_tag == TW_Infinity )
+ { setcc(0); return; }
+ }
+ else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+ {
+ if ( st1_tag == TAG_Zero )
+ {
+ arith_invalid(0); /* fprem(Valid,Zero) is invalid */
+ return;
+ }
+ else if ( st1_tag != TW_NaN )
+ {
+ if ( ((st0_tag == TW_Denormal) || (st1_tag == TW_Denormal))
+ && (denormal_operand() < 0) )
+ return;
+
+ if ( st1_tag == TW_Infinity )
+ {
+ /* fprem(Valid,Infinity) is o.k. */
+ setcc(0); return;
+ }
+ }
+ }
+ else if ( st0_tag == TW_Infinity )
+ {
+ if ( st1_tag != TW_NaN )
+ {
+ arith_invalid(0); /* fprem(Infinity,?) is invalid */
+ return;
+ }
+ }
+
+ /* One of the registers must contain a NaN if we got here. */
+
+#ifdef PARANOID
+ if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) )
+ EXCEPTION(EX_INTERNAL | 0x118);
+#endif /* PARANOID */
+
+ real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
+
+}
+
+
+/* ST(1) <- ST(1) * log ST; pop ST */
+static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st1_ptr = &st(1), exponent;
+ u_char st1_tag = FPU_gettagi(1);
+ u_char sign;
+ int e, tag;
+
+ clear_C1();
+
+ if ( (st0_tag == TAG_Valid) && (st1_tag == TAG_Valid) )
+ {
+ both_valid:
+ /* Both regs are Valid or Denormal */
+ if ( signpositive(st0_ptr) )
+ {
+ if ( st0_tag == TW_Denormal )
+ FPU_to_exp16(st0_ptr, st0_ptr);
+ else
+ /* Convert st(0) for internal use. */
+ setexponent16(st0_ptr, exponent(st0_ptr));
+
+ if ( (st0_ptr->sigh == 0x80000000) && (st0_ptr->sigl == 0) )
+ {
+ /* Special case. The result can be precise. */
+ u_char esign;
+ e = exponent16(st0_ptr);
+ if ( e >= 0 )
+ {
+ exponent.sigh = e;
+ esign = SIGN_POS;
+ }
+ else
+ {
+ exponent.sigh = -e;
+ esign = SIGN_NEG;
+ }
+ exponent.sigl = 0;
+ setexponent16(&exponent, 31);
+ tag = FPU_normalize_nuo(&exponent, 0);
+ stdexp(&exponent);
+ setsign(&exponent, esign);
+ tag = FPU_mul(&exponent, tag, 1, FULL_PRECISION);
+ if ( tag >= 0 )
+ FPU_settagi(1, tag);
+ }
+ else
+ {
+ /* The usual case */
+ sign = getsign(st1_ptr);
+ if ( st1_tag == TW_Denormal )
+ FPU_to_exp16(st1_ptr, st1_ptr);
+ else
+ /* Convert st(1) for internal use. */
+ setexponent16(st1_ptr, exponent(st1_ptr));
+ poly_l2(st0_ptr, st1_ptr, sign);
+ }
+ }
+ else
+ {
+ /* negative */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+
+ FPU_pop();
+
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st1_tag == TAG_Special )
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
+ {
+ FPU_stack_underflow_pop(1);
+ return;
+ }
+ else if ( (st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal) )
+ {
+ if ( st0_tag == TAG_Zero )
+ {
+ if ( st1_tag == TAG_Zero )
+ {
+ /* Both args zero is invalid */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+ else
+ {
+ u_char sign;
+ sign = getsign(st1_ptr)^SIGN_NEG;
+ if ( FPU_divide_by_zero(1, sign) < 0 )
+ return;
+
+ setsign(st1_ptr, sign);
+ }
+ }
+ else if ( st1_tag == TAG_Zero )
+ {
+ /* st(1) contains zero, st(0) valid <> 0 */
+ /* Zero is the valid answer */
+ sign = getsign(st1_ptr);
+
+ if ( signnegative(st0_ptr) )
+ {
+ /* log(negative) */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+ else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+ else
+ {
+ if ( exponent(st0_ptr) < 0 )
+ sign ^= SIGN_NEG;
+
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ setsign(st1_ptr, sign);
+ }
+ }
+ else
+ {
+ /* One or both operands are denormals. */
+ if ( denormal_operand() < 0 )
+ return;
+ goto both_valid;
+ }
+ }
+ else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+ {
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+ return;
+ }
+ /* One or both arg must be an infinity */
+ else if ( st0_tag == TW_Infinity )
+ {
+ if ( (signnegative(st0_ptr)) || (st1_tag == TAG_Zero) )
+ {
+ /* log(-infinity) or 0*log(infinity) */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+ else
+ {
+ u_char sign = getsign(st1_ptr);
+
+ if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+ setsign(st1_ptr, sign);
+ }
+ }
+ /* st(1) must be infinity here */
+ else if ( ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
+ && ( signpositive(st0_ptr) ) )
+ {
+ if ( exponent(st0_ptr) >= 0 )
+ {
+ if ( (exponent(st0_ptr) == 0) &&
+ (st0_ptr->sigh == 0x80000000) &&
+ (st0_ptr->sigl == 0) )
+ {
+ /* st(0) holds 1.0 */
+ /* infinity*log(1) */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+ /* else st(0) is positive and > 1.0 */
+ }
+ else
+ {
+ /* st(0) is positive and < 1.0 */
+
+ if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ changesign(st1_ptr);
+ }
+ }
+ else
+ {
+ /* st(0) must be zero or negative */
+ if ( st0_tag == TAG_Zero )
+ {
+ /* This should be invalid, but a real 80486 is happy with it. */
+
+#ifndef PECULIAR_486
+ sign = getsign(st1_ptr);
+ if ( FPU_divide_by_zero(1, sign) < 0 )
+ return;
+#endif /* PECULIAR_486 */
+
+ changesign(st1_ptr);
+ }
+ else if ( arith_invalid(1) < 0 ) /* log(negative) */
+ return;
+ }
+
+ FPU_pop();
+}
+
+
+static void fpatan(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+ int tag;
+
+ clear_C1();
+ if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+ {
+ valid_atan:
+
+ poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
+
+ FPU_pop();
+
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st1_tag == TAG_Special )
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+ {
+ if ( denormal_operand() < 0 )
+ return;
+
+ goto valid_atan;
+ }
+ else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
+ {
+ FPU_stack_underflow_pop(1);
+ return;
+ }
+ else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+ {
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0 )
+ FPU_pop();
+ return;
+ }
+ else if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
+ {
+ u_char sign = getsign(st1_ptr);
+ if ( st0_tag == TW_Infinity )
+ {
+ if ( st1_tag == TW_Infinity )
+ {
+ if ( signpositive(st0_ptr) )
+ {
+ FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
+ }
+ else
+ {
+ setpositive(st1_ptr);
+ tag = FPU_u_add(&CONST_PI4, &CONST_PI2, st1_ptr,
+ FULL_PRECISION, SIGN_POS,
+ exponent(&CONST_PI4), exponent(&CONST_PI2));
+ if ( tag >= 0 )
+ FPU_settagi(1, tag);
+ }
+ }
+ else
+ {
+ if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ if ( signpositive(st0_ptr) )
+ {
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ setsign(st1_ptr, sign); /* An 80486 preserves the sign */
+ FPU_pop();
+ return;
+ }
+ else
+ {
+ FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+ }
+ }
+ }
+ else
+ {
+ /* st(1) is infinity, st(0) not infinity */
+ if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+ }
+ setsign(st1_ptr, sign);
+ }
+ else if ( st1_tag == TAG_Zero )
+ {
+ /* st(0) must be valid or zero */
+ u_char sign = getsign(st1_ptr);
+
+ if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ if ( signpositive(st0_ptr) )
+ {
+ /* An 80486 preserves the sign */
+ FPU_pop();
+ return;
+ }
+
+ FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+ setsign(st1_ptr, sign);
+ }
+ else if ( st0_tag == TAG_Zero )
+ {
+ /* st(1) must be TAG_Valid here */
+ u_char sign = getsign(st1_ptr);
+
+ if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+ setsign(st1_ptr, sign);
+ }
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL | 0x125);
+#endif /* PARANOID */
+
+ FPU_pop();
+ set_precision_flag_up(); /* We do not really know if up or down */
+}
+
+
+static void fprem(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ do_fprem(st0_ptr, st0_tag, RC_CHOP);
+}
+
+
+static void fprem1(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ do_fprem(st0_ptr, st0_tag, RC_RND);
+}
+
+
+static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ u_char sign, sign1;
+ FPU_REG *st1_ptr = &st(1), a, b;
+ u_char st1_tag = FPU_gettagi(1);
+
+ clear_C1();
+ if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+ {
+ valid_yl2xp1:
+
+ sign = getsign(st0_ptr);
+ sign1 = getsign(st1_ptr);
+
+ FPU_to_exp16(st0_ptr, &a);
+ FPU_to_exp16(st1_ptr, &b);
+
+ if ( poly_l2p1(sign, sign1, &a, &b, st1_ptr) )
+ return;
+
+ FPU_pop();
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st1_tag == TAG_Special )
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
+ || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
+ {
+ if ( denormal_operand() < 0 )
+ return;
+
+ goto valid_yl2xp1;
+ }
+ else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
+ {
+ FPU_stack_underflow_pop(1);
+ return;
+ }
+ else if ( st0_tag == TAG_Zero )
+ {
+ switch ( st1_tag )
+ {
+ case TW_Denormal:
+ if ( denormal_operand() < 0 )
+ return;
+
+ case TAG_Zero:
+ case TAG_Valid:
+ setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
+ FPU_copy_to_reg1(st0_ptr, st0_tag);
+ break;
+
+ case TW_Infinity:
+ /* Infinity*log(1) */
+ if ( arith_invalid(1) < 0 )
+ return;
+ break;
+
+ case TW_NaN:
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+ return;
+ break;
+
+ default:
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL | 0x116);
+ return;
+#endif /* PARANOID */
+ }
+ }
+ else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+ {
+ switch ( st1_tag )
+ {
+ case TAG_Zero:
+ if ( signnegative(st0_ptr) )
+ {
+ if ( exponent(st0_ptr) >= 0 )
+ {
+ /* st(0) holds <= -1.0 */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
+#else
+ if ( arith_invalid(1) < 0 )
+ return;
+#endif /* PECULIAR_486 */
+ }
+ else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+ else
+ changesign(st1_ptr);
+ }
+ else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+ break;
+
+ case TW_Infinity:
+ if ( signnegative(st0_ptr) )
+ {
+ if ( (exponent(st0_ptr) >= 0) &&
+ !((st0_ptr->sigh == 0x80000000) &&
+ (st0_ptr->sigl == 0)) )
+ {
+ /* st(0) holds < -1.0 */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
+#else
+ if ( arith_invalid(1) < 0 ) return;
+#endif /* PECULIAR_486 */
+ }
+ else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+ else
+ changesign(st1_ptr);
+ }
+ else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+ break;
+
+ case TW_NaN:
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+ return;
+ }
+
+ }
+ else if ( st0_tag == TW_NaN )
+ {
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+ return;
+ }
+ else if ( st0_tag == TW_Infinity )
+ {
+ if ( st1_tag == TW_NaN )
+ {
+ if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
+ return;
+ }
+ else if ( signnegative(st0_ptr) )
+ {
+#ifndef PECULIAR_486
+ /* This should have higher priority than denormals, but... */
+ if ( arith_invalid(1) < 0 ) /* log(-infinity) */
+ return;
+#endif /* PECULIAR_486 */
+ if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+#ifdef PECULIAR_486
+ /* Denormal operands actually get higher priority */
+ if ( arith_invalid(1) < 0 ) /* log(-infinity) */
+ return;
+#endif /* PECULIAR_486 */
+ }
+ else if ( st1_tag == TAG_Zero )
+ {
+ /* log(infinity) */
+ if ( arith_invalid(1) < 0 )
+ return;
+ }
+
+ /* st(1) must be valid here. */
+
+ else if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ /* The Manual says that log(Infinity) is invalid, but a real
+ 80486 sensibly says that it is o.k. */
+ else
+ {
+ u_char sign = getsign(st1_ptr);
+ FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+ setsign(st1_ptr, sign);
+ }
+ }
+#ifdef PARANOID
+ else
+ {
+ EXCEPTION(EX_INTERNAL | 0x117);
+ return;
+ }
+#endif /* PARANOID */
+
+ FPU_pop();
+ return;
+
+}
+
+
+static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
+{
+ FPU_REG *st1_ptr = &st(1);
+ u_char st1_tag = FPU_gettagi(1);
+ int old_cw = control_word;
+ u_char sign = getsign(st0_ptr);
+
+ clear_C1();
+ if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
+ {
+ s32 scale;
+ FPU_REG tmp;
+
+ /* Convert register for internal use. */
+ setexponent16(st0_ptr, exponent(st0_ptr));
+
+ valid_scale:
+
+ if ( exponent(st1_ptr) > 30 )
+ {
+ /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
+
+ if ( signpositive(st1_ptr) )
+ {
+ EXCEPTION(EX_Overflow);
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ }
+ else
+ {
+ EXCEPTION(EX_Underflow);
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ }
+ setsign(st0_ptr, sign);
+ return;
+ }
+
+ control_word &= ~CW_RC;
+ control_word |= RC_CHOP;
+ reg_copy(st1_ptr, &tmp);
+ FPU_round_to_int(&tmp, st1_tag); /* This can never overflow here */
+ control_word = old_cw;
+ scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
+ scale += exponent16(st0_ptr);
+
+ setexponent16(st0_ptr, scale);
+
+ /* Use FPU_round() to properly detect under/overflow etc */
+ FPU_round(st0_ptr, 0, 0, control_word, sign);
+
+ return;
+ }
+
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st1_tag == TAG_Special )
+ st1_tag = FPU_Special(st1_ptr);
+
+ if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
+ {
+ switch ( st1_tag )
+ {
+ case TAG_Valid:
+ /* st(0) must be a denormal */
+ if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
+ goto valid_scale;
+
+ case TAG_Zero:
+ if ( st0_tag == TW_Denormal )
+ denormal_operand();
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
+ return;
+
+ if ( signpositive(st1_ptr) )
+ FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+ else
+ FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+ setsign(st0_ptr, sign);
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ }
+ else if ( st0_tag == TAG_Zero )
+ {
+ switch ( st1_tag )
+ {
+ case TAG_Valid:
+ case TAG_Zero:
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if ( signpositive(st1_ptr) )
+ arith_invalid(0); /* Zero scaled by +Infinity */
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ }
+ else if ( st0_tag == TW_Infinity )
+ {
+ switch ( st1_tag )
+ {
+ case TAG_Valid:
+ case TAG_Zero:
+ return;
+
+ case TW_Denormal:
+ denormal_operand();
+ return;
+
+ case TW_Infinity:
+ if ( signnegative(st1_ptr) )
+ arith_invalid(0); /* Infinity scaled by -Infinity */
+ return;
+
+ case TW_NaN:
+ real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+ return;
+ }
+ }
+ else if ( st0_tag == TW_NaN )
+ {
+ if ( st1_tag != TAG_Empty )
+ { real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); return; }
+ }
+
+#ifdef PARANOID
+ if ( !((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) )
+ {
+ EXCEPTION(EX_INTERNAL | 0x115);
+ return;
+ }
+#endif
+
+ /* At least one of st(0), st(1) must be empty */
+ FPU_stack_underflow();
+
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+static FUNC_ST0 const trig_table_a[] = {
+ f2xm1, fyl2x, fptan, fpatan,
+ fxtract, fprem1, (FUNC_ST0)fdecstp, (FUNC_ST0)fincstp
+};
+
+void FPU_triga(void)
+{
+ (trig_table_a[FPU_rm])(&st(0), FPU_gettag0());
+}
+
+
+static FUNC_ST0 const trig_table_b[] =
+ {
+ fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0)fsin, fcos
+ };
+
+void FPU_trigb(void)
+{
+ (trig_table_b[FPU_rm])(&st(0), FPU_gettag0());
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | get_address.c |
+ | |
+ | Get the effective address from an FPU instruction. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+
+#include <linux/stddef.h>
+
+#include <asm/uaccess.h>
+#include <asm/desc.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#define FPU_WRITE_BIT 0x10
+
+static int reg_offset[] = {
+ offsetof(struct info,___eax),
+ offsetof(struct info,___ecx),
+ offsetof(struct info,___edx),
+ offsetof(struct info,___ebx),
+ offsetof(struct info,___esp),
+ offsetof(struct info,___ebp),
+ offsetof(struct info,___esi),
+ offsetof(struct info,___edi)
+};
+
+#define REG_(x) (*(s32 *)(reg_offset[(x)]+(u_char *) FPU_info))
+
+static int reg_offset_vm86[] = {
+ offsetof(struct info,___cs),
+ offsetof(struct info,___vm86_ds),
+ offsetof(struct info,___vm86_es),
+ offsetof(struct info,___vm86_fs),
+ offsetof(struct info,___vm86_gs),
+ offsetof(struct info,___ss),
+ offsetof(struct info,___vm86_ds)
+ };
+
+#define VM86_REG_(x) (*(unsigned short *) \
+ (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info))
+
+/* These are dummy, fs and gs are not saved on the stack. */
+#define ___FS ___ds
+#define ___GS ___ds
+
+static int reg_offset_pm[] = {
+ offsetof(struct info,___cs),
+ offsetof(struct info,___ds),
+ offsetof(struct info,___es),
+ offsetof(struct info,___FS),
+ offsetof(struct info,___GS),
+ offsetof(struct info,___ss),
+ offsetof(struct info,___ds)
+ };
+
+#define PM_REG_(x) (*(unsigned short *) \
+ (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info))
+
+
+/* Decode the SIB byte. This function assumes mod != 0 */
+static int sib(int mod, u32 *fpu_eip)
+{
+ u_char ss,index,base;
+ s32 offset;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(base, (u_char *) (*fpu_eip)); /* The SIB byte */
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ ss = base >> 6;
+ index = (base >> 3) & 7;
+ base &= 7;
+
+ if ((mod == 0) && (base == 5))
+ offset = 0; /* No base register */
+ else
+ offset = REG_(base);
+
+ if (index == 4)
+ {
+ /* No index register */
+ /* A non-zero ss is illegal */
+ if ( ss )
+ EXCEPTION(EX_Invalid);
+ }
+ else
+ {
+ offset += (REG_(index)) << ss;
+ }
+
+ if (mod == 1)
+ {
+ /* 8 bit signed displacement */
+ s32 displacement;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(displacement, (signed char *) (*fpu_eip));
+ offset += displacement;
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ }
+ else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
+ {
+ /* 32 bit displacement */
+ s32 displacement;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(4);
+ FPU_get_user(displacement, (s32 *) (*fpu_eip));
+ offset += displacement;
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip) += 4;
+ }
+
+ return offset;
+}
+
+
+static u32 vm86_segment(u_char segment,
+ struct address *addr)
+{
+ segment--;
+#ifdef PARANOID
+ if ( segment > PREFIX_SS_ )
+ {
+ EXCEPTION(EX_INTERNAL|0x130);
+ math_abort(FPU_info,SIGSEGV);
+ }
+#endif /* PARANOID */
+ addr->selector = VM86_REG_(segment);
+ return (u32)VM86_REG_(segment) << 4;
+}
+
+
+/* This should work for 16 and 32 bit protected mode. */
+static s32 pm_address(u_char FPU_modrm, u_char segment,
+ struct address *addr, s32 offset)
+{
+ struct desc_struct descriptor;
+ u32 base_address, limit, address, seg_top;
+
+ segment--;
+
+#ifdef PARANOID
+ /* segment is unsigned, so this also detects if segment was 0: */
+ if ( segment > PREFIX_SS_ )
+ {
+ EXCEPTION(EX_INTERNAL|0x132);
+ math_abort(FPU_info,SIGSEGV);
+ }
+#endif /* PARANOID */
+
+ switch ( segment )
+ {
+ /* fs and gs aren't used by the kernel, so they still have their
+ user-space values. */
+ case PREFIX_FS_-1:
+ /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+ in the assembler statement. */
+ __asm__("mov %%fs,%0":"=r" ((unsigned short)addr->selector));
+ break;
+ case PREFIX_GS_-1:
+ /* The cast is needed here to get gcc 2.8.0 to use a 16 bit register
+ in the assembler statement. */
+ __asm__("mov %%gs,%0":"=r" ((unsigned short)addr->selector));
+ break;
+ default:
+ addr->selector = PM_REG_(segment);
+ }
+
+ descriptor = LDT_DESCRIPTOR(PM_REG_(segment));
+ base_address = SEG_BASE_ADDR(descriptor);
+ address = base_address + offset;
+ limit = base_address
+ + (SEG_LIMIT(descriptor)+1) * SEG_GRANULARITY(descriptor) - 1;
+ if ( limit < base_address ) limit = 0xffffffff;
+
+ if ( SEG_EXPAND_DOWN(descriptor) )
+ {
+ if ( SEG_G_BIT(descriptor) )
+ seg_top = 0xffffffff;
+ else
+ {
+ seg_top = base_address + (1 << 20);
+ if ( seg_top < base_address ) seg_top = 0xffffffff;
+ }
+ access_limit =
+ (address <= limit) || (address >= seg_top) ? 0 :
+ ((seg_top-address) >= 255 ? 255 : seg_top-address);
+ }
+ else
+ {
+ access_limit =
+ (address > limit) || (address < base_address) ? 0 :
+ ((limit-address) >= 254 ? 255 : limit-address+1);
+ }
+ if ( SEG_EXECUTE_ONLY(descriptor) ||
+ (!SEG_WRITE_PERM(descriptor) && (FPU_modrm & FPU_WRITE_BIT)) )
+ {
+ access_limit = 0;
+ }
+ return address;
+}
+
+
+/*
+ MOD R/M byte: MOD == 3 has a special use for the FPU
+ SIB byte used iff R/M = 100b
+
+ 7 6 5 4 3 2 1 0
+ ..... ......... .........
+ MOD OPCODE(2) R/M
+
+
+ SIB byte
+
+ 7 6 5 4 3 2 1 0
+ ..... ......... .........
+ SS INDEX BASE
+
+*/
+
+void *FPU_get_address(u_char FPU_modrm, u32 *fpu_eip,
+ struct address *addr,
+ fpu_addr_modes addr_modes)
+{
+ u_char mod;
+ unsigned rm = FPU_modrm & 7;
+ s32 *cpu_reg_ptr;
+ int address = 0; /* Initialized just to stop compiler warnings. */
+
+ /* Memory accessed via the cs selector is write protected
+ in `non-segmented' 32 bit protected mode. */
+ if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+ && (addr_modes.override.segment == PREFIX_CS_) )
+ {
+ math_abort(FPU_info,SIGSEGV);
+ }
+
+ addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
+
+ mod = (FPU_modrm >> 6) & 3;
+
+ if (rm == 4 && mod != 3)
+ {
+ address = sib(mod, fpu_eip);
+ }
+ else
+ {
+ cpu_reg_ptr = & REG_(rm);
+ switch (mod)
+ {
+ case 0:
+ if (rm == 5)
+ {
+ /* Special case: disp32 */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(4);
+ FPU_get_user(address, (u32 *) (*fpu_eip));
+ (*fpu_eip) += 4;
+ RE_ENTRANT_CHECK_ON;
+ addr->offset = address;
+ return (void *) address;
+ }
+ else
+ {
+ address = *cpu_reg_ptr; /* Just return the contents
+ of the cpu register */
+ addr->offset = address;
+ return (void *) address;
+ }
+ case 1:
+ /* 8 bit signed displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(address, (signed char *) (*fpu_eip));
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ break;
+ case 2:
+ /* 32 bit displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(4);
+ FPU_get_user(address, (s32 *) (*fpu_eip));
+ (*fpu_eip) += 4;
+ RE_ENTRANT_CHECK_ON;
+ break;
+ case 3:
+ /* Not legal for the FPU */
+ EXCEPTION(EX_Invalid);
+ }
+ address += *cpu_reg_ptr;
+ }
+
+ addr->offset = address;
+
+ switch ( addr_modes.default_mode )
+ {
+ case 0:
+ break;
+ case VM86:
+ address += vm86_segment(addr_modes.override.segment, addr);
+ break;
+ case PM16:
+ case SEG32:
+ address = pm_address(FPU_modrm, addr_modes.override.segment,
+ addr, address);
+ break;
+ default:
+ EXCEPTION(EX_INTERNAL|0x133);
+ }
+
+ return (void *)address;
+}
+
+
+void *FPU_get_address_16(u_char FPU_modrm, u32 *fpu_eip,
+ struct address *addr,
+ fpu_addr_modes addr_modes)
+{
+ u_char mod;
+ unsigned rm = FPU_modrm & 7;
+ int address = 0; /* Default used for mod == 0 */
+
+ /* Memory accessed via the cs selector is write protected
+ in `non-segmented' 32 bit protected mode. */
+ if ( !addr_modes.default_mode && (FPU_modrm & FPU_WRITE_BIT)
+ && (addr_modes.override.segment == PREFIX_CS_) )
+ {
+ math_abort(FPU_info,SIGSEGV);
+ }
+
+ addr->selector = FPU_DS; /* Default, for 32 bit non-segmented mode. */
+
+ mod = (FPU_modrm >> 6) & 3;
+
+ switch (mod)
+ {
+ case 0:
+ if (rm == 6)
+ {
+ /* Special case: disp16 */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(2);
+ FPU_get_user(address, (unsigned short *) (*fpu_eip));
+ (*fpu_eip) += 2;
+ RE_ENTRANT_CHECK_ON;
+ goto add_segment;
+ }
+ break;
+ case 1:
+ /* 8 bit signed displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(1);
+ FPU_get_user(address, (signed char *) (*fpu_eip));
+ RE_ENTRANT_CHECK_ON;
+ (*fpu_eip)++;
+ break;
+ case 2:
+ /* 16 bit displacement */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_code_verify_area(2);
+ FPU_get_user(address, (unsigned short *) (*fpu_eip));
+ (*fpu_eip) += 2;
+ RE_ENTRANT_CHECK_ON;
+ break;
+ case 3:
+ /* Not legal for the FPU */
+ EXCEPTION(EX_Invalid);
+ break;
+ }
+ switch ( rm )
+ {
+ case 0:
+ address += FPU_info->___ebx + FPU_info->___esi;
+ break;
+ case 1:
+ address += FPU_info->___ebx + FPU_info->___edi;
+ break;
+ case 2:
+ address += FPU_info->___ebp + FPU_info->___esi;
+ if ( addr_modes.override.segment == PREFIX_DEFAULT )
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 3:
+ address += FPU_info->___ebp + FPU_info->___edi;
+ if ( addr_modes.override.segment == PREFIX_DEFAULT )
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 4:
+ address += FPU_info->___esi;
+ break;
+ case 5:
+ address += FPU_info->___edi;
+ break;
+ case 6:
+ address += FPU_info->___ebp;
+ if ( addr_modes.override.segment == PREFIX_DEFAULT )
+ addr_modes.override.segment = PREFIX_SS_;
+ break;
+ case 7:
+ address += FPU_info->___ebx;
+ break;
+ }
+
+ add_segment:
+ address &= 0xffff;
+
+ addr->offset = address;
+
+ switch ( addr_modes.default_mode )
+ {
+ case 0:
+ break;
+ case VM86:
+ address += vm86_segment(addr_modes.override.segment, addr);
+ break;
+ case PM16:
+ case SEG32:
+ address = pm_address(FPU_modrm, addr_modes.override.segment,
+ addr, address);
+ break;
+ default:
+ EXCEPTION(EX_INTERNAL|0x131);
+ }
+
+ return (void *)address ;
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | load_store.c |
+ | |
+ | This file contains most of the code to interpret the FPU instructions |
+ | which load and store from user memory. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+#include <asm/uaccess.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "control_w.h"
+
+
+#define _NONE_ 0 /* st0_ptr etc not needed */
+#define _REG0_ 1 /* Will be storing st(0) */
+#define _PUSH_ 3 /* Need to check for space to push onto stack */
+#define _null_ 4 /* Function illegal or not implemented */
+
+#define pop_0() { FPU_settag0(TAG_Empty); top++; }
+
+
+static u_char const type_table[32] = {
+ _PUSH_, _PUSH_, _PUSH_, _PUSH_,
+ _null_, _null_, _null_, _null_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _REG0_, _REG0_, _REG0_, _REG0_,
+ _NONE_, _null_, _NONE_, _PUSH_,
+ _NONE_, _PUSH_, _null_, _PUSH_,
+ _NONE_, _null_, _NONE_, _REG0_,
+ _NONE_, _REG0_, _NONE_, _REG0_
+ };
+
+u_char const data_sizes_16[32] = {
+ 4, 4, 8, 2, 0, 0, 0, 0,
+ 4, 4, 8, 2, 4, 4, 8, 2,
+ 14, 0, 94, 10, 2, 10, 0, 8,
+ 14, 0, 94, 10, 2, 10, 2, 8
+};
+
+u_char const data_sizes_32[32] = {
+ 4, 4, 8, 2, 0, 0, 0, 0,
+ 4, 4, 8, 2, 4, 4, 8, 2,
+ 28, 0,108, 10, 2, 10, 0, 8,
+ 28, 0,108, 10, 2, 10, 2, 8
+};
+
+int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
+ void *data_address)
+{
+ FPU_REG loaded_data;
+ FPU_REG *st0_ptr;
+ u_char st0_tag = TAG_Empty; /* This is just to stop a gcc warning. */
+ u_char loaded_tag;
+
+ st0_ptr = NULL; /* Initialized just to stop compiler warnings. */
+
+ if ( addr_modes.default_mode & PROTECTED )
+ {
+ if ( addr_modes.default_mode == SEG32 )
+ {
+ if ( access_limit < data_sizes_32[type] )
+ math_abort(FPU_info,SIGSEGV);
+ }
+ else if ( addr_modes.default_mode == PM16 )
+ {
+ if ( access_limit < data_sizes_16[type] )
+ math_abort(FPU_info,SIGSEGV);
+ }
+#ifdef PARANOID
+ else
+ EXCEPTION(EX_INTERNAL|0x140);
+#endif /* PARANOID */
+ }
+
+ switch ( type_table[type] )
+ {
+ case _NONE_:
+ break;
+ case _REG0_:
+ st0_ptr = &st(0); /* Some of these instructions pop after
+ storing */
+ st0_tag = FPU_gettag0();
+ break;
+ case _PUSH_:
+ {
+ if ( FPU_gettagi(-1) != TAG_Empty )
+ { FPU_stack_overflow(); return 0; }
+ top--;
+ st0_ptr = &st(0);
+ }
+ break;
+ case _null_:
+ FPU_illegal();
+ return 0;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x141);
+ return 0;
+#endif /* PARANOID */
+ }
+
+ switch ( type )
+ {
+ case 000: /* fld m32real */
+ clear_C1();
+ loaded_tag = FPU_load_single((float *)data_address, &loaded_data);
+ if ( (loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0) )
+ {
+ top++;
+ break;
+ }
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 001: /* fild m32int */
+ clear_C1();
+ loaded_tag = FPU_load_int32((s32 *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 002: /* fld m64real */
+ clear_C1();
+ loaded_tag = FPU_load_double((double *)data_address, &loaded_data);
+ if ( (loaded_tag == TAG_Special)
+ && isNaN(&loaded_data)
+ && (real_1op_NaN(&loaded_data) < 0) )
+ {
+ top++;
+ break;
+ }
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 003: /* fild m16int */
+ clear_C1();
+ loaded_tag = FPU_load_int16((s16 *)data_address, &loaded_data);
+ FPU_copy_to_reg0(&loaded_data, loaded_tag);
+ break;
+ case 010: /* fst m32real */
+ clear_C1();
+ FPU_store_single(st0_ptr, st0_tag, (float *)data_address);
+ break;
+ case 011: /* fist m32int */
+ clear_C1();
+ FPU_store_int32(st0_ptr, st0_tag, (s32 *)data_address);
+ break;
+ case 012: /* fst m64real */
+ clear_C1();
+ FPU_store_double(st0_ptr, st0_tag, (double *)data_address);
+ break;
+ case 013: /* fist m16int */
+ clear_C1();
+ FPU_store_int16(st0_ptr, st0_tag, (s16 *)data_address);
+ break;
+ case 014: /* fstp m32real */
+ clear_C1();
+ if ( FPU_store_single(st0_ptr, st0_tag, (float *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 015: /* fistp m32int */
+ clear_C1();
+ if ( FPU_store_int32(st0_ptr, st0_tag, (s32 *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 016: /* fstp m64real */
+ clear_C1();
+ if ( FPU_store_double(st0_ptr, st0_tag, (double *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 017: /* fistp m16int */
+ clear_C1();
+ if ( FPU_store_int16(st0_ptr, st0_tag, (s16 *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 020: /* fldenv m14/28byte */
+ fldenv(addr_modes, (u_char *)data_address);
+ /* Ensure that the values just loaded are not changed by
+ fix-up operations. */
+ return 1;
+ case 022: /* frstor m94/108byte */
+ frstor(addr_modes, (u_char *)data_address);
+ /* Ensure that the values just loaded are not changed by
+ fix-up operations. */
+ return 1;
+ case 023: /* fbld m80dec */
+ clear_C1();
+ loaded_tag = FPU_load_bcd((u_char *)data_address);
+ FPU_settag0(loaded_tag);
+ break;
+ case 024: /* fldcw */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, data_address, 2);
+ FPU_get_user(control_word, (u16 *) data_address);
+ RE_ENTRANT_CHECK_ON;
+ if ( partial_status & ~control_word & CW_Exceptions )
+ partial_status |= (SW_Summary | SW_Backward);
+ else
+ partial_status &= ~(SW_Summary | SW_Backward);
+#ifdef PECULIAR_486
+ control_word |= 0x40; /* An 80486 appears to always set this bit */
+#endif /* PECULIAR_486 */
+ return 1;
+ case 025: /* fld m80real */
+ clear_C1();
+ loaded_tag = FPU_load_extended((long double *)data_address, 0);
+ FPU_settag0(loaded_tag);
+ break;
+ case 027: /* fild m64int */
+ clear_C1();
+ loaded_tag = FPU_load_int64((s64 *)data_address);
+ FPU_settag0(loaded_tag);
+ break;
+ case 030: /* fstenv m14/28byte */
+ fstenv(addr_modes, (u_char *)data_address);
+ return 1;
+ case 032: /* fsave */
+ fsave(addr_modes, (u_char *)data_address);
+ return 1;
+ case 033: /* fbstp m80dec */
+ clear_C1();
+ if ( FPU_store_bcd(st0_ptr, st0_tag, (u_char *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 034: /* fstcw m16int */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,data_address,2);
+ FPU_put_user(control_word, (u16 *) data_address);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ case 035: /* fstp m80real */
+ clear_C1();
+ if ( FPU_store_extended(st0_ptr, st0_tag, (long double *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ case 036: /* fstsw m2byte */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,data_address,2);
+ FPU_put_user(status_word(),(u16 *) data_address);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ case 037: /* fistp m64int */
+ clear_C1();
+ if ( FPU_store_int64(st0_ptr, st0_tag, (s64 *)data_address) )
+ pop_0(); /* pop only if the number was actually stored
+ (see the 80486 manual p16-28) */
+ break;
+ }
+ return 0;
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | mul_Xsig.S |
+ | |
+ | Multiply a 12 byte fixed point number by another fixed point number. |
+ | |
+ | Copyright (C) 1992,1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | Call from C as: |
+ | void mul32_Xsig(Xsig *x, unsigned b) |
+ | |
+ | void mul64_Xsig(Xsig *x, unsigned long long *b) |
+ | |
+ | void mul_Xsig_Xsig(Xsig *x, unsigned *b) |
+ | |
+ | The result is neither rounded nor normalized, and the ls bit or so may |
+ | be wrong. |
+ | |
+ +---------------------------------------------------------------------------*/
+ .file "mul_Xsig.S"
+
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(mul32_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $16,%esp
+ pushl %esi
+
+ movl PARAM1,%esi
+ movl PARAM2,%ecx
+
+ xor %eax,%eax
+ movl %eax,-4(%ebp)
+ movl %eax,-8(%ebp)
+
+ movl (%esi),%eax /* lsl of Xsig */
+ mull %ecx /* msl of b */
+ movl %edx,-12(%ebp)
+
+ movl 4(%esi),%eax /* midl of Xsig */
+ mull %ecx /* msl of b */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull %ecx /* msl of b */
+ addl %eax,-8(%ebp)
+ adcl %edx,-4(%ebp)
+
+ movl -12(%ebp),%eax
+ movl %eax,(%esi)
+ movl -8(%ebp),%eax
+ movl %eax,4(%esi)
+ movl -4(%ebp),%eax
+ movl %eax,8(%esi)
+
+ popl %esi
+ leave
+ ret
+
+
+ENTRY(mul64_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $16,%esp
+ pushl %esi
+
+ movl PARAM1,%esi
+ movl PARAM2,%ecx
+
+ xor %eax,%eax
+ movl %eax,-4(%ebp)
+ movl %eax,-8(%ebp)
+
+ movl (%esi),%eax /* lsl of Xsig */
+ mull 4(%ecx) /* msl of b */
+ movl %edx,-12(%ebp)
+
+ movl 4(%esi),%eax /* midl of Xsig */
+ mull (%ecx) /* lsl of b */
+ addl %edx,-12(%ebp)
+ adcl $0,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 4(%esi),%eax /* midl of Xsig */
+ mull 4(%ecx) /* msl of b */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull (%ecx) /* lsl of b */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull 4(%ecx) /* msl of b */
+ addl %eax,-8(%ebp)
+ adcl %edx,-4(%ebp)
+
+ movl -12(%ebp),%eax
+ movl %eax,(%esi)
+ movl -8(%ebp),%eax
+ movl %eax,4(%esi)
+ movl -4(%ebp),%eax
+ movl %eax,8(%esi)
+
+ popl %esi
+ leave
+ ret
+
+
+
+ENTRY(mul_Xsig_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $16,%esp
+ pushl %esi
+
+ movl PARAM1,%esi
+ movl PARAM2,%ecx
+
+ xor %eax,%eax
+ movl %eax,-4(%ebp)
+ movl %eax,-8(%ebp)
+
+ movl (%esi),%eax /* lsl of Xsig */
+ mull 8(%ecx) /* msl of b */
+ movl %edx,-12(%ebp)
+
+ movl 4(%esi),%eax /* midl of Xsig */
+ mull 4(%ecx) /* midl of b */
+ addl %edx,-12(%ebp)
+ adcl $0,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull (%ecx) /* lsl of b */
+ addl %edx,-12(%ebp)
+ adcl $0,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 4(%esi),%eax /* midl of Xsig */
+ mull 8(%ecx) /* msl of b */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull 4(%ecx) /* midl of b */
+ addl %eax,-12(%ebp)
+ adcl %edx,-8(%ebp)
+ adcl $0,-4(%ebp)
+
+ movl 8(%esi),%eax /* msl of Xsig */
+ mull 8(%ecx) /* msl of b */
+ addl %eax,-8(%ebp)
+ adcl %edx,-4(%ebp)
+
+ movl -12(%ebp),%edx
+ movl %edx,(%esi)
+ movl -8(%ebp),%edx
+ movl %edx,4(%esi)
+ movl -4(%ebp),%edx
+ movl %edx,8(%esi)
+
+ popl %esi
+ leave
+ ret
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | mul_Xsig.S |
+ | |
+ | Multiply a 12 byte fixed point number by another fixed point number. |
+ | |
+ | Copyright (C) 1992,1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ | The result is neither rounded nor normalized, and the ls bit or so may |
+ | be wrong. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void mul32_Xsig(Xsig *x, const u32 ba)
+{
+ Xsig y;
+ u32 zl;
+ u64 b = ba, z;
+
+ z = b * x->lsw;
+ y.lsw = z >> 32;
+
+ z = b * x->midw;
+ y.midw = z >> 32;
+ zl = z;
+ y.lsw += zl;
+ if ( zl > y.lsw )
+ y.midw ++;
+
+ z = b * x->msw;
+ y.msw = z >> 32;
+ zl = z;
+ y.midw += zl;
+ if ( zl > y.midw )
+ y.msw ++;
+
+ *x = y;
+
+}
+
+
+void mul64_Xsig(Xsig *x, const u64 *b)
+{
+ Xsig yh, yl;
+
+ yh = *x;
+ yl = *x;
+ mul32_Xsig(&yh, (*b) >> 32);
+ mul32_Xsig(&yl, *b);
+
+ x->msw = yh.msw;
+ x->midw = yh.midw + yl.msw;
+ if ( yh.midw > x->midw )
+ x->msw ++;
+ x->lsw = yh.lsw + yl.midw;
+ if ( yh.lsw > x->lsw )
+ {
+ x->midw ++;
+ if ( x->midw == 0 )
+ x->msw ++;
+ }
+
+}
+
+
+void mul_Xsig_Xsig(Xsig *x, const Xsig *b)
+{
+ u32 yh;
+ u64 y, z;
+
+ y = b->lsw;
+ y *= x->msw;
+ yh = y >> 32;
+
+ z = b->msw;
+ z <<= 32;
+ z += b->midw;
+ mul64_Xsig(x, &z);
+
+ x->lsw += yh;
+ if ( yh > x->lsw )
+ {
+ x->midw ++;
+ if ( x->midw == 0 )
+ x->msw ++;
+ }
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly.h |
+ | |
+ | Header file for the FPU-emu poly*.c source files. |
+ | |
+ | Copyright (C) 1994,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Declarations and definitions for functions operating on Xsig (12-byte |
+ | extended-significand) quantities. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _POLY_H
+#define _POLY_H
+
+/* This 12-byte structure is used to improve the accuracy of computation
+ of transcendental functions.
+ Intended to be used to get results better than 8-byte computation
+ allows. 9-byte would probably be sufficient.
+ */
+typedef struct {
+#ifdef EMU_BIG_ENDIAN
+ u32 msw;
+ u32 midw;
+ u32 lsw;
+#else
+ u32 lsw;
+ u32 midw;
+ u32 msw;
+#endif
+} GCC_ATTRIBUTE((packed)) Xsig;
+
+asmlinkage void mul64(u64 const *a, u64 const *b,
+ u64 *result);
+asmlinkage void polynomial_Xsig(Xsig *, const u64 *x,
+ const u64 terms[], const int n);
+
+asmlinkage void mul32_Xsig(Xsig *, const u32 mult);
+asmlinkage void mul64_Xsig(Xsig *, const u64 *mult);
+asmlinkage void mul_Xsig_Xsig(Xsig *dest, const Xsig *mult);
+
+asmlinkage void shr_Xsig(Xsig *, const int n);
+asmlinkage int round_Xsig(Xsig *);
+asmlinkage int norm_Xsig(Xsig *);
+asmlinkage void div_Xsig(const Xsig *x1, const Xsig *x2, Xsig *dest);
+
+/* Macro to extract the most significant 32 bits from a 64bit quantity */
+#ifdef EMU_BIG_ENDIAN
+#define LL_MSW(x) (((u32 *)&x)[0])
+#else
+#define LL_MSW(x) (((u32 *)&x)[1])
+#endif
+
+/* Macro to initialize an Xsig struct */
+#ifdef EMU_BIG_ENDIAN
+#define MK_XSIG(a,b,c) { a, b, c }
+#else
+#define MK_XSIG(a,b,c) { c, b, a }
+#endif
+
+/* Macro to access the 8 ms bytes of an Xsig as a 64bit quantity */
+#ifdef EMU_BIG_ENDIAN
+#define XSIG_LL(x) (*(u64 *)&x.msw)
+#else
+#define XSIG_LL(x) (*(u64 *)&x.midw)
+#endif
+
+
+/*
+ Need to run gcc with optimizations on to get these to
+ actually be in-line.
+ */
+
+/* Multiply two fixed-point 32 bit numbers, producing a 32 bit result.
+ The answer is the ms word of the product. */
+BX_C_INLINE
+u32 mul_32_32(const u32 arg1, const u32 arg2)
+{
+#ifdef NO_ASSEMBLER
+ return (((u64)arg1) * arg2) >> 32;
+#else
+/* Some versions of gcc make it difficult to stop eax from being clobbered.
+ Merely specifying that it is used doesn't work...
+ */
+ int retval;
+ asm volatile ("mull %2; movl %%edx,%%eax" \
+ :"=a" (retval) \
+ :"0" (arg1), "g" (arg2) \
+ :"dx");
+ return retval;
+#endif
+}
+
+
+/* Add the 12 byte Xsig x2 to Xsig dest, with no checks for overflow. */
+BX_C_INLINE
+void add_Xsig_Xsig(Xsig *dest, const Xsig *x2)
+{
+#ifdef NO_ASSEMBLER
+ dest->lsw += x2->lsw;
+ if ( dest->lsw < x2->lsw )
+ {
+ dest->midw ++;
+ if ( dest->midw == 0 )
+ dest->msw ++;
+ }
+ dest->midw += x2->midw;
+ if ( dest->midw < x2->midw )
+ {
+ dest->msw ++;
+ }
+ dest->msw += x2->msw;
+#else
+ asm volatile ("movl %1,%%edi; movl %2,%%esi;
+ movl (%%esi),%%eax; addl %%eax,(%%edi);
+ movl 4(%%esi),%%eax; adcl %%eax,4(%%edi);
+ movl 8(%%esi),%%eax; adcl %%eax,8(%%edi);"
+ :"=g" (*dest):"g" (dest), "g" (x2)
+ :"ax","si","di");
+#endif
+}
+
+
+/* Add the 12 byte Xsig x2 to Xsig dest, adjust exp if overflow occurs. */
+BX_C_INLINE
+void add_two_Xsig(Xsig *dest, const Xsig *x2, s32 *exp)
+{
+#ifdef NO_ASSEMBLER
+ int ovfl = 0;
+
+ dest->lsw += x2->lsw;
+ if ( dest->lsw < x2->lsw )
+ {
+ dest->midw ++;
+ if ( dest->midw == 0 )
+ {
+ dest->msw ++;
+ if ( dest->msw == 0 )
+ ovfl = 1;
+ }
+ }
+ dest->midw += x2->midw;
+ if ( dest->midw < x2->midw )
+ {
+ dest->msw ++;
+ if ( dest->msw == 0 )
+ ovfl = 1;
+ }
+ dest->msw += x2->msw;
+ if ( dest->msw < x2->msw )
+ ovfl = 1;
+ if ( ovfl )
+ {
+ (*exp) ++;
+ dest->lsw >>= 1;
+ if ( dest->midw & 1 )
+ dest->lsw |= 0x80000000;
+ dest->midw >>= 1;
+ if ( dest->msw & 1 )
+ dest->midw |= 0x80000000;
+ dest->msw >>= 1;
+ dest->msw |= 0x80000000;
+ }
+#else
+/* Note: the constraints in the asm statement didn't always work properly
+ with gcc 2.5.8. Changing from using edi to using ecx got around the
+ problem, but keep fingers crossed! */
+ asm volatile ("movl %2,%%ecx; movl %3,%%esi;
+ movl (%%esi),%%eax; addl %%eax,(%%ecx);
+ movl 4(%%esi),%%eax; adcl %%eax,4(%%ecx);
+ movl 8(%%esi),%%eax; adcl %%eax,8(%%ecx);
+ jnc 0f;
+ rcrl 8(%%ecx); rcrl 4(%%ecx); rcrl (%%ecx)
+ movl %4,%%ecx; incl (%%ecx)
+ movl $1,%%eax; jmp 1f;
+ 0: xorl %%eax,%%eax;
+ 1:"
+ :"=g" (*exp), "=g" (*dest)
+ :"g" (dest), "g" (x2), "g" (exp)
+ :"cx","si","ax");
+#endif
+}
+
+
+/* Negate the 12 byte Xsig */
+BX_C_INLINE
+void negate_Xsig(Xsig *x)
+{
+#ifdef NO_ASSEMBLER
+ x->lsw = ~x->lsw;
+ x->midw = ~x->midw;
+ x->msw = ~x->msw;
+ x->lsw ++;
+ if ( x->lsw == 0 )
+ {
+ x->midw ++;
+ if ( x->midw == 0 )
+ x->msw ++;
+ }
+#else
+/* Negate (subtract from 1.0) the 12 byte Xsig */
+/* This is faster in a loop on my 386 than using the "neg" instruction. */
+ asm volatile("movl %1,%%esi; "
+ "xorl %%ecx,%%ecx; "
+ "movl %%ecx,%%eax; subl (%%esi),%%eax; movl %%eax,(%%esi); "
+ "movl %%ecx,%%eax; sbbl 4(%%esi),%%eax; movl %%eax,4(%%esi); "
+ "movl %%ecx,%%eax; sbbl 8(%%esi),%%eax; movl %%eax,8(%%esi); "
+ :"=g" (*x):"g" (x):"si","ax","cx");
+#endif
+}
+
+
+#endif /* _POLY_H */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly_2xm1.c |
+ | |
+ | Function to compute 2^x-1 by a polynomial approximation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+#define HIPOWER 11
+static const u64 lterms[HIPOWER] =
+{
+ BX_CONST64(0x0000000000000000), /* This term done separately as 12 bytes */
+ BX_CONST64(0xf5fdeffc162c7543),
+ BX_CONST64(0x1c6b08d704a0bfa6),
+ BX_CONST64(0x0276556df749cc21),
+ BX_CONST64(0x002bb0ffcf14f6b8),
+ BX_CONST64(0x0002861225ef751c),
+ BX_CONST64(0x00001ffcbfcd5422),
+ BX_CONST64(0x00000162c005d5f1),
+ BX_CONST64(0x0000000da96ccb1b),
+ BX_CONST64(0x0000000078d1b897),
+ BX_CONST64(0x000000000422b029)
+};
+
+static const Xsig hiterm = MK_XSIG(0xb17217f7, 0xd1cf79ab, 0xc8a39194);
+
+/* Four slices: 0.0 : 0.25 : 0.50 : 0.75 : 1.0,
+ These numbers are 2^(1/4), 2^(1/2), and 2^(3/4)
+ */
+static const Xsig shiftterm0 = MK_XSIG(0, 0, 0);
+static const Xsig shiftterm1 = MK_XSIG(0x9837f051, 0x8db8a96f, 0x46ad2318);
+static const Xsig shiftterm2 = MK_XSIG(0xb504f333, 0xf9de6484, 0x597d89b3);
+static const Xsig shiftterm3 = MK_XSIG(0xd744fcca, 0xd69d6af4, 0x39a68bb9);
+
+static const Xsig *shiftterm[] = { &shiftterm0, &shiftterm1,
+ &shiftterm2, &shiftterm3 };
+
+
+/*--- poly_2xm1() -----------------------------------------------------------+
+ | Requires st(0) which is TAG_Valid and < 1. |
+ +---------------------------------------------------------------------------*/
+int poly_2xm1(u_char sign, FPU_REG *arg, FPU_REG *result)
+{
+ s32 exponent, shift;
+ u64 Xll;
+ Xsig accumulator, Denom, argSignif;
+ u_char tag;
+
+ exponent = exponent16(arg);
+
+#ifdef PARANOID
+ if ( exponent >= 0 ) /* Don't want a |number| >= 1.0 */
+ {
+ /* Number negative, too large, or not Valid. */
+ EXCEPTION(EX_INTERNAL|0x127);
+ return 1;
+ }
+#endif /* PARANOID */
+
+ argSignif.lsw = 0;
+ XSIG_LL(argSignif) = Xll = significand(arg);
+
+ if ( exponent == -1 )
+ {
+ shift = (argSignif.msw & 0x40000000) ? 3 : 2;
+ /* subtract 0.5 or 0.75 */
+ exponent -= 2;
+ XSIG_LL(argSignif) <<= 2;
+ Xll <<= 2;
+ }
+ else if ( exponent == -2 )
+ {
+ shift = 1;
+ /* subtract 0.25 */
+ exponent--;
+ XSIG_LL(argSignif) <<= 1;
+ Xll <<= 1;
+ }
+ else
+ shift = 0;
+
+ if ( exponent < -2 )
+ {
+ /* Shift the argument right by the required places. */
+ if ( FPU_shrx(&Xll, -2-exponent) >= 0x80000000U )
+ Xll++; /* round up */
+ }
+
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+ polynomial_Xsig(&accumulator, &Xll, lterms, HIPOWER-1);
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ shr_Xsig(&accumulator, 3);
+
+ mul_Xsig_Xsig(&argSignif, &hiterm); /* The leading term */
+ add_two_Xsig(&accumulator, &argSignif, &exponent);
+
+ if ( shift )
+ {
+ /* The argument is large, use the identity:
+ f(x+a) = f(a) * (f(x) + 1) - 1;
+ */
+ shr_Xsig(&accumulator, - exponent);
+ accumulator.msw |= 0x80000000; /* add 1.0 */
+ mul_Xsig_Xsig(&accumulator, shiftterm[shift]);
+ accumulator.msw &= 0x3fffffff; /* subtract 1.0 */
+ exponent = 1;
+ }
+
+ if ( sign != SIGN_POS )
+ {
+ /* The argument is negative, use the identity:
+ f(-x) = -f(x) / (1 + f(x))
+ */
+ Denom.lsw = accumulator.lsw;
+ XSIG_LL(Denom) = XSIG_LL(accumulator);
+ if ( exponent < 0 )
+ shr_Xsig(&Denom, - exponent);
+ else if ( exponent > 0 )
+ {
+ /* exponent must be 1 here */
+ XSIG_LL(Denom) <<= 1;
+ if ( Denom.lsw & 0x80000000 )
+ XSIG_LL(Denom) |= 1;
+ (Denom.lsw) <<= 1;
+ }
+ Denom.msw |= 0x80000000; /* add 1.0 */
+ div_Xsig(&accumulator, &Denom, &accumulator);
+ }
+
+ /* Convert to 64 bit signed-compatible */
+ exponent += round_Xsig(&accumulator);
+
+ result = &st(0);
+ significand(result) = XSIG_LL(accumulator);
+ setexponent16(result, exponent);
+
+ tag = FPU_round(result, 1, 0, FULL_PRECISION, sign);
+
+ setsign(result, sign);
+ FPU_settag0(tag);
+
+ return 0;
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly_atan.c |
+ | |
+ | Compute the arctan of a FPU_REG, using a polynomial approximation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "status_w.h"
+#include "control_w.h"
+#include "poly.h"
+
+#define HIPOWERon 6 /* odd poly, negative terms */
+static const u64 oddnegterms[HIPOWERon] =
+{
+ BX_CONST64(0x0000000000000000), /* Dummy (not for - 1.0) */
+ BX_CONST64(0x015328437f756467),
+ BX_CONST64(0x0005dda27b73dec6),
+ BX_CONST64(0x0000226bf2bfb91a),
+ BX_CONST64(0x000000ccc439c5f7),
+ BX_CONST64(0x0000000355438407)
+} ;
+
+#define HIPOWERop 6 /* odd poly, positive terms */
+static const u64 oddplterms[HIPOWERop] =
+{
+/* BX_CONST64(0xaaaaaaaaaaaaaaab), transferred to fixedpterm[] */
+ BX_CONST64(0x0db55a71875c9ac2),
+ BX_CONST64(0x0029fce2d67880b0),
+ BX_CONST64(0x0000dfd3908b4596),
+ BX_CONST64(0x00000550fd61dab4),
+ BX_CONST64(0x0000001c9422b3f9),
+ BX_CONST64(0x000000003e3301e1)
+};
+
+static const u64 denomterm = BX_CONST64(0xebd9b842c5c53a0e);
+
+static const Xsig fixedpterm = MK_XSIG(0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa);
+
+static const Xsig pi_signif = MK_XSIG(0xc90fdaa2, 0x2168c234, 0xc4c6628b);
+
+
+/*--- poly_atan() -----------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void poly_atan(FPU_REG *st0_ptr, u_char st0_tag,
+ FPU_REG *st1_ptr, u_char st1_tag)
+{
+ u_char transformed, inverted,
+ sign1, sign2;
+ s32 exponent;
+ s32 dummy_exp;
+ Xsig accumulator, Numer, Denom, accumulatore, argSignif,
+ argSq, argSqSq;
+ u_char tag;
+
+ sign1 = getsign(st0_ptr);
+ sign2 = getsign(st1_ptr);
+ if ( st0_tag == TAG_Valid )
+ {
+ exponent = exponent(st0_ptr);
+ }
+ else
+ {
+ /* This gives non-compatible stack contents... */
+ FPU_to_exp16(st0_ptr, st0_ptr);
+ exponent = exponent16(st0_ptr);
+ }
+ if ( st1_tag == TAG_Valid )
+ {
+ exponent -= exponent(st1_ptr);
+ }
+ else
+ {
+ /* This gives non-compatible stack contents... */
+ FPU_to_exp16(st1_ptr, st1_ptr);
+ exponent -= exponent16(st1_ptr);
+ }
+
+ if ( (exponent < 0) || ((exponent == 0) &&
+ ((st0_ptr->sigh < st1_ptr->sigh) ||
+ ((st0_ptr->sigh == st1_ptr->sigh) &&
+ (st0_ptr->sigl < st1_ptr->sigl))) ) )
+ {
+ inverted = 1;
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = significand(st0_ptr);
+ XSIG_LL(Denom) = significand(st1_ptr);
+ }
+ else
+ {
+ inverted = 0;
+ exponent = -exponent;
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = significand(st1_ptr);
+ XSIG_LL(Denom) = significand(st0_ptr);
+ }
+ div_Xsig(&Numer, &Denom, &argSignif);
+ exponent += norm_Xsig(&argSignif);
+
+ if ( (exponent >= -1)
+ || ((exponent == -2) && (argSignif.msw > 0xd413ccd0)) )
+ {
+ /* The argument is greater than sqrt(2)-1 (=0.414213562...) */
+ /* Convert the argument by an identity for atan */
+ transformed = 1;
+
+ if ( exponent >= 0 )
+ {
+#ifdef PARANOID
+ if ( !( (exponent == 0) &&
+ (argSignif.lsw == 0) && (argSignif.midw == 0) &&
+ (argSignif.msw == 0x80000000) ) )
+ {
+ EXCEPTION(EX_INTERNAL|0x104); /* There must be a logic error */
+ return;
+ }
+#endif /* PARANOID */
+ argSignif.msw = 0; /* Make the transformed arg -> 0.0 */
+ }
+ else
+ {
+ Numer.lsw = Denom.lsw = argSignif.lsw;
+ XSIG_LL(Numer) = XSIG_LL(Denom) = XSIG_LL(argSignif);
+
+ if ( exponent < -1 )
+ shr_Xsig(&Numer, -1-exponent);
+ negate_Xsig(&Numer);
+
+ shr_Xsig(&Denom, -exponent);
+ Denom.msw |= 0x80000000;
+
+ div_Xsig(&Numer, &Denom, &argSignif);
+
+ exponent = -1 + norm_Xsig(&argSignif);
+ }
+ }
+ else
+ {
+ transformed = 0;
+ }
+
+ argSq.lsw = argSignif.lsw; argSq.midw = argSignif.midw;
+ argSq.msw = argSignif.msw;
+ mul_Xsig_Xsig(&argSq, &argSq);
+
+ argSqSq.lsw = argSq.lsw; argSqSq.midw = argSq.midw; argSqSq.msw = argSq.msw;
+ mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+ accumulatore.lsw = argSq.lsw;
+ XSIG_LL(accumulatore) = XSIG_LL(argSq);
+
+ shr_Xsig(&argSq, 2*(-1-exponent-1));
+ shr_Xsig(&argSqSq, 4*(-1-exponent-1));
+
+ /* Now have argSq etc with binary point at the left
+ .1xxxxxxxx */
+
+ /* Do the basic fixed point polynomial evaluation */
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq),
+ oddplterms, HIPOWERop-1);
+ mul64_Xsig(&accumulator, &XSIG_LL(argSq));
+ negate_Xsig(&accumulator);
+ polynomial_Xsig(&accumulator, &XSIG_LL(argSqSq), oddnegterms, HIPOWERon-1);
+ negate_Xsig(&accumulator);
+ add_two_Xsig(&accumulator, &fixedpterm, &dummy_exp);
+
+ mul64_Xsig(&accumulatore, &denomterm);
+ shr_Xsig(&accumulatore, 1 + 2*(-1-exponent));
+ accumulatore.msw |= 0x80000000;
+
+ div_Xsig(&accumulator, &accumulatore, &accumulator);
+
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ mul_Xsig_Xsig(&accumulator, &argSq);
+
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &argSignif);
+
+ if ( transformed )
+ {
+ /* compute pi/4 - accumulator */
+ shr_Xsig(&accumulator, -1-exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = -1;
+ }
+
+ if ( inverted )
+ {
+ /* compute pi/2 - accumulator */
+ shr_Xsig(&accumulator, -exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = 0;
+ }
+
+ if ( sign1 )
+ {
+ /* compute pi - accumulator */
+ shr_Xsig(&accumulator, 1 - exponent);
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &pi_signif);
+ exponent = 1;
+ }
+
+ exponent += round_Xsig(&accumulator);
+
+ significand(st1_ptr) = XSIG_LL(accumulator);
+ setexponent16(st1_ptr, exponent);
+
+ tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
+ FPU_settagi(1, tag);
+
+
+ set_precision_flag_up(); /* We do not really know if up or down,
+ use this as the default. */
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly_l2.c |
+ | |
+ | Compute the base 2 log of a FPU_REG, using a polynomial approximation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+static void log2_kernel(FPU_REG const *arg, u_char argsign,
+ Xsig *accum_result, s32 *expon);
+
+
+/*--- poly_l2() -------------------------------------------------------------+
+ | Base 2 logarithm by a polynomial approximation. |
+ +---------------------------------------------------------------------------*/
+void poly_l2(FPU_REG *st0_ptr, FPU_REG *st1_ptr, u_char st1_sign)
+{
+ s32 exponent, expon, expon_expon;
+ Xsig accumulator, expon_accum, yaccum;
+ u_char sign, argsign;
+ FPU_REG x;
+ int tag;
+
+ exponent = exponent16(st0_ptr);
+
+ /* From st0_ptr, make a number > sqrt(2)/2 and < sqrt(2) */
+ if ( st0_ptr->sigh > (unsigned)0xb504f334 )
+ {
+ /* Treat as sqrt(2)/2 < st0_ptr < 1 */
+ significand(&x) = - significand(st0_ptr);
+ setexponent16(&x, -1);
+ exponent++;
+ argsign = SIGN_NEG;
+ }
+ else
+ {
+ /* Treat as 1 <= st0_ptr < sqrt(2) */
+ x.sigh = st0_ptr->sigh - 0x80000000;
+ x.sigl = st0_ptr->sigl;
+ setexponent16(&x, 0);
+ argsign = SIGN_POS;
+ }
+ tag = FPU_normalize_nuo(&x, 0);
+
+ if ( tag == TAG_Zero )
+ {
+ expon = 0;
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ }
+ else
+ {
+ log2_kernel(&x, argsign, &accumulator, &expon);
+ }
+
+ if ( exponent < 0 )
+ {
+ sign = SIGN_NEG;
+ exponent = -exponent;
+ }
+ else
+ sign = SIGN_POS;
+ expon_accum.msw = exponent; expon_accum.midw = expon_accum.lsw = 0;
+ if ( exponent )
+ {
+ expon_expon = 31 + norm_Xsig(&expon_accum);
+ shr_Xsig(&accumulator, expon_expon - expon);
+
+ if ( sign ^ argsign )
+ negate_Xsig(&accumulator);
+ add_Xsig_Xsig(&accumulator, &expon_accum);
+ }
+ else
+ {
+ expon_expon = expon;
+ sign = argsign;
+ }
+
+ yaccum.lsw = 0; XSIG_LL(yaccum) = significand(st1_ptr);
+ mul_Xsig_Xsig(&accumulator, &yaccum);
+
+ expon_expon += round_Xsig(&accumulator);
+
+ if ( accumulator.msw == 0 )
+ {
+ FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+ return;
+ }
+
+ significand(st1_ptr) = XSIG_LL(accumulator);
+ setexponent16(st1_ptr, expon_expon + exponent16(st1_ptr) + 1);
+
+ tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign ^ st1_sign);
+ FPU_settagi(1, tag);
+
+ set_precision_flag_up(); /* 80486 appears to always do this */
+
+ return;
+
+}
+
+
+/*--- poly_l2p1() -----------------------------------------------------------+
+ | Base 2 logarithm by a polynomial approximation. |
+ | log2(x+1) |
+ +---------------------------------------------------------------------------*/
+int poly_l2p1(u_char sign0, u_char sign1,
+ FPU_REG *st0_ptr, FPU_REG *st1_ptr, FPU_REG *dest)
+{
+ u_char tag;
+ s32 exponent;
+ Xsig accumulator, yaccum;
+
+ if ( exponent16(st0_ptr) < 0 )
+ {
+ log2_kernel(st0_ptr, sign0, &accumulator, &exponent);
+
+ yaccum.lsw = 0;
+ XSIG_LL(yaccum) = significand(st1_ptr);
+ mul_Xsig_Xsig(&accumulator, &yaccum);
+
+ exponent += round_Xsig(&accumulator);
+
+ exponent += exponent16(st1_ptr) + 1;
+ if ( exponent < EXP_WAY_UNDER ) exponent = EXP_WAY_UNDER;
+
+ significand(dest) = XSIG_LL(accumulator);
+ setexponent16(dest, exponent);
+
+ tag = FPU_round(dest, 1, 0, FULL_PRECISION, sign0 ^ sign1);
+ FPU_settagi(1, tag);
+
+ if ( tag == TAG_Valid )
+ set_precision_flag_up(); /* 80486 appears to always do this */
+ }
+ else
+ {
+ /* The magnitude of st0_ptr is far too large. */
+
+ if ( sign0 != SIGN_POS )
+ {
+ /* Trying to get the log of a negative number. */
+#ifdef PECULIAR_486 /* Stupid 80486 doesn't worry about log(negative). */
+ changesign(st1_ptr);
+#else
+ if ( arith_invalid(1) < 0 )
+ return 1;
+#endif /* PECULIAR_486 */
+ }
+
+ /* 80486 appears to do this */
+ if ( sign0 == SIGN_NEG )
+ set_precision_flag_down();
+ else
+ set_precision_flag_up();
+ }
+
+ if ( exponent(dest) <= EXP_UNDER )
+ EXCEPTION(EX_Underflow);
+
+ return 0;
+
+}
+
+
+
+
+#undef HIPOWER
+#define HIPOWER 10
+static const u64 logterms[HIPOWER] =
+{
+ BX_CONST64(0x2a8eca5705fc2ef0),
+ BX_CONST64(0xf6384ee1d01febce),
+ BX_CONST64(0x093bb62877cdf642),
+ BX_CONST64(0x006985d8a9ec439b),
+ BX_CONST64(0x0005212c4f55a9c8),
+ BX_CONST64(0x00004326a16927f0),
+ BX_CONST64(0x0000038d1d80a0e7),
+ BX_CONST64(0x0000003141cc80c6),
+ BX_CONST64(0x00000002b1668c9f),
+ BX_CONST64(0x000000002c7a46aa)
+};
+
+static const u32 leadterm = 0xb8000000;
+
+
+/*--- log2_kernel() ---------------------------------------------------------+
+ | Base 2 logarithm by a polynomial approximation. |
+ | log2(x+1) |
+ +---------------------------------------------------------------------------*/
+static void log2_kernel(FPU_REG const *arg, u_char argsign, Xsig *accum_result,
+ s32 *expon)
+{
+ s32 exponent, adj;
+ u64 Xsq;
+ Xsig accumulator, Numer, Denom, argSignif, arg_signif;
+
+ exponent = exponent16(arg);
+ Numer.lsw = Denom.lsw = 0;
+ XSIG_LL(Numer) = XSIG_LL(Denom) = significand(arg);
+ if ( argsign == SIGN_POS )
+ {
+ shr_Xsig(&Denom, 2 - (1 + exponent));
+ Denom.msw |= 0x80000000;
+ div_Xsig(&Numer, &Denom, &argSignif);
+ }
+ else
+ {
+ shr_Xsig(&Denom, 1 - (1 + exponent));
+ negate_Xsig(&Denom);
+ if ( Denom.msw & 0x80000000 )
+ {
+ div_Xsig(&Numer, &Denom, &argSignif);
+ exponent ++;
+ }
+ else
+ {
+ /* Denom must be 1.0 */
+ argSignif.lsw = Numer.lsw; argSignif.midw = Numer.midw;
+ argSignif.msw = Numer.msw;
+ }
+ }
+
+#ifndef PECULIAR_486
+ /* Should check here that |local_arg| is within the valid range */
+ if ( exponent >= -2 )
+ {
+ if ( (exponent > -2) ||
+ (argSignif.msw > (unsigned)0xafb0ccc0) )
+ {
+ /* The argument is too large */
+ }
+ }
+#endif /* PECULIAR_486 */
+
+ arg_signif.lsw = argSignif.lsw; XSIG_LL(arg_signif) = XSIG_LL(argSignif);
+ adj = norm_Xsig(&argSignif);
+ accumulator.lsw = argSignif.lsw; XSIG_LL(accumulator) = XSIG_LL(argSignif);
+ mul_Xsig_Xsig(&accumulator, &accumulator);
+ shr_Xsig(&accumulator, 2*(-1 - (1 + exponent + adj)));
+ Xsq = XSIG_LL(accumulator);
+ if ( accumulator.lsw & 0x80000000 )
+ Xsq++;
+
+ accumulator.msw = accumulator.midw = accumulator.lsw = 0;
+ /* Do the basic fixed point polynomial evaluation */
+ polynomial_Xsig(&accumulator, &Xsq, logterms, HIPOWER-1);
+
+ mul_Xsig_Xsig(&accumulator, &argSignif);
+ shr_Xsig(&accumulator, 6 - adj);
+
+ mul32_Xsig(&arg_signif, leadterm);
+ add_two_Xsig(&accumulator, &arg_signif, &exponent);
+
+ *expon = exponent + 1;
+ accum_result->lsw = accumulator.lsw;
+ accum_result->midw = accumulator.midw;
+ accum_result->msw = accumulator.msw;
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly_sin.c |
+ | |
+ | Computation of an approximation of the sin function and the cosine |
+ | function by a polynomial. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+
+#define N_COEFF_P 4
+#define N_COEFF_N 4
+
+static const u64 pos_terms_l[N_COEFF_P] =
+{
+ BX_CONST64(0xaaaaaaaaaaaaaaab),
+ BX_CONST64(0x00d00d00d00cf906),
+ BX_CONST64(0x000006b99159a8bb),
+ BX_CONST64(0x000000000d7392e6)
+};
+
+static const u64 neg_terms_l[N_COEFF_N] =
+{
+ BX_CONST64(0x2222222222222167),
+ BX_CONST64(0x0002e3bc74aab624),
+ BX_CONST64(0x0000000b09229062),
+ BX_CONST64(0x00000000000c7973)
+};
+
+
+
+#define N_COEFF_PH 4
+#define N_COEFF_NH 4
+static const u64 pos_terms_h[N_COEFF_PH] =
+{
+ BX_CONST64(0x0000000000000000),
+ BX_CONST64(0x05b05b05b05b0406),
+ BX_CONST64(0x000049f93edd91a9),
+ BX_CONST64(0x00000000c9c9ed62)
+};
+
+static const u64 neg_terms_h[N_COEFF_NH] =
+{
+ BX_CONST64(0xaaaaaaaaaaaaaa98),
+ BX_CONST64(0x001a01a01a019064),
+ BX_CONST64(0x0000008f76c68a77),
+ BX_CONST64(0x0000000000d58f5e)
+};
+
+
+/*--- poly_sine() -----------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void poly_sine(FPU_REG *st0_ptr)
+{
+ int exponent, echange;
+ Xsig accumulator, argSqrd, argTo4;
+ s32 fix_up, adj;
+ u64 fixed_arg;
+ FPU_REG result;
+
+ exponent = exponent(st0_ptr);
+
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+
+ /* Split into two ranges, for arguments below and above 1.0 */
+ /* The boundary between upper and lower is approx 0.88309101259 */
+ if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xe21240aa)) )
+ {
+ /* The argument is <= 0.88309101259 */
+
+ argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl; argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &significand(st0_ptr));
+ shr_Xsig(&argSqrd, 2*(-1-exponent));
+ argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+ N_COEFF_N-1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+ N_COEFF_P-1);
+
+ shr_Xsig(&accumulator, 2); /* Divide by four */
+ accumulator.msw |= 0x80000000; /* Add 1.0 */
+
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+
+ /* Divide by four, FPU_REG compatible, etc */
+ exponent = 3*exponent;
+
+ /* The minimum exponent difference is 3 */
+ shr_Xsig(&accumulator, exponent(st0_ptr) - exponent);
+
+ negate_Xsig(&accumulator);
+ XSIG_LL(accumulator) += significand(st0_ptr);
+
+ echange = round_Xsig(&accumulator);
+
+ setexponentpos(&result, exponent(st0_ptr) + echange);
+ }
+ else
+ {
+ /* The argument is > 0.88309101259 */
+ /* We use sin(st(0)) = cos(pi/2-st(0)) */
+
+ fixed_arg = significand(st0_ptr);
+
+ if ( exponent == 0 )
+ {
+ /* The argument is >= 1.0 */
+
+ /* Put the binary point at the left. */
+ fixed_arg <<= 1;
+ }
+ /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+ fixed_arg = BX_CONST64(0x921fb54442d18469) - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if ( fixed_arg == BX_CONST64(0xffffffffffffffff))
+ fixed_arg = 0;
+
+ XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &fixed_arg);
+
+ XSIG_LL(argTo4) = XSIG_LL(argSqrd); argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+ N_COEFF_NH-1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+ N_COEFF_PH-1);
+ negate_Xsig(&accumulator);
+
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
+
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
+
+ add_Xsig_Xsig(&accumulator, &argSqrd);
+
+ shr_Xsig(&accumulator, 1);
+
+ accumulator.lsw |= 1; /* A zero accumulator here would cause problems */
+ negate_Xsig(&accumulator);
+
+ /* The basic computation is complete. Now fix the answer to
+ compensate for the error due to the approximation used for
+ pi/2
+ */
+
+ /* This has an exponent of -65 */
+ fix_up = 0x898cc517;
+ /* The fix-up needs to be improved for larger args */
+ if ( argSqrd.msw & 0xffc00000 )
+ {
+ /* Get about 32 bit precision in these: */
+ fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
+ }
+ fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
+
+ adj = accumulator.lsw; /* temp save */
+ accumulator.lsw -= fix_up;
+ if ( accumulator.lsw > adj )
+ XSIG_LL(accumulator) --;
+
+ echange = round_Xsig(&accumulator);
+
+ setexponentpos(&result, echange - 1);
+ }
+
+ significand(&result) = XSIG_LL(accumulator);
+ setsign(&result, getsign(st0_ptr));
+ FPU_copy_to_reg0(&result, TAG_Valid);
+
+#ifdef PARANOID
+ if ( (exponent(&result) >= 0)
+ && (significand(&result) > BX_CONST64(0x8000000000000000)) )
+ {
+ EXCEPTION(EX_INTERNAL|0x150);
+ }
+#endif /* PARANOID */
+
+}
+
+
+
+/*--- poly_cos() ------------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void poly_cos(FPU_REG *st0_ptr)
+{
+ FPU_REG result;
+ s32 exponent, exp2, echange;
+ Xsig accumulator, argSqrd, fix_up, argTo4;
+ u64 fixed_arg;
+
+#ifdef PARANOID
+ if ( (exponent(st0_ptr) > 0)
+ || ((exponent(st0_ptr) == 0)
+ && (significand(st0_ptr) > BX_CONST64(0xc90fdaa22168c234))) )
+ {
+ EXCEPTION(EX_Invalid);
+ FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+ return;
+ }
+#endif /* PARANOID */
+
+ exponent = exponent(st0_ptr);
+
+ accumulator.lsw = accumulator.midw = accumulator.msw = 0;
+
+ if ( (exponent < -1) || ((exponent == -1) && (st0_ptr->sigh <= 0xb00d6f54)) )
+ {
+ /* arg is < 0.687705 */
+
+ argSqrd.msw = st0_ptr->sigh; argSqrd.midw = st0_ptr->sigl;
+ argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &significand(st0_ptr));
+
+ if ( exponent < -1 )
+ {
+ /* shift the argument right by the required places */
+ shr_Xsig(&argSqrd, 2*(-1-exponent));
+ }
+
+ argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_h,
+ N_COEFF_NH-1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_h,
+ N_COEFF_PH-1);
+ negate_Xsig(&accumulator);
+
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ mul64_Xsig(&accumulator, &significand(st0_ptr));
+ shr_Xsig(&accumulator, -2*(1+exponent));
+
+ shr_Xsig(&accumulator, 3);
+ negate_Xsig(&accumulator);
+
+ add_Xsig_Xsig(&accumulator, &argSqrd);
+
+ shr_Xsig(&accumulator, 1);
+
+ /* It doesn't matter if accumulator is all zero here, the
+ following code will work ok */
+ negate_Xsig(&accumulator);
+
+ if ( accumulator.lsw & 0x80000000 )
+ XSIG_LL(accumulator) ++;
+ if ( accumulator.msw == 0 )
+ {
+ /* The result is 1.0 */
+ FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+ return;
+ }
+ else
+ {
+ significand(&result) = XSIG_LL(accumulator);
+
+ /* will be a valid positive nr with expon = -1 */
+ setexponentpos(&result, -1);
+ }
+ }
+ else
+ {
+ fixed_arg = significand(st0_ptr);
+
+ if ( exponent == 0 )
+ {
+ /* The argument is >= 1.0 */
+
+ /* Put the binary point at the left. */
+ fixed_arg <<= 1;
+ }
+ /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
+ fixed_arg = BX_CONST64(0x921fb54442d18469) - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if ( fixed_arg == BX_CONST64(0xffffffffffffffff))
+ fixed_arg = 0;
+
+ exponent = -1;
+ exp2 = -1;
+
+ /* A shift is needed here only for a narrow range of arguments,
+ i.e. for fixed_arg approx 2^-32, but we pick up more... */
+ if ( !(LL_MSW(fixed_arg) & 0xffff0000) )
+ {
+ fixed_arg <<= 16;
+ exponent -= 16;
+ exp2 -= 16;
+ }
+
+ XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
+ mul64_Xsig(&argSqrd, &fixed_arg);
+
+ if ( exponent < -1 )
+ {
+ /* shift the argument right by the required places */
+ shr_Xsig(&argSqrd, 2*(-1-exponent));
+ }
+
+ argTo4.msw = argSqrd.msw; argTo4.midw = argSqrd.midw;
+ argTo4.lsw = argSqrd.lsw;
+ mul_Xsig_Xsig(&argTo4, &argTo4);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), neg_terms_l,
+ N_COEFF_N-1);
+ mul_Xsig_Xsig(&accumulator, &argSqrd);
+ negate_Xsig(&accumulator);
+
+ polynomial_Xsig(&accumulator, &XSIG_LL(argTo4), pos_terms_l,
+ N_COEFF_P-1);
+
+ shr_Xsig(&accumulator, 2); /* Divide by four */
+ accumulator.msw |= 0x80000000; /* Add 1.0 */
+
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
+ mul64_Xsig(&accumulator, &fixed_arg);
+
+ /* Divide by four, FPU_REG compatible, etc */
+ exponent = 3*exponent;
+
+ /* The minimum exponent difference is 3 */
+ shr_Xsig(&accumulator, exp2 - exponent);
+
+ negate_Xsig(&accumulator);
+ XSIG_LL(accumulator) += fixed_arg;
+
+ /* The basic computation is complete. Now fix the answer to
+ compensate for the error due to the approximation used for
+ pi/2
+ */
+
+ /* This has an exponent of -65 */
+ XSIG_LL(fix_up) = BX_CONST64(0x898cc51701b839a2);
+ fix_up.lsw = 0;
+
+ /* The fix-up needs to be improved for larger args */
+ if ( argSqrd.msw & 0xffc00000 )
+ {
+ /* Get about 32 bit precision in these: */
+ fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
+ fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
+ }
+
+ exp2 += norm_Xsig(&accumulator);
+ shr_Xsig(&accumulator, 1); /* Prevent overflow */
+ exp2++;
+ shr_Xsig(&fix_up, 65 + exp2);
+
+ add_Xsig_Xsig(&accumulator, &fix_up);
+
+ echange = round_Xsig(&accumulator);
+
+ setexponentpos(&result, exp2 + echange);
+ significand(&result) = XSIG_LL(accumulator);
+ }
+
+ FPU_copy_to_reg0(&result, TAG_Valid);
+
+#ifdef PARANOID
+ if ( (exponent(&result) >= 0)
+ && (significand(&result) > BX_CONST64(0x8000000000000000)) )
+ {
+ EXCEPTION(EX_INTERNAL|0x151);
+ }
+#endif /* PARANOID */
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | poly_tan.c |
+ | |
+ | Compute the tan of a FPU_REG, using a polynomial approximation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+#include "control_w.h"
+#include "poly.h"
+
+//#define DEBUG_POLY_TAN // ***********
+
+#define HiPOWERop 3 /* odd poly, positive terms */
+static const u64 oddplterm[HiPOWERop] =
+{
+ BX_CONST64(0x0000000000000000),
+ BX_CONST64(0x0051a1cf08fca228),
+ BX_CONST64(0x0000000071284ff7)
+};
+
+#define HiPOWERon 2 /* odd poly, negative terms */
+static const u64 oddnegterm[HiPOWERon] =
+{
+ BX_CONST64(0x1291a9a184244e80),
+ BX_CONST64(0x0000583245819c21)
+};
+
+#define HiPOWERep 2 /* even poly, positive terms */
+static const u64 evenplterm[HiPOWERep] =
+{
+ BX_CONST64(0x0e848884b539e888),
+ BX_CONST64(0x00003c7f18b887da)
+};
+
+#define HiPOWERen 2 /* even poly, negative terms */
+static const u64 evennegterm[HiPOWERen] =
+{
+ BX_CONST64(0xf1f0200fd51569cc),
+ BX_CONST64(0x003afb46105c4432)
+};
+
+static const u64 twothirds = BX_CONST64(0xaaaaaaaaaaaaaaab);
+
+
+/*--- poly_tan() ------------------------------------------------------------+
+ | |
+ +---------------------------------------------------------------------------*/
+void poly_tan(FPU_REG *st0_ptr, int invert)
+{
+ s32 exponent;
+ Xsig argSq, argSqSq, accumulatoro, accumulatore, accum,
+ argSignif;
+
+ exponent = exponent(st0_ptr);
+
+
+#ifdef PARANOID
+ if ( signnegative(st0_ptr) ) /* Can't hack a number < 0.0 */
+ { arith_invalid(0); return; } /* Need a positive number */
+#endif /* PARANOID */
+
+ if ( (exponent >= 0)
+ || ((exponent == -1) && (st0_ptr->sigh > 0xc90fdaa2)) )
+ {
+ EXCEPTION(0x250);
+ }
+ else
+ {
+ argSignif.lsw = 0;
+ XSIG_LL(accum) = XSIG_LL(argSignif) = significand(st0_ptr);
+
+ if ( exponent < -1 )
+ {
+ /* shift the argument right by the required places */
+ if ( FPU_shrx(&XSIG_LL(accum), -1-exponent) >= 0x80000000U )
+ XSIG_LL(accum) ++; /* round up */
+ }
+ }
+
+ XSIG_LL(argSq) = XSIG_LL(accum); argSq.lsw = accum.lsw;
+ mul_Xsig_Xsig(&argSq, &argSq);
+ XSIG_LL(argSqSq) = XSIG_LL(argSq); argSqSq.lsw = argSq.lsw;
+ mul_Xsig_Xsig(&argSqSq, &argSqSq);
+
+ /* Compute the negative terms for the numerator polynomial */
+ accumulatoro.msw = accumulatoro.midw = accumulatoro.lsw = 0;
+ polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddnegterm, HiPOWERon-1);
+ mul_Xsig_Xsig(&accumulatoro, &argSq);
+ negate_Xsig(&accumulatoro);
+ /* Add the positive terms */
+ polynomial_Xsig(&accumulatoro, &XSIG_LL(argSqSq), oddplterm, HiPOWERop-1);
+
+
+ /* Compute the positive terms for the denominator polynomial */
+ accumulatore.msw = accumulatore.midw = accumulatore.lsw = 0;
+ polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evenplterm, HiPOWERep-1);
+ mul_Xsig_Xsig(&accumulatore, &argSq);
+ negate_Xsig(&accumulatore);
+ /* Add the negative terms */
+ polynomial_Xsig(&accumulatore, &XSIG_LL(argSqSq), evennegterm, HiPOWERen-1);
+ /* Multiply by arg^2 */
+ mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+ mul64_Xsig(&accumulatore, &XSIG_LL(argSignif));
+ /* de-normalize and divide by 2 */
+ shr_Xsig(&accumulatore, -2*(1+exponent) + 1);
+ negate_Xsig(&accumulatore); /* This does 1 - accumulator */
+
+ /* Now find the ratio. */
+ if ( accumulatore.msw == 0 )
+ {
+ /* accumulatoro must contain 1.0 here, (actually, 0) but it
+ really doesn't matter what value we use because it will
+ have negligible effect in later calculations
+ */
+ XSIG_LL(accum) = BX_CONST64(0x8000000000000000);
+ accum.lsw = 0;
+ }
+ else
+ {
+ div_Xsig(&accumulatoro, &accumulatore, &accum);
+ }
+
+ /* Multiply by 1/3 * arg^3 */
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &XSIG_LL(argSignif));
+ mul64_Xsig(&accum, &twothirds);
+ shr_Xsig(&accum, -2*(exponent+1));
+
+
+ /* tan(arg) = arg + accum */
+ add_two_Xsig(&accum, &argSignif, &exponent);
+
+ if ( invert )
+ {
+ /* accum now contains tan(pi/2 - arg).
+ Use tan(arg) = 1.0 / tan(pi/2 - arg)
+ */
+ accumulatoro.lsw = accumulatoro.midw = 0;
+ accumulatoro.msw = 0x80000000;
+ div_Xsig(&accumulatoro, &accum, &accum);
+ exponent = - exponent;
+ }
+
+
+ /* Transfer the result */
+ exponent += round_Xsig(&accum);
+ FPU_settag0(TAG_Valid);
+ significand(st0_ptr) = XSIG_LL(accum);
+ setexponent16(st0_ptr, exponent + EXTENDED_Ebias); /* Result is positive. */
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | polynomial_Xsig.S |
+ | |
+ | Fixed point arithmetic polynomial evaluation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Call from C as: |
+ | void polynomial_Xsig(Xsig *accum, unsigned long long *x, |
+ | unsigned long long terms[], int n) |
+ | |
+ | Computes: |
+ | terms[0] + (terms[1] + (terms[2] + ... + (terms[n]*x)*x)*x)*x) ... )*x |
+ | and adds the result to the 12 byte Xsig. |
+ | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
+ | precision. |
+ | |
+ | This function must be used carefully: most overflow of intermediate |
+ | results is controlled, but overflow of the result is not. |
+ | |
+ +---------------------------------------------------------------------------*/
+ .file "polynomial_Xsig.S"
+
+#include "fpu_emu.h"
+
+
+#define TERM_SIZE $8
+#define SUM_MS -20(%ebp) /* sum ms long */
+#define SUM_MIDDLE -24(%ebp) /* sum middle long */
+#define SUM_LS -28(%ebp) /* sum ls long */
+#define ACCUM_MS -4(%ebp) /* accum ms long */
+#define ACCUM_MIDDLE -8(%ebp) /* accum middle long */
+#define ACCUM_LS -12(%ebp) /* accum ls long */
+#define OVERFLOWED -16(%ebp) /* addition overflow flag */
+
+.text
+ENTRY(polynomial_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ subl $32,%esp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM2,%esi /* x */
+ movl PARAM3,%edi /* terms */
+
+ movl TERM_SIZE,%eax
+ mull PARAM4 /* n */
+ addl %eax,%edi
+
+ movl 4(%edi),%edx /* terms[n] */
+ movl %edx,SUM_MS
+ movl (%edi),%edx /* terms[n] */
+ movl %edx,SUM_MIDDLE
+ xor %eax,%eax
+ movl %eax,SUM_LS
+ movb %al,OVERFLOWED
+
+ subl TERM_SIZE,%edi
+ decl PARAM4
+ js L_accum_done
+
+L_accum_loop:
+ xor %eax,%eax
+ movl %eax,ACCUM_MS
+ movl %eax,ACCUM_MIDDLE
+
+ movl SUM_MIDDLE,%eax
+ mull (%esi) /* x ls long */
+ movl %edx,ACCUM_LS
+
+ movl SUM_LS,%eax
+ mull 4(%esi) /* x ms long */
+ addl %edx,ACCUM_LS
+ adcl $0,ACCUM_MIDDLE
+ adcl $0,ACCUM_MS
+
+ movl SUM_MIDDLE,%eax
+ mull 4(%esi) /* x ms long */
+ addl %eax,ACCUM_LS
+ adcl %edx,ACCUM_MIDDLE
+ adcl $0,ACCUM_MS
+
+ movl SUM_MS,%eax
+ mull (%esi) /* x ls long */
+ addl %eax,ACCUM_LS
+ adcl %edx,ACCUM_MIDDLE
+ adcl $0,ACCUM_MS
+
+ movl SUM_MS,%eax
+ mull 4(%esi) /* x ms long */
+ addl %eax,ACCUM_MIDDLE
+ adcl %edx,ACCUM_MS
+
+ testb $0xff,OVERFLOWED
+ jz L_no_overflow
+
+ movl (%esi),%eax
+ addl %eax,ACCUM_MIDDLE
+ movl 4(%esi),%eax
+ adcl %eax,ACCUM_MS /* This could overflow too */
+
+L_no_overflow:
+
+/*
+ * Now put the sum of next term and the accumulator
+ * into the sum register
+ */
+ movl ACCUM_LS,%eax
+// addl (%edi),%eax /* term ls long */
+ movl %eax,SUM_LS
+ movl ACCUM_MIDDLE,%eax
+// adcl (%edi),%eax /* term ls long */
+ addl (%edi),%eax /* term ls long */
+ movl %eax,SUM_MIDDLE
+ movl ACCUM_MS,%eax
+ adcl 4(%edi),%eax /* term ms long */
+ movl %eax,SUM_MS
+ sbbb %al,%al
+ movb %al,OVERFLOWED /* Used in the next iteration */
+
+ subl TERM_SIZE,%edi
+ decl PARAM4
+ jns L_accum_loop
+
+L_accum_done:
+ movl PARAM1,%edi /* accum */
+ movl SUM_LS,%eax
+ addl %eax,(%edi)
+ movl SUM_MIDDLE,%eax
+ adcl %eax,4(%edi)
+ movl SUM_MS,%eax
+ adcl %eax,8(%edi)
+
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | polynomial_Xsig.c |
+ | |
+ | Fixed point arithmetic polynomial evaluation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Computes: |
+ | terms[0] + (terms[1] + (terms[2] + ... + (terms[n]*x)*x)*x)*x) ... )*x |
+ | and adds the result to the 12 byte Xsig. |
+ | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
+ | precision. |
+ | |
+ | This function must be used carefully: most overflow of intermediate |
+ | results is controlled, but overflow of the result is not. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+
+void polynomial_Xsig(Xsig *accum, const u64 *x, const u64 terms[], const int n)
+{
+ int i;
+ Xsig acc, Xprod;
+ u32 lprod;
+ u64 xlwr, xupr, prod;
+ char overflowed;
+
+ xlwr = (u32)(*x);
+ xupr = (u32)((*x) >> 32);
+
+ acc.msw = terms[n] >> 32;
+ acc.midw = terms[n];
+ acc.lsw = 0;
+ overflowed = 0;
+
+ for ( i = n-1; i >= 0; i-- )
+ {
+ /* Split the product into five parts to get a 16 byte result */
+
+ /* first word by first word */
+ prod = acc.msw * xupr;
+ Xprod.midw = prod;
+ Xprod.msw = prod >> 32;
+
+ /* first word by second word */
+ prod = acc.msw * xlwr;
+ Xprod.lsw = prod;
+ lprod = prod >> 32;
+ Xprod.midw += lprod;
+ if ( lprod > Xprod.midw )
+ Xprod.msw ++;
+
+ /* second word by first word */
+ prod = acc.midw * xupr;
+ Xprod.lsw += prod;
+ if ( (u32)prod > Xprod.lsw )
+ {
+ Xprod.midw ++;
+ if ( Xprod.midw == 0 )
+ Xprod.msw ++;
+ }
+ lprod = prod >> 32;
+ Xprod.midw += lprod;
+ if ( lprod > Xprod.midw )
+ Xprod.msw ++;
+
+ /* second word by second word */
+ prod = acc.midw * xlwr;
+ lprod = prod >> 32;
+ Xprod.lsw += lprod;
+ if ( lprod > Xprod.lsw )
+ {
+ Xprod.midw ++;
+ if ( Xprod.midw == 0 )
+ Xprod.msw ++;
+ }
+
+ /* third word by first word */
+ prod = acc.lsw * xupr;
+ lprod = prod >> 32;
+ Xprod.lsw += lprod;
+ if ( lprod > Xprod.lsw )
+ {
+ Xprod.midw ++;
+ if ( Xprod.midw == 0 )
+ Xprod.msw ++;
+ }
+
+ if ( overflowed )
+ {
+ Xprod.midw += xlwr;
+ if ( (u32)xlwr > Xprod.midw )
+ Xprod.msw ++;
+ Xprod.msw += xupr;
+ overflowed = 0; /* We don't check this addition for overflow */
+ }
+
+ acc.lsw = Xprod.lsw;
+ acc.midw = (u32)terms[i] + Xprod.midw;
+ acc.msw = (terms[i] >> 32) + Xprod.msw;
+ if ( Xprod.msw > acc.msw )
+ overflowed = 1;
+ if ( (u32)terms[i] > acc.midw )
+ {
+ acc.msw ++;
+ if ( acc.msw == 0 )
+ overflowed = 1;
+ }
+ }
+
+ /* We don't check the addition to accum for overflow */
+ accum->lsw += acc.lsw;
+ if ( acc.lsw > accum->lsw )
+ {
+ accum->midw ++;
+ if ( accum->midw == 0 )
+ accum->msw ++;
+ }
+ accum->midw += acc.midw;
+ if ( acc.midw > accum->midw )
+ {
+ accum->msw ++;
+ }
+ accum->msw += acc.msw;
+}
+
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_add_sub.c |
+ | |
+ | Functions to add or subtract two registers and put the result in a third. |
+ | |
+ | Copyright (C) 1992,1993,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | For each function, the destination may be any FPU_REG, including one of |
+ | the source FPU_REGs. |
+ | Each function returns 0 if the answer is o.k., otherwise a non-zero |
+ | value is returned, indicating either an exception condition or an |
+ | internal error. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "fpu_system.h"
+
+static
+int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
+ FPU_REG const *b, u_char tagb, u_char signb,
+ FPU_REG *dest, int deststnr, u16 control_w);
+
+/*
+ Operates on st(0) and st(n), or on st(0) and temporary data.
+ The destination must be one of the source st(x).
+ */
+int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, u16 control_w)
+{
+ FPU_REG *a = &st(0);
+ FPU_REG *dest = &st(deststnr);
+ u_char signb = getsign(b);
+ u_char taga = FPU_gettag0();
+ u_char signa = getsign(a);
+ u_char saved_sign = getsign(dest);
+ int diff, tag, expa, expb;
+
+ if ( !(taga | tagb) )
+ {
+ expa = exponent(a);
+ expb = exponent(b);
+
+ valid_add:
+ /* Both registers are valid */
+ if (!(signa ^ signb))
+ {
+ /* signs are the same */
+ tag = FPU_u_add(a, b, dest, control_w, signa, expa, expb);
+ }
+ else
+ {
+ /* The signs are different, so do a subtraction */
+ diff = expa - expb;
+ if (!diff)
+ {
+ diff = a->sigh - b->sigh; /* This works only if the ms bits
+ are identical. */
+ if (!diff)
+ {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+
+ if (diff > 0)
+ {
+ tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
+ }
+ else if ( diff < 0 )
+ {
+ tag = FPU_u_sub(b, a, dest, control_w, signb, expb, expa);
+ }
+ else
+ {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ /* sign depends upon rounding mode */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ return TAG_Zero;
+ }
+ }
+
+ if ( tag < 0 )
+ {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+
+ if ( taga == TAG_Special )
+ taga = FPU_Special(a);
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+
+ if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+ {
+ FPU_REG x, y;
+
+ if ( denormal_operand() < 0 )
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ a = &x;
+ b = &y;
+ expa = exponent16(a);
+ expb = exponent16(b);
+ goto valid_add;
+ }
+
+ if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+ {
+ if ( deststnr == 0 )
+ return real_2op_NaN(b, tagb, deststnr, a);
+ else
+ return real_2op_NaN(a, taga, deststnr, a);
+ }
+
+ return add_sub_specials(a, taga, signa, b, tagb, signb,
+ dest, deststnr, control_w);
+}
+
+
+/* Subtract b from a. (a-b) -> dest
+ bbd: arg2 used to be int type, but sometimes pointers were forced
+ in with typecasts. On Alphas pointers are 64 bits and ints are 32,
+ so when rm was cast back to a pointer...SEGFAULT. Pass the pointers
+ around instead, since they are always larger precision than the
+ register numbers. */
+int FPU_sub(int flags, FPU_REG *rm, u16 control_w)
+{
+ FPU_REG const *a, *b;
+ FPU_REG *dest;
+ u_char taga, tagb, signa, signb, saved_sign, sign;
+ int diff, tag, expa, expb, deststnr;
+
+ a = &st(0);
+ taga = FPU_gettag0();
+
+ deststnr = 0;
+ if ( flags & LOADED )
+ {
+ b = rm;
+ tagb = flags & 0x0f;
+ }
+ else
+ {
+ int rmint = PTR2INT(rm);
+ b = &st(rmint);
+ tagb = FPU_gettagi(rmint);
+
+ if ( flags & DEST_RM )
+ deststnr = rmint;
+ }
+
+ signa = getsign(a);
+ signb = getsign(b);
+
+ if ( flags & REV )
+ {
+ signa ^= SIGN_NEG;
+ signb ^= SIGN_NEG;
+ }
+
+ dest = &st(deststnr);
+ saved_sign = getsign(dest);
+
+ if ( !(taga | tagb) )
+ {
+ expa = exponent(a);
+ expb = exponent(b);
+
+ valid_subtract:
+ /* Both registers are valid */
+
+ diff = expa - expb;
+
+ if (!diff)
+ {
+ diff = a->sigh - b->sigh; /* Works only if ms bits are identical */
+ if (!diff)
+ {
+ diff = a->sigl > b->sigl;
+ if (!diff)
+ diff = -(a->sigl < b->sigl);
+ }
+ }
+
+ switch ( (((int)signa)*2 + signb) / SIGN_NEG )
+ {
+ case 0: /* P - P */
+ case 3: /* N - N */
+ if (diff > 0)
+ {
+ /* |a| > |b| */
+ tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb);
+ }
+ else if ( diff == 0 )
+ {
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+
+ /* sign depends upon rounding mode */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ return TAG_Zero;
+ }
+ else
+ {
+ sign = signa ^ SIGN_NEG;
+ tag = FPU_u_sub(b, a, dest, control_w, sign, expb, expa);
+ }
+ break;
+ case 1: /* P - N */
+ tag = FPU_u_add(a, b, dest, control_w, SIGN_POS, expa, expb);
+ break;
+ case 2: /* N - P */
+ tag = FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa, expb);
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x111);
+ return -1;
+#endif
+ }
+ if ( tag < 0 )
+ {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+
+ if ( taga == TAG_Special )
+ taga = FPU_Special(a);
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+
+ if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+ {
+ FPU_REG x, y;
+
+ if ( denormal_operand() < 0 )
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ a = &x;
+ b = &y;
+ expa = exponent16(a);
+ expb = exponent16(b);
+
+ goto valid_subtract;
+ }
+
+ if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+ {
+ FPU_REG const *d1, *d2;
+ if ( flags & REV )
+ {
+ d1 = b;
+ d2 = a;
+ }
+ else
+ {
+ d1 = a;
+ d2 = b;
+ }
+ if ( flags & LOADED )
+ return real_2op_NaN(b, tagb, deststnr, d1);
+ if ( flags & DEST_RM )
+ return real_2op_NaN(a, taga, deststnr, d2);
+ else
+ return real_2op_NaN(b, tagb, deststnr, d2);
+ }
+
+ return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG,
+ dest, deststnr, control_w);
+}
+
+
+static
+int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
+ FPU_REG const *b, u_char tagb, u_char signb,
+ FPU_REG *dest, int deststnr, u16 control_w)
+{
+ if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
+ && (denormal_operand() < 0) )
+ return FPU_Exception;
+
+ if (taga == TAG_Zero)
+ {
+ if (tagb == TAG_Zero)
+ {
+ /* Both are zero, result will be zero. */
+ u_char different_signs = signa ^ signb;
+
+ FPU_copy_to_regi(a, TAG_Zero, deststnr);
+ if ( different_signs )
+ {
+ /* Signs are different. */
+ /* Sign of answer depends upon rounding mode. */
+ setsign(dest, ((control_w & CW_RC) != RC_DOWN)
+ ? SIGN_POS : SIGN_NEG);
+ }
+ else
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ return TAG_Zero;
+ }
+ else
+ {
+ reg_copy(b, dest);
+ if ( (tagb == TW_Denormal) && (b->sigh & 0x80000000) )
+ {
+ /* A pseudoDenormal, convert it. */
+ addexponent(dest, 1);
+ tagb = TAG_Valid;
+ }
+ else if ( tagb > TAG_Empty )
+ tagb = TAG_Special;
+ setsign(dest, signb); /* signb may differ from the sign of b. */
+ FPU_settagi(deststnr, tagb);
+ return tagb;
+ }
+ }
+ else if (tagb == TAG_Zero)
+ {
+ reg_copy(a, dest);
+ if ( (taga == TW_Denormal) && (a->sigh & 0x80000000) )
+ {
+ /* A pseudoDenormal */
+ addexponent(dest, 1);
+ taga = TAG_Valid;
+ }
+ else if ( taga > TAG_Empty )
+ taga = TAG_Special;
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ FPU_settagi(deststnr, taga);
+ return taga;
+ }
+ else if (taga == TW_Infinity)
+ {
+ if ( (tagb != TW_Infinity) || (signa == signb) )
+ {
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, signa); /* signa may differ from the sign of a. */
+ return taga;
+ }
+ /* Infinity-Infinity is undefined. */
+ return arith_invalid(deststnr);
+ }
+ else if (tagb == TW_Infinity)
+ {
+ FPU_copy_to_regi(b, TAG_Special, deststnr);
+ setsign(dest, signb); /* signb may differ from the sign of b. */
+ return tagb;
+ }
+
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL|0x101);
+#endif
+
+ return FPU_Exception;
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_compare.c |
+ | |
+ | Compare two floating point registers |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | compare() is the core FPU_REG comparison function |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+static int compare(FPU_REG const *b, int tagb)
+{
+ int diff, exp0, expb;
+ u_char st0_tag;
+ FPU_REG *st0_ptr;
+ FPU_REG x, y;
+ u_char st0_sign, signb = getsign(b);
+
+ st0_ptr = &st(0);
+ st0_tag = FPU_gettag0();
+ st0_sign = getsign(st0_ptr);
+
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+ if ( st0_tag == TAG_Special )
+ st0_tag = FPU_Special(st0_ptr);
+
+ if ( ((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal))
+ || ((tagb != TAG_Valid) && (tagb != TW_Denormal)) )
+ {
+ if ( st0_tag == TAG_Zero )
+ {
+ if ( tagb == TAG_Zero ) return COMP_A_eq_B;
+ if ( tagb == TAG_Valid )
+ return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+ if ( tagb == TW_Denormal )
+ return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | COMP_Denormal;
+ }
+ else if ( tagb == TAG_Zero )
+ {
+ if ( st0_tag == TAG_Valid )
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ if ( st0_tag == TW_Denormal )
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | COMP_Denormal;
+ }
+
+ if ( st0_tag == TW_Infinity )
+ {
+ if ( (tagb == TAG_Valid) || (tagb == TAG_Zero) )
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ else if ( tagb == TW_Denormal )
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | COMP_Denormal;
+ else if ( tagb == TW_Infinity )
+ {
+ /* The 80486 book says that infinities can be equal! */
+ return (st0_sign == signb) ? COMP_A_eq_B :
+ ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B);
+ }
+ /* Fall through to the NaN code */
+ }
+ else if ( tagb == TW_Infinity )
+ {
+ if ( (st0_tag == TAG_Valid) || (st0_tag == TAG_Zero) )
+ return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B);
+ if ( st0_tag == TW_Denormal )
+ return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | COMP_Denormal;
+ /* Fall through to the NaN code */
+ }
+
+ /* The only possibility now should be that one of the arguments
+ is a NaN */
+ if ( (st0_tag == TW_NaN) || (tagb == TW_NaN) )
+ {
+ int signalling = 0, unsupported = 0;
+ if ( st0_tag == TW_NaN )
+ {
+ signalling = (st0_ptr->sigh & 0xc0000000) == 0x80000000;
+ unsupported = !((exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->sigh & 0x80000000));
+ }
+ if ( tagb == TW_NaN )
+ {
+ signalling |= (b->sigh & 0xc0000000) == 0x80000000;
+ unsupported |= !((exponent(b) == EXP_OVER)
+ && (b->sigh & 0x80000000));
+ }
+ if ( signalling || unsupported )
+ return COMP_No_Comp | COMP_SNaN | COMP_NaN;
+ else
+ /* Neither is a signaling NaN */
+ return COMP_No_Comp | COMP_NaN;
+ }
+
+ EXCEPTION(EX_Invalid);
+ }
+
+ if (st0_sign != signb)
+ {
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+ }
+
+ if ( (st0_tag == TW_Denormal) || (tagb == TW_Denormal) )
+ {
+ FPU_to_exp16(st0_ptr, &x);
+ FPU_to_exp16(b, &y);
+ st0_ptr = &x;
+ b = &y;
+ exp0 = exponent16(st0_ptr);
+ expb = exponent16(b);
+ }
+ else
+ {
+ exp0 = exponent(st0_ptr);
+ expb = exponent(b);
+ }
+
+#ifdef PARANOID
+ if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+ if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+#endif /* PARANOID */
+
+ diff = exp0 - expb;
+ if ( diff == 0 )
+ {
+ diff = st0_ptr->sigh - b->sigh; /* Works only if ms bits are
+ identical */
+ if ( diff == 0 )
+ {
+ diff = st0_ptr->sigl > b->sigl;
+ if ( diff == 0 )
+ diff = -(st0_ptr->sigl < b->sigl);
+ }
+ }
+
+ if ( diff > 0 )
+ {
+ return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B)
+ | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+ }
+ if ( diff < 0 )
+ {
+ return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B)
+ | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+ }
+
+ return COMP_A_eq_B
+ | ( ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ?
+ COMP_Denormal : 0);
+
+}
+
+
+/* This function requires that st(0) is not empty */
+int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
+{
+ int f, c;
+
+ c = compare(loaded_data, loaded_tag);
+
+ if (c & COMP_NaN)
+ {
+ EXCEPTION(EX_Invalid);
+ f = SW_C3 | SW_C2 | SW_C0;
+ }
+ else
+ switch (c & 7)
+ {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x121);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ if (c & COMP_Denormal)
+ {
+ return denormal_operand() < 0;
+ }
+ return 0;
+}
+
+
+static int compare_st_st(int nr)
+{
+ int f, c;
+ FPU_REG *st_ptr;
+
+ if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
+ {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
+ }
+
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN)
+ {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ }
+ else
+ switch (c & 7)
+ {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x122);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ if (c & COMP_Denormal)
+ {
+ return denormal_operand() < 0;
+ }
+ return 0;
+}
+
+
+static int compare_u_st_st(int nr)
+{
+ int f, c;
+ FPU_REG *st_ptr;
+
+ if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
+ {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ /* Stack fault */
+ EXCEPTION(EX_StackUnder);
+ return !(control_word & CW_Invalid);
+ }
+
+ st_ptr = &st(nr);
+ c = compare(st_ptr, FPU_gettagi(nr));
+ if (c & COMP_NaN)
+ {
+ setcc(SW_C3 | SW_C2 | SW_C0);
+ if (c & COMP_SNaN) /* This is the only difference between
+ un-ordered and ordinary comparisons */
+ {
+ EXCEPTION(EX_Invalid);
+ return !(control_word & CW_Invalid);
+ }
+ return 0;
+ }
+ else
+ switch (c & 7)
+ {
+ case COMP_A_lt_B:
+ f = SW_C0;
+ break;
+ case COMP_A_eq_B:
+ f = SW_C3;
+ break;
+ case COMP_A_gt_B:
+ f = 0;
+ break;
+ case COMP_No_Comp:
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#ifdef PARANOID
+ default:
+ EXCEPTION(EX_INTERNAL|0x123);
+ f = SW_C3 | SW_C2 | SW_C0;
+ break;
+#endif /* PARANOID */
+ }
+ setcc(f);
+ if (c & COMP_Denormal)
+ {
+ return denormal_operand() < 0;
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void fcom_st()
+{
+ /* fcom st(i) */
+ compare_st_st(FPU_rm);
+}
+
+
+void fcompst()
+{
+ /* fcomp st(i) */
+ if ( !compare_st_st(FPU_rm) )
+ FPU_pop();
+}
+
+
+void fcompp()
+{
+ /* fcompp */
+ if (FPU_rm != 1)
+ {
+ FPU_illegal();
+ return;
+ }
+ if ( !compare_st_st(1) )
+ poppop();
+}
+
+
+void fucom_()
+{
+ /* fucom st(i) */
+ compare_u_st_st(FPU_rm);
+
+}
+
+
+void fucomp()
+{
+ /* fucomp st(i) */
+ if ( !compare_u_st_st(FPU_rm) )
+ FPU_pop();
+}
+
+
+void fucompp()
+{
+ /* fucompp */
+ if (FPU_rm == 1)
+ {
+ if ( !compare_u_st_st(1) )
+ poppop();
+ }
+ else
+ FPU_illegal();
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_constant.c |
+ | |
+ | All of the constant FPU_REGs |
+ | |
+ | Copyright (C) 1992,1993,1994,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_system.h"
+#include "fpu_emu.h"
+#include "status_w.h"
+#include "reg_constant.h"
+#include "control_w.h"
+
+
+
+FPU_REG const CONST_1 = MAKE_REG(POS, 0, 0x00000000, 0x80000000);
+FPU_REG const CONST_2 = MAKE_REG(POS, 1, 0x00000000, 0x80000000);
+FPU_REG const CONST_HALF = MAKE_REG(POS, -1, 0x00000000, 0x80000000);
+FPU_REG const CONST_L2T = MAKE_REG(POS, 1, 0xcd1b8afe, 0xd49a784b);
+FPU_REG const CONST_L2E = MAKE_REG(POS, 0, 0x5c17f0bc, 0xb8aa3b29);
+FPU_REG const CONST_PI = MAKE_REG(POS, 1, 0x2168c235, 0xc90fdaa2);
+// bbd: make CONST_PI2 non-const so that you can write "&CONST_PI2" when
+// calling a function. Otherwise you get const warnings. Surely there's
+// a better way.
+FPU_REG CONST_PI2 = MAKE_REG(POS, 0, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_PI4 = MAKE_REG(POS, -1, 0x2168c235, 0xc90fdaa2);
+FPU_REG const CONST_LG2 = MAKE_REG(POS, -2, 0xfbcff799, 0x9a209a84);
+FPU_REG const CONST_LN2 = MAKE_REG(POS, -1, 0xd1cf79ac, 0xb17217f7);
+
+/* Extra bits to take pi/2 to more than 128 bits precision. */
+FPU_REG const CONST_PI2extra = MAKE_REG(NEG, -66,
+ 0xfc8f8cbb, 0xece675d1);
+
+/* Only the sign (and tag) is used in internal zeroes */
+FPU_REG const CONST_Z = MAKE_REG(POS, EXP_UNDER, 0x0, 0x0);
+
+/* Only the sign and significand (and tag) are used in internal NaNs */
+/* The 80486 never generates one of these
+FPU_REG const CONST_SNAN = MAKE_REG(POS, EXP_OVER, 0x00000001, 0x80000000);
+ */
+/* This is the real indefinite QNaN */
+FPU_REG const CONST_QNaN = MAKE_REG(NEG, EXP_OVER, 0x00000000, 0xC0000000);
+
+/* Only the sign (and tag) is used in internal infinities */
+FPU_REG const CONST_INF = MAKE_REG(POS, EXP_OVER, 0x00000000, 0x80000000);
+
+
+static void fld_const(FPU_REG const *c, int adj, u_char tag)
+{
+ FPU_REG *st_new_ptr;
+
+ if ( STACK_OVERFLOW )
+ {
+ FPU_stack_overflow();
+ return;
+ }
+ push();
+ reg_copy(c, st_new_ptr);
+ st_new_ptr->sigl += adj; /* For all our fldxxx constants, we don't need to
+ borrow or carry. */
+ FPU_settag0(tag);
+ clear_C1();
+}
+
+/* A fast way to find out whether x is one of RC_DOWN or RC_CHOP
+ (and not one of RC_RND or RC_UP).
+ */
+#define DOWN_OR_CHOP(x) (x & RC_DOWN)
+
+static void fld1(int rc)
+{
+ fld_const(&CONST_1, 0, TAG_Valid);
+}
+
+static void fldl2t(int rc)
+{
+ fld_const(&CONST_L2T, (rc == RC_UP) ? 1 : 0, TAG_Valid);
+}
+
+static void fldl2e(int rc)
+{
+ fld_const(&CONST_L2E, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldpi(int rc)
+{
+ fld_const(&CONST_PI, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldlg2(int rc)
+{
+ fld_const(&CONST_LG2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldln2(int rc)
+{
+ fld_const(&CONST_LN2, DOWN_OR_CHOP(rc) ? -1 : 0, TAG_Valid);
+}
+
+static void fldz(int rc)
+{
+ fld_const(&CONST_Z, 0, TAG_Zero);
+}
+
+typedef void (*FUNC_RC)(int);
+
+static FUNC_RC constants_table[] = {
+ fld1, fldl2t, fldl2e, fldpi, fldlg2, fldln2, fldz, (FUNC_RC)FPU_illegal
+};
+
+void fconst(void)
+{
+ (constants_table[FPU_rm])(control_word & CW_RC);
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_constant.h |
+ | |
+ | Copyright (C) 1992 W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _REG_CONSTANT_H_
+#define _REG_CONSTANT_H_
+
+#include "fpu_emu.h"
+
+extern FPU_REG const CONST_1;
+extern FPU_REG const CONST_2;
+extern FPU_REG const CONST_HALF;
+extern FPU_REG const CONST_L2T;
+extern FPU_REG const CONST_L2E;
+extern FPU_REG const CONST_PI;
+// bbd: make CONST_PI2 non-const so that you can write "&CONST_PI2" when
+// calling a function. Otherwise you get const warnings. Surely there's
+// a better way.
+extern FPU_REG CONST_PI2;
+extern FPU_REG const CONST_PI2extra;
+extern FPU_REG const CONST_PI4;
+extern FPU_REG const CONST_LG2;
+extern FPU_REG const CONST_LN2;
+extern FPU_REG const CONST_Z;
+extern FPU_REG const CONST_PINF;
+extern FPU_REG const CONST_INF;
+extern FPU_REG const CONST_MINF;
+extern FPU_REG const CONST_QNaN;
+
+#endif /* _REG_CONSTANT_H_ */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_convert.c |
+ | |
+ | Convert register representation. |
+ | |
+ | Copyright (C) 1992,1993,1994,1996,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
+{
+ int sign = getsign(a);
+
+#ifndef EMU_BIG_ENDIAN
+ *(s64 *)&(x->sigl) = *(const s64 *)&(a->sigl);
+#else
+ *(s64 *)&(x->sigh) = *(const s64 *)&(a->sigh);
+#endif
+
+ /* Set up the exponent as a 16 bit quantity. */
+ setexponent16(x, exponent(a));
+
+ if ( exponent16(x) == EXP_UNDER )
+ {
+ /* The number is a de-normal or pseudodenormal. */
+ /* We only deal with the significand and exponent. */
+
+ if (x->sigh & 0x80000000)
+ {
+ /* Is a pseudodenormal. */
+ /* This is non-80486 behaviour because the number
+ loses its 'denormal' identity. */
+ addexponent(x, 1);
+ }
+ else
+ {
+ /* Is a denormal. */
+ addexponent(x, 1);
+ FPU_normalize_nuo(x, 0);
+ }
+ }
+
+ if ( !(x->sigh & 0x80000000) )
+ {
+ EXCEPTION(EX_INTERNAL | 0x180);
+ }
+
+ return sign;
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_divide.c |
+ | |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ | |
+ | Copyright (C) 1996 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_emu.h"
+#include "fpu_system.h"
+
+/*
+ Divide one register by another and put the result into a third register.
+bbd: arg2 used to be an int, see comments on FPU_sub.
+ */
+int FPU_div(int flags, FPU_REG *rm, int control_w)
+{
+ FPU_REG x, y;
+ FPU_REG const *a, *b, *st0_ptr, *st_ptr;
+ FPU_REG *dest;
+ u_char taga, tagb, signa, signb, sign, saved_sign;
+ int tag, deststnr;
+ int rmint = PTR2INT(rm);
+
+ if ( flags & DEST_RM )
+ deststnr = rmint;
+ else
+ deststnr = 0;
+
+ if ( flags & REV )
+ {
+ b = &st(0);
+ st0_ptr = b;
+ tagb = FPU_gettag0();
+ if ( flags & LOADED )
+ {
+ a = rm;
+ taga = flags & 0x0f;
+ }
+ else
+ {
+ a = &st(rmint);
+ st_ptr = a;
+ taga = FPU_gettagi(rmint);
+ }
+ }
+ else
+ {
+ a = &st(0);
+ st0_ptr = a;
+ taga = FPU_gettag0();
+ if ( flags & LOADED )
+ {
+ b = rm;
+ tagb = flags & 0x0f;
+ }
+ else
+ {
+ b = &st(rmint);
+ st_ptr = b;
+ tagb = FPU_gettagi(rmint);
+ }
+ }
+
+ signa = getsign(a);
+ signb = getsign(b);
+
+ sign = signa ^ signb;
+
+ dest = &st(deststnr);
+ saved_sign = getsign(dest);
+
+ if ( !(taga | tagb) )
+ {
+ /* Both regs Valid, this should be the most common case. */
+ reg_copy(a, &x);
+ reg_copy(b, &y);
+ setpositive(&x);
+ setpositive(&y);
+ tag = FPU_u_div(&x, &y, dest, control_w, sign);
+
+ if ( tag < 0 )
+ return tag;
+
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+
+ if ( taga == TAG_Special )
+ taga = FPU_Special(a);
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+
+ if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+ {
+ if ( denormal_operand() < 0 )
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ tag = FPU_u_div(&x, &y, dest, control_w, sign);
+ if ( tag < 0 )
+ return tag;
+
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+ else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
+ {
+ if ( tagb != TAG_Zero )
+ {
+ /* Want to find Zero/Valid */
+ if ( tagb == TW_Denormal )
+ {
+ if ( denormal_operand() < 0 )
+ return FPU_Exception;
+ }
+
+ /* The result is zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ setsign(dest, sign);
+ return TAG_Zero;
+ }
+ /* We have an exception condition, either 0/0 or Valid/Zero. */
+ if ( taga == TAG_Zero )
+ {
+ /* 0/0 */
+ return arith_invalid(deststnr);
+ }
+ /* Valid/Zero */
+ return FPU_divide_by_zero(deststnr, sign);
+ }
+ /* Must have infinities, NaNs, etc */
+ else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+ {
+ if ( flags & LOADED )
+ return real_2op_NaN((FPU_REG *)rm, flags & 0x0f, 0, st0_ptr);
+
+ if ( flags & DEST_RM )
+ {
+ int tag;
+ tag = FPU_gettag0();
+ if ( tag == TAG_Special )
+ tag = FPU_Special(st0_ptr);
+ return real_2op_NaN(st0_ptr, tag, rmint, (flags & REV) ? st0_ptr : &st(rmint));
+ }
+ else
+ {
+ int tag;
+ tag = FPU_gettagi(rmint);
+ if ( tag == TAG_Special )
+ tag = FPU_Special(&st(rmint));
+ return real_2op_NaN(&st(rmint), tag, 0, (flags & REV) ? st0_ptr : &st(rmint));
+ }
+ }
+ else if (taga == TW_Infinity)
+ {
+ if (tagb == TW_Infinity)
+ {
+ /* infinity/infinity */
+ return arith_invalid(deststnr);
+ }
+ else
+ {
+ /* tagb must be Valid or Zero */
+ if ( (tagb == TW_Denormal) && (denormal_operand() < 0) )
+ return FPU_Exception;
+
+ /* Infinity divided by Zero or Valid does
+ not raise and exception, but returns Infinity */
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return taga;
+ }
+ }
+ else if (tagb == TW_Infinity)
+ {
+ if ( (taga == TW_Denormal) && (denormal_operand() < 0) )
+ return FPU_Exception;
+
+ /* The result is zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ setsign(dest, sign);
+ return TAG_Zero;
+ }
+#ifdef PARANOID
+ else
+ {
+ EXCEPTION(EX_INTERNAL|0x102);
+ return FPU_Exception;
+ }
+#endif /* PARANOID */
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_ld_str.c |
+ | |
+ | All of the functions which transfer data between user memory and FPU_REGs.|
+ | |
+ | Copyright (C) 1992,1993,1994,1996,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Note: |
+ | The file contains code which accesses user memory. |
+ | Emulator static data may change when user memory is accessed, due to |
+ | other processes using the emulator while swapping is in progress. |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+#include <asm/uaccess.h>
+
+#include "fpu_system.h"
+#include "exception.h"
+#include "reg_constant.h"
+#include "control_w.h"
+#include "status_w.h"
+
+
+#define DOUBLE_Emax 1023 /* largest valid exponent */
+#define DOUBLE_Ebias 1023
+#define DOUBLE_Emin (-1022) /* smallest valid exponent */
+
+#define SINGLE_Emax 127 /* largest valid exponent */
+#define SINGLE_Ebias 127
+#define SINGLE_Emin (-126) /* smallest valid exponent */
+
+
+static u_char normalize_no_excep(FPU_REG *r, int exp, int sign)
+{
+ u_char tag;
+
+ setexponent16(r, exp);
+
+ tag = FPU_normalize_nuo(r, 0);
+ stdexp(r);
+ if ( sign )
+ setnegative(r);
+
+ return tag;
+}
+
+
+int FPU_tagof(FPU_REG *ptr)
+{
+ int exp;
+
+ exp = exponent16(ptr) & 0x7fff;
+ if ( exp == 0 )
+ {
+ if ( !(ptr->sigh | ptr->sigl) )
+ {
+ return TAG_Zero;
+ }
+ /* The number is a de-normal or pseudodenormal. */
+ return TAG_Special;
+ }
+
+ if ( exp == 0x7fff )
+ {
+ /* Is an Infinity, a NaN, or an unsupported data type. */
+ return TAG_Special;
+ }
+
+ if ( !(ptr->sigh & 0x80000000) )
+ {
+ /* Unsupported data type. */
+ /* Valid numbers have the ms bit set to 1. */
+ /* Unnormal. */
+ return TAG_Special;
+ }
+
+ return TAG_Valid;
+}
+
+
+/* Get a long double from user memory */
+int FPU_load_extended(long double *s, int stnr)
+{
+ FPU_REG *sti_ptr = &st(stnr);
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, s, 10);
+#ifndef USE_WITH_CPU_SIM
+ __copy_from_user(sti_ptr, s, 10);
+#else
+ FPU_get_user(sti_ptr->sigl, (u32*)(((u8*)s)+0));
+ FPU_get_user(sti_ptr->sigh, (u32*)(((u8*)s)+4));
+ FPU_get_user(sti_ptr->exp, (u16*)(((u8*)s)+8));
+#endif
+ RE_ENTRANT_CHECK_ON;
+
+ return FPU_tagof(sti_ptr);
+}
+
+
+/* Get a double from user memory */
+int FPU_load_double(double *dfloat, FPU_REG *loaded_data)
+{
+ int exp, tag, negative;
+ u32 m64, l64;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, dfloat, 8);
+ FPU_get_user(m64, 1 + (u32 *) dfloat);
+ FPU_get_user(l64, (u32 *) dfloat);
+ RE_ENTRANT_CHECK_ON;
+
+ negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+ exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
+ m64 &= 0xfffff;
+ if ( exp > DOUBLE_Emax + EXTENDED_Ebias )
+ {
+ /* Infinity or NaN */
+ if ((m64 == 0) && (l64 == 0))
+ {
+ /* +- infinity */
+ loaded_data->sigh = 0x80000000;
+ loaded_data->sigl = 0x00000000;
+ exp = EXP_Infinity + EXTENDED_Ebias;
+ tag = TAG_Special;
+ }
+ else
+ {
+ /* Must be a signaling or quiet NaN */
+ exp = EXP_NaN + EXTENDED_Ebias;
+ loaded_data->sigh = (m64 << 11) | 0x80000000;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
+ tag = TAG_Special; /* The calling function must look for NaNs */
+ }
+ }
+ else if ( exp < DOUBLE_Emin + EXTENDED_Ebias )
+ {
+ /* Zero or de-normal */
+ if ((m64 == 0) && (l64 == 0))
+ {
+ /* Zero */
+ reg_copy(&CONST_Z, loaded_data);
+ exp = 0;
+ tag = TAG_Zero;
+ }
+ else
+ {
+ /* De-normal */
+ loaded_data->sigh = m64 << 11;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
+
+ return normalize_no_excep(loaded_data, DOUBLE_Emin, negative)
+ | (denormal_operand() < 0 ? FPU_Exception : 0);
+ }
+ }
+ else
+ {
+ loaded_data->sigh = (m64 << 11) | 0x80000000;
+ loaded_data->sigh |= l64 >> 21;
+ loaded_data->sigl = l64 << 11;
+
+ tag = TAG_Valid;
+ }
+
+ setexponent16(loaded_data, exp | negative);
+
+ return tag;
+}
+
+
+/* Get a float from user memory */
+int FPU_load_single(float *single, FPU_REG *loaded_data)
+{
+ u32 m32;
+ int exp, tag, negative;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, single, 4);
+ FPU_get_user(m32, (u32 *) single);
+ RE_ENTRANT_CHECK_ON;
+
+ negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
+
+ if (!(m32 & 0x7fffffff))
+ {
+ /* Zero */
+ reg_copy(&CONST_Z, loaded_data);
+ addexponent(loaded_data, negative);
+ return TAG_Zero;
+ }
+ exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
+ m32 = (m32 & 0x7fffff) << 8;
+ if ( exp < SINGLE_Emin + EXTENDED_Ebias )
+ {
+ /* De-normals */
+ loaded_data->sigh = m32;
+ loaded_data->sigl = 0;
+
+ return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
+ | (denormal_operand() < 0 ? FPU_Exception : 0);
+ }
+ else if ( exp > SINGLE_Emax + EXTENDED_Ebias )
+ {
+ /* Infinity or NaN */
+ if ( m32 == 0 )
+ {
+ /* +- infinity */
+ loaded_data->sigh = 0x80000000;
+ loaded_data->sigl = 0x00000000;
+ exp = EXP_Infinity + EXTENDED_Ebias;
+ tag = TAG_Special;
+ }
+ else
+ {
+ /* Must be a signaling or quiet NaN */
+ exp = EXP_NaN + EXTENDED_Ebias;
+ loaded_data->sigh = m32 | 0x80000000;
+ loaded_data->sigl = 0;
+ tag = TAG_Special; /* The calling function must look for NaNs */
+ }
+ }
+ else
+ {
+ loaded_data->sigh = m32 | 0x80000000;
+ loaded_data->sigl = 0;
+ tag = TAG_Valid;
+ }
+
+ setexponent16(loaded_data, exp | negative); /* Set the sign. */
+
+ return tag;
+}
+
+
+/* Get a 64bit quantity from user memory */
+int FPU_load_int64(s64 *_s)
+{
+ s64 s;
+ int sign;
+ FPU_REG *st0_ptr = &st(0);
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, _s, 8);
+#ifndef USE_WITH_CPU_SIM
+ copy_from_user(&s,_s,8);
+#else
+ {
+ u32 chunk0, chunk1;
+ FPU_get_user(chunk0, (u32*)(((u8*)_s)+0));
+ FPU_get_user(chunk1, (u32*)(((u8*)_s)+4));
+ s = chunk0;
+ s |= (((u64)chunk1) << 32);
+ }
+#endif
+ RE_ENTRANT_CHECK_ON;
+
+ if (s == 0)
+ {
+ reg_copy(&CONST_Z, st0_ptr);
+ return TAG_Zero;
+ }
+
+ if (s > 0)
+ sign = SIGN_Positive;
+ else
+ {
+ s = -s;
+ sign = SIGN_Negative;
+ }
+
+ significand(st0_ptr) = s;
+
+ return normalize_no_excep(st0_ptr, 63, sign);
+}
+
+
+/* Get a long from user memory */
+int FPU_load_int32(s32 *_s, FPU_REG *loaded_data)
+{
+ s32 s;
+ int negative;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, _s, 4);
+ FPU_get_user(s, _s);
+ RE_ENTRANT_CHECK_ON;
+
+ if (s == 0)
+ { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+
+ if (s > 0)
+ negative = SIGN_Positive;
+ else
+ {
+ s = -s;
+ negative = SIGN_Negative;
+ }
+
+ loaded_data->sigh = s;
+ loaded_data->sigl = 0;
+
+ return normalize_no_excep(loaded_data, 31, negative);
+}
+
+
+/* Get a short from user memory */
+int FPU_load_int16(s16 *_s, FPU_REG *loaded_data)
+{
+ int s, negative;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, _s, 2);
+ /* Cast as short to get the sign extended. */
+ FPU_get_user(s, _s);
+ RE_ENTRANT_CHECK_ON;
+
+ if (s == 0)
+ { reg_copy(&CONST_Z, loaded_data); return TAG_Zero; }
+
+ if (s > 0)
+ negative = SIGN_Positive;
+ else
+ {
+ s = -s;
+ negative = SIGN_Negative;
+ }
+
+ loaded_data->sigh = s << 16;
+ loaded_data->sigl = 0;
+
+ return normalize_no_excep(loaded_data, 15, negative);
+}
+
+
+/* Get a packed bcd array from user memory */
+int FPU_load_bcd(u_char *s)
+{
+ FPU_REG *st0_ptr = &st(0);
+ int pos;
+ u_char bcd;
+ s64 l=0;
+ int sign;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, s, 10);
+ RE_ENTRANT_CHECK_ON;
+ for ( pos = 8; pos >= 0; pos--)
+ {
+ l *= 10;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_get_user(bcd, (u_char *) s+pos);
+ RE_ENTRANT_CHECK_ON;
+ l += bcd >> 4;
+ l *= 10;
+ l += bcd & 0x0f;
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_get_user(sign, (u_char *) s+9);
+ sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
+ RE_ENTRANT_CHECK_ON;
+
+ if ( l == 0 )
+ {
+ reg_copy(&CONST_Z, st0_ptr);
+ addexponent(st0_ptr, sign); /* Set the sign. */
+ return TAG_Zero;
+ }
+ else
+ {
+ significand(st0_ptr) = l;
+ return normalize_no_excep(st0_ptr, 63, sign);
+ }
+}
+
+/*===========================================================================*/
+
+/* Put a long double into user memory */
+int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag, long double *d)
+{
+ /*
+ The only exception raised by an attempt to store to an
+ extended format is the Invalid Stack exception, i.e.
+ attempting to store from an empty register.
+ */
+
+ if ( st0_tag != TAG_Empty )
+ {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE, d, 10);
+
+ FPU_put_user(st0_ptr->sigl, (u32 *) d);
+ FPU_put_user(st0_ptr->sigh, (u32 *) ((u_char *)d + 4));
+ FPU_put_user(exponent16(st0_ptr), (u16 *) ((u_char *)d + 8));
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+ }
+
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,10);
+ FPU_put_user(0, (u32 *) d);
+ FPU_put_user(0xc0000000, 1 + (u32 *) d);
+ FPU_put_user(0xffff, 4 + (s16 *) d);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ }
+ else
+ return 0;
+
+}
+
+
+/* Put a double into user memory */
+int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double *dfloat)
+{
+ u32 l[2];
+ u32 increment = 0; /* avoid gcc warnings */
+ int precision_loss;
+ int exp;
+ FPU_REG tmp;
+
+ if ( st0_tag == TAG_Valid )
+ {
+ reg_copy(st0_ptr, &tmp);
+ exp = exponent(&tmp);
+
+ if ( exp < DOUBLE_Emin ) /* It may be a denormal */
+ {
+ addexponent(&tmp, -DOUBLE_Emin + 52); /* largest exp to be 51 */
+
+ denormal_arg:
+
+ if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
+ {
+#ifdef PECULIAR_486
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as peculiar, it appears
+ that the 80486 rounds to the dest precision, then
+ converts to decide underflow. */
+ if ( !((tmp.sigh == 0x00100000) && (tmp.sigl == 0) &&
+ (st0_ptr->sigl & 0x000007ff)) )
+#endif /* PECULIAR_486 */
+ {
+ EXCEPTION(EX_Underflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ the 80486 book */
+ if ( !(control_word & CW_Underflow) )
+ return 0;
+ }
+ EXCEPTION(precision_loss);
+ if ( !(control_word & CW_Precision) )
+ return 0;
+ }
+ l[0] = tmp.sigl;
+ l[1] = tmp.sigh;
+ }
+ else
+ {
+ if ( tmp.sigl & 0x000007ff )
+ {
+ precision_loss = 1;
+ switch (control_word & CW_RC)
+ {
+ case RC_RND:
+ /* Rounding can get a little messy.. */
+ increment = ((tmp.sigl & 0x7ff) > 0x400) | /* nearest */
+ ((tmp.sigl & 0xc00) == 0xc00); /* odd -> even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment = signpositive(&tmp) ? 0 : tmp.sigl & 0x7ff;
+ break;
+ case RC_UP: /* towards +infinity */
+ increment = signpositive(&tmp) ? tmp.sigl & 0x7ff : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate the mantissa */
+ tmp.sigl &= 0xfffff800;
+
+ if ( increment )
+ {
+ if ( tmp.sigl >= 0xfffff800 )
+ {
+ /* the sigl part overflows */
+ if ( tmp.sigh == 0xffffffff )
+ {
+ /* The sigh part overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if (exp >= EXP_OVER)
+ goto overflow;
+ }
+ else
+ {
+ tmp.sigh ++;
+ }
+ tmp.sigl = 0x00000000;
+ }
+ else
+ {
+ /* We only need to increment sigl */
+ tmp.sigl += 0x00000800;
+ }
+ }
+ }
+ else
+ precision_loss = 0;
+
+ l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
+ l[1] = ((tmp.sigh >> 11) & 0xfffff);
+
+ if ( exp > DOUBLE_Emax )
+ {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ if ( !(control_word & CW_Overflow) )
+ return 0;
+ set_precision_flag_up();
+ if ( !(control_word & CW_Precision) )
+ return 0;
+
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ /* Overflow to infinity */
+ l[0] = 0x00000000; /* Set to */
+ l[1] = 0x7ff00000; /* + INF */
+ }
+ else
+ {
+ if ( precision_loss )
+ {
+ if ( increment )
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
+ /* Add the exponent */
+ l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);
+ }
+ }
+ }
+ else if (st0_tag == TAG_Zero)
+ {
+ /* Number is zero */
+ l[0] = 0;
+ l[1] = 0;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if ( st0_tag == TW_Denormal )
+ {
+ /* A denormal will always underflow. */
+#ifndef PECULIAR_486
+ /* An 80486 is supposed to be able to generate
+ a denormal exception here, but... */
+ /* Underflow has priority. */
+ if ( control_word & CW_Underflow )
+ denormal_operand();
+#endif /* PECULIAR_486 */
+ reg_copy(st0_ptr, &tmp);
+ goto denormal_arg;
+ }
+ else if (st0_tag == TW_Infinity)
+ {
+ l[0] = 0;
+ l[1] = 0x7ff00000;
+ }
+ else if (st0_tag == TW_NaN)
+ {
+ /* Is it really a NaN ? */
+ if ( (exponent(st0_ptr) == EXP_OVER)
+ && (st0_ptr->sigh & 0x80000000) )
+ {
+ /* See if we can get a valid NaN from the FPU_REG */
+ l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21);
+ l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+ if ( !(st0_ptr->sigh & 0x40000000) )
+ {
+ /* It is a signalling NaN */
+ EXCEPTION(EX_Invalid);
+ if ( !(control_word & CW_Invalid) )
+ return 0;
+ l[1] |= (0x40000000 >> 11);
+ }
+ l[1] |= 0x7ff00000;
+ }
+ else
+ {
+ /* It is an unsupported data type */
+ EXCEPTION(EX_Invalid);
+ if ( !(control_word & CW_Invalid) )
+ return 0;
+ l[0] = 0;
+ l[1] = 0xfff80000;
+ }
+ }
+ }
+ else if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if ( control_word & CW_Invalid )
+ {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
+ FPU_put_user(0, (u32 *) dfloat);
+ FPU_put_user(0xfff80000, 1 + (u32 *) dfloat);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ if ( getsign(st0_ptr) )
+ l[1] |= 0x80000000;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,(void *)dfloat,8);
+ FPU_put_user(l[0], (u32 *)dfloat);
+ FPU_put_user(l[1], 1 + (u32 *)dfloat);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+
+/* Put a float into user memory */
+int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
+{
+ s32 templ;
+ u32 increment = 0; /* avoid gcc warnings */
+ int precision_loss;
+ int exp;
+ FPU_REG tmp;
+
+ if ( st0_tag == TAG_Valid )
+ {
+
+ reg_copy(st0_ptr, &tmp);
+ exp = exponent(&tmp);
+
+ if ( exp < SINGLE_Emin )
+ {
+ addexponent(&tmp, -SINGLE_Emin + 23); /* largest exp to be 22 */
+
+ denormal_arg:
+
+ if ( (precision_loss = FPU_round_to_int(&tmp, st0_tag)) )
+ {
+#ifdef PECULIAR_486
+ /* Did it round to a non-denormal ? */
+ /* This behaviour might be regarded as peculiar, it appears
+ that the 80486 rounds to the dest precision, then
+ converts to decide underflow. */
+ if ( !((tmp.sigl == 0x00800000) &&
+ ((st0_ptr->sigh & 0x000000ff) || st0_ptr->sigl)) )
+#endif /* PECULIAR_486 */
+ {
+ EXCEPTION(EX_Underflow);
+ /* This is a special case: see sec 16.2.5.1 of
+ the 80486 book */
+ if ( !(control_word & CW_Underflow) )
+ return 0;
+ }
+ EXCEPTION(precision_loss);
+ if ( !(control_word & CW_Precision) )
+ return 0;
+ }
+ templ = tmp.sigl;
+ }
+ else
+ {
+ if ( tmp.sigl | (tmp.sigh & 0x000000ff) )
+ {
+ u32 sigh = tmp.sigh;
+ u32 sigl = tmp.sigl;
+
+ precision_loss = 1;
+ switch (control_word & CW_RC)
+ {
+ case RC_RND:
+ increment = ((sigh & 0xff) > 0x80) /* more than half */
+ || (((sigh & 0xff) == 0x80) && sigl) /* more than half */
+ || ((sigh & 0x180) == 0x180); /* round to even */
+ break;
+ case RC_DOWN: /* towards -infinity */
+ increment = signpositive(&tmp)
+ ? 0 : (sigl | (sigh & 0xff));
+ break;
+ case RC_UP: /* towards +infinity */
+ increment = signpositive(&tmp)
+ ? (sigl | (sigh & 0xff)) : 0;
+ break;
+ case RC_CHOP:
+ increment = 0;
+ break;
+ }
+
+ /* Truncate part of the mantissa */
+ tmp.sigl = 0;
+
+ if (increment)
+ {
+ if ( sigh >= 0xffffff00 )
+ {
+ /* The sigh part overflows */
+ tmp.sigh = 0x80000000;
+ exp++;
+ if ( exp >= EXP_OVER )
+ goto overflow;
+ }
+ else
+ {
+ tmp.sigh &= 0xffffff00;
+ tmp.sigh += 0x100;
+ }
+ }
+ else
+ {
+ tmp.sigh &= 0xffffff00; /* Finish the truncation */
+ }
+ }
+ else
+ precision_loss = 0;
+
+ templ = (tmp.sigh >> 8) & 0x007fffff;
+
+ if ( exp > SINGLE_Emax )
+ {
+ overflow:
+ EXCEPTION(EX_Overflow);
+ if ( !(control_word & CW_Overflow) )
+ return 0;
+ set_precision_flag_up();
+ if ( !(control_word & CW_Precision) )
+ return 0;
+
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book. */
+ /* Masked response is overflow to infinity. */
+ templ = 0x7f800000;
+ }
+ else
+ {
+ if ( precision_loss )
+ {
+ if ( increment )
+ set_precision_flag_up();
+ else
+ set_precision_flag_down();
+ }
+ /* Add the exponent */
+ templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
+ }
+ }
+ }
+ else if (st0_tag == TAG_Zero)
+ {
+ templ = 0;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if (st0_tag == TW_Denormal)
+ {
+ reg_copy(st0_ptr, &tmp);
+
+ /* A denormal will always underflow. */
+#ifndef PECULIAR_486
+ /* An 80486 is supposed to be able to generate
+ a denormal exception here, but... */
+ /* Underflow has priority. */
+ if ( control_word & CW_Underflow )
+ denormal_operand();
+#endif /* PECULIAR_486 */
+ goto denormal_arg;
+ }
+ else if (st0_tag == TW_Infinity)
+ {
+ templ = 0x7f800000;
+ }
+ else if (st0_tag == TW_NaN)
+ {
+ /* Is it really a NaN ? */
+ if ( (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000) )
+ {
+ /* See if we can get a valid NaN from the FPU_REG */
+ templ = st0_ptr->sigh >> 8;
+ if ( !(st0_ptr->sigh & 0x40000000) )
+ {
+ /* It is a signalling NaN */
+ EXCEPTION(EX_Invalid);
+ if ( !(control_word & CW_Invalid) )
+ return 0;
+ templ |= (0x40000000 >> 8);
+ }
+ templ |= 0x7f800000;
+ }
+ else
+ {
+ /* It is an unsupported data type */
+ EXCEPTION(EX_Invalid);
+ if ( !(control_word & CW_Invalid) )
+ return 0;
+ templ = 0xffc00000;
+ }
+ }
+#ifdef PARANOID
+ else
+ {
+ EXCEPTION(EX_INTERNAL|0x164);
+ return 0;
+ }
+#endif
+ }
+ else if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ if ( control_word & EX_Invalid )
+ {
+ /* The masked response */
+ /* Put out the QNaN indefinite */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,(void *)single,4);
+ FPU_put_user(0xffc00000, (u32 *) single);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ }
+ else
+ return 0;
+ }
+#ifdef PARANOID
+ else
+ {
+ EXCEPTION(EX_INTERNAL|0x163);
+ return 0;
+ }
+#endif
+ if ( getsign(st0_ptr) )
+ templ |= 0x80000000;
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,(void *)single,4);
+ FPU_put_user(templ,(u32 *) single);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+
+/* Put a 64bit quantity into user memory */
+int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, s64 *d)
+{
+ FPU_REG t;
+ s64 tll;
+ int precision_loss;
+
+ if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if ( (st0_tag == TW_Infinity) ||
+ (st0_tag == TW_NaN) )
+ {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
+ }
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+#ifndef EMU_BIG_ENDIAN
+ ((u32 *)&tll)[0] = t.sigl;
+ ((u32 *)&tll)[1] = t.sigh;
+#else
+ ((u32 *)&tll)[0] = t.sigh;
+ ((u32 *)&tll)[1] = t.sigl;
+#endif
+ if ( (precision_loss == 1) ||
+ ((t.sigh & 0x80000000) &&
+ !((t.sigh == 0x80000000) && (t.sigl == 0) &&
+ signnegative(&t))) )
+ {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if ( control_word & EX_Invalid )
+ {
+ /* Produce something like QNaN "indefinite" */
+ tll = BX_CONST64(0x8000000000000000);
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ if ( precision_loss )
+ set_precision_flag(precision_loss);
+ if ( signnegative(&t) )
+ tll = - tll;
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,(void *)d,8);
+#ifndef USE_WITH_CPU_SIM
+ copy_to_user(d, &tll, 8);
+#else
+ FPU_put_user((u32) tll, (u32*)(((u8 *)d)+0));
+ FPU_put_user((u32) (tll>>32), (u32*)(((u8 *)d)+4));
+#endif
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+
+/* Put a long into user memory */
+int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, s32 *d)
+{
+ FPU_REG t;
+ int precision_loss;
+
+ if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if ( (st0_tag == TW_Infinity) ||
+ (st0_tag == TW_NaN) )
+ {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
+ }
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ if (t.sigh ||
+ ((t.sigl & 0x80000000) &&
+ !((t.sigl == 0x80000000) && signnegative(&t))) )
+ {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if ( control_word & EX_Invalid )
+ {
+ /* Produce something like QNaN "indefinite" */
+ t.sigl = 0x80000000;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ if ( precision_loss )
+ set_precision_flag(precision_loss);
+ if ( signnegative(&t) )
+ t.sigl = -(s32)t.sigl;
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,4);
+ FPU_put_user(t.sigl, (u32 *) d);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+
+/* Put a short into user memory */
+int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, s16 *d)
+{
+ FPU_REG t;
+ int precision_loss;
+
+ if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if ( (st0_tag == TW_Infinity) ||
+ (st0_tag == TW_NaN) )
+ {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
+ }
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ if (t.sigh ||
+ ((t.sigl & 0xffff8000) &&
+ !((t.sigl == 0x8000) && signnegative(&t))) )
+ {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if ( control_word & EX_Invalid )
+ {
+ /* Produce something like QNaN "indefinite" */
+ t.sigl = 0x8000;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ if ( precision_loss )
+ set_precision_flag(precision_loss);
+ if ( signnegative(&t) )
+ t.sigl = -t.sigl;
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,2);
+ FPU_put_user((s16)t.sigl,(s16 *) d);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+
+/* Put a packed bcd array into user memory */
+int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char *d)
+{
+ FPU_REG t;
+ u64 ll;
+ u_char b;
+ int i, precision_loss;
+ u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;
+
+ if ( st0_tag == TAG_Empty )
+ {
+ /* Empty register (stack underflow) */
+ EXCEPTION(EX_StackUnder);
+ goto invalid_operand;
+ }
+ else if ( st0_tag == TAG_Special )
+ {
+ st0_tag = FPU_Special(st0_ptr);
+ if ( (st0_tag == TW_Infinity) ||
+ (st0_tag == TW_NaN) )
+ {
+ EXCEPTION(EX_Invalid);
+ goto invalid_operand;
+ }
+ }
+
+ reg_copy(st0_ptr, &t);
+ precision_loss = FPU_round_to_int(&t, st0_tag);
+ ll = significand(&t);
+
+ /* Check for overflow, by comparing with 999999999999999999 decimal. */
+ if ( (t.sigh > 0x0de0b6b3) ||
+ ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff)) )
+ {
+ EXCEPTION(EX_Invalid);
+ /* This is a special case: see sec 16.2.5.1 of the 80486 book */
+ invalid_operand:
+ if ( control_word & CW_Invalid )
+ {
+ /* Produce the QNaN "indefinite" */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,10);
+ for ( i = 0; i < 7; i++)
+ FPU_put_user(0, (u_char *) d+i); /* These bytes "undefined" */
+ FPU_put_user(0xc0, (u_char *) d+7); /* This byte "undefined" */
+ FPU_put_user(0xff, (u_char *) d+8);
+ FPU_put_user(0xff, (u_char *) d+9);
+ RE_ENTRANT_CHECK_ON;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ else if ( precision_loss )
+ {
+ /* Precision loss doesn't stop the data transfer */
+ set_precision_flag(precision_loss);
+ }
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,10);
+ RE_ENTRANT_CHECK_ON;
+ for ( i = 0; i < 9; i++)
+ {
+ b = FPU_div_small(&ll, 10);
+ b |= (FPU_div_small(&ll, 10)) << 4;
+ RE_ENTRANT_CHECK_OFF;
+ FPU_put_user(b,(u_char *) d+i);
+ RE_ENTRANT_CHECK_ON;
+ }
+ RE_ENTRANT_CHECK_OFF;
+ FPU_put_user(sign,(u_char *) d+9);
+ RE_ENTRANT_CHECK_ON;
+
+ return 1;
+}
+
+/*===========================================================================*/
+
+/* r gets mangled such that sig is int, sign:
+ it is NOT normalized */
+/* The return value (in eax) is zero if the result is exact,
+ if bits are changed due to rounding, truncation, etc, then
+ a non-zero value is returned */
+/* Overflow is signalled by a non-zero return value (in eax).
+ In the case of overflow, the returned significand always has the
+ largest possible value */
+int FPU_round_to_int(FPU_REG *r, u_char tag)
+{
+ u_char very_big;
+ unsigned eax;
+
+ if (tag == TAG_Zero)
+ {
+ /* Make sure that zero is returned */
+ significand(r) = 0;
+ return 0; /* o.k. */
+ }
+
+ if (exponent(r) > 63)
+ {
+ r->sigl = r->sigh = ~0; /* The largest representable number */
+ return 1; /* overflow */
+ }
+
+#ifndef EMU_BIG_ENDIAN
+ eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
+#else
+ eax = FPU_shrxs(&r->sigh, 63 - exponent(r));
+#endif
+ very_big = !(~(r->sigh) | ~(r->sigl)); /* test for 0xfff...fff */
+#define half_or_more (eax & 0x80000000)
+#define frac_part (eax)
+#define more_than_half ((eax & 0x80000001) == 0x80000001)
+ switch (control_word & CW_RC)
+ {
+ case RC_RND:
+ if ( more_than_half /* nearest */
+ || (half_or_more && (r->sigl & 1)) ) /* odd -> even */
+ {
+ if ( very_big ) return 1; /* overflow */
+ significand(r) ++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_DOWN:
+ if (frac_part && getsign(r))
+ {
+ if ( very_big ) return 1; /* overflow */
+ significand(r) ++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_UP:
+ if (frac_part && !getsign(r))
+ {
+ if ( very_big ) return 1; /* overflow */
+ significand(r) ++;
+ return PRECISION_LOST_UP;
+ }
+ break;
+ case RC_CHOP:
+ break;
+ }
+
+ return eax ? PRECISION_LOST_DOWN : 0;
+
+}
+
+/*===========================================================================*/
+
+u_char *fldenv(fpu_addr_modes addr_modes, u_char *s)
+{
+ u16 tag_word = 0;
+ u_char tag;
+ int i;
+
+ if ( (addr_modes.default_mode == VM86) ||
+ ((addr_modes.default_mode == PM16)
+ ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
+ {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, s, 0x0e);
+ FPU_get_user(control_word, (u16 *) s);
+ FPU_get_user(partial_status, (u16 *) (s+2));
+ FPU_get_user(tag_word, (u16 *) (s+4));
+ FPU_get_user(instruction_address.offset, (u16 *) (s+6));
+ FPU_get_user(instruction_address.selector, (u16 *) (s+8));
+ FPU_get_user(operand_address.offset, (u16 *) (s+0x0a));
+ FPU_get_user(operand_address.selector, (u16 *) (s+0x0c));
+ RE_ENTRANT_CHECK_ON;
+ s += 0x0e;
+ if ( addr_modes.default_mode == VM86 )
+ {
+ instruction_address.offset
+ += (instruction_address.selector & 0xf000) << 4;
+ operand_address.offset += (operand_address.selector & 0xf000) << 4;
+ }
+ }
+ else
+ {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ, s, 0x1c);
+ FPU_get_user(control_word, (u16 *) s);
+ FPU_get_user(partial_status, (u16 *) (s+4));
+ FPU_get_user(tag_word, (u16 *) (s+8));
+ FPU_get_user(instruction_address.offset, (u32 *) (s+0x0c));
+ FPU_get_user(instruction_address.selector, (u16 *) (s+0x10));
+ FPU_get_user(instruction_address.opcode, (u16 *) (s+0x12));
+ FPU_get_user(operand_address.offset, (u32 *) (s+0x14));
+ FPU_get_user(operand_address.selector, (u32 *) (s+0x18));
+ RE_ENTRANT_CHECK_ON;
+ s += 0x1c;
+ }
+
+#ifdef PECULIAR_486
+ control_word &= ~0xe080;
+#endif /* PECULIAR_486 */
+
+ top = (partial_status >> SW_Top_Shift) & 7;
+
+ if ( partial_status & ~control_word & CW_Exceptions )
+ partial_status |= (SW_Summary | SW_Backward);
+ else
+ partial_status &= ~(SW_Summary | SW_Backward);
+
+ for ( i = 0; i < 8; i++ )
+ {
+ tag = tag_word & 3;
+ tag_word >>= 2;
+
+ if ( tag == TAG_Empty )
+ /* New tag is empty. Accept it */
+ FPU_settag(i, TAG_Empty);
+ else if ( FPU_gettag(i) == TAG_Empty )
+ {
+ /* Old tag is empty and new tag is not empty. New tag is determined
+ by old reg contents */
+ if ( exponent(&fpu_register(i)) == - EXTENDED_Ebias )
+ {
+ if ( !(fpu_register(i).sigl | fpu_register(i).sigh) )
+ FPU_settag(i, TAG_Zero);
+ else
+ FPU_settag(i, TAG_Special);
+ }
+ else if ( exponent(&fpu_register(i)) == 0x7fff - EXTENDED_Ebias )
+ {
+ FPU_settag(i, TAG_Special);
+ }
+ else if ( fpu_register(i).sigh & 0x80000000 )
+ FPU_settag(i, TAG_Valid);
+ else
+ FPU_settag(i, TAG_Special); /* An Un-normal */
+ }
+ /* Else old tag is not empty and new tag is not empty. Old tag
+ remains correct */
+ }
+
+ return s;
+}
+
+
+void frstor(fpu_addr_modes addr_modes, u_char *data_address)
+{
+ int i, regnr;
+ u_char *s = fldenv(addr_modes, data_address);
+ int offset = (top & 7) * sizeof(FPU_REG), other = 8*sizeof(FPU_REG) - offset;
+
+ /* Copy all registers in stack order. */
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_READ,s,80);
+#ifndef USE_WITH_CPU_SIM
+ __copy_from_user(register_base+offset, s, other);
+ if ( offset )
+ __copy_from_user(register_base, s+other, offset);
+#else
+ {
+ FPU_REG *fpu_reg_p;
+
+ fpu_reg_p = (FPU_REG *) (register_base+offset);
+ while (other>0) {
+ FPU_get_user(fpu_reg_p->sigl, (u32*)(s+0));
+ FPU_get_user(fpu_reg_p->sigh, (u32*)(s+4));
+ FPU_get_user(fpu_reg_p->exp, (u16*)(s+8));
+ fpu_reg_p++;
+ s += 10;
+ other -= sizeof(FPU_REG);
+ }
+ fpu_reg_p = (FPU_REG *) register_base;
+ while (offset>0) {
+ FPU_get_user(fpu_reg_p->sigl, (u32*)(s+0));
+ FPU_get_user(fpu_reg_p->sigh, (u32*)(s+4));
+ FPU_get_user(fpu_reg_p->exp, (u16*)(s+8));
+ fpu_reg_p++;
+ s += 10;
+ offset -= sizeof(FPU_REG);
+ }
+ }
+#endif
+ RE_ENTRANT_CHECK_ON;
+
+ for ( i = 0; i < 8; i++ )
+ {
+ regnr = (i+top) & 7;
+ if ( FPU_gettag(regnr) != TAG_Empty )
+ /* The loaded data over-rides all other cases. */
+ FPU_settag(regnr, FPU_tagof(&st(i)));
+ }
+
+}
+
+
+u_char *fstenv(fpu_addr_modes addr_modes, u_char *d)
+{
+ if ( (addr_modes.default_mode == VM86) ||
+ ((addr_modes.default_mode == PM16)
+ ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX)) )
+ {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,14);
+#ifdef PECULIAR_486
+ FPU_put_user(control_word & ~0xe080, (u32 *) d);
+#else
+ FPU_put_user(control_word, (u16 *) d);
+#endif /* PECULIAR_486 */
+ FPU_put_user(status_word(), (u16 *) (d+2));
+ FPU_put_user(fpu_tag_word, (u16 *) (d+4));
+ FPU_put_user(instruction_address.offset, (u16 *) (d+6));
+ FPU_put_user(operand_address.offset, (u16 *) (d+0x0a));
+ if ( addr_modes.default_mode == VM86 )
+ {
+ FPU_put_user((instruction_address.offset & 0xf0000) >> 4,
+ (u16 *) (d+8));
+ FPU_put_user((operand_address.offset & 0xf0000) >> 4,
+ (u16 *) (d+0x0c));
+ }
+ else
+ {
+ FPU_put_user(instruction_address.selector, (u16 *) (d+8));
+ FPU_put_user(operand_address.selector, (u16 *) (d+0x0c));
+ }
+ RE_ENTRANT_CHECK_ON;
+ d += 0x0e;
+ }
+ else
+ {
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE, d, 7*4);
+#ifdef PECULIAR_486
+ control_word &= ~0xe080;
+ /* An 80486 sets nearly all of the reserved bits to 1. */
+ control_word |= 0xffff0040;
+ partial_status = status_word() | 0xffff0000;
+ fpu_tag_word |= 0xffff0000;
+ I387.soft.fcs &= ~0xf8000000;
+ I387.soft.fos |= 0xffff0000;
+#endif /* PECULIAR_486 */
+#ifndef USE_WITH_CPU_SIM
+ __copy_to_user(d, &control_word, 7*4);
+#else
+ FPU_put_user((u32) I387.soft.cwd, (u32*)(((u8 *)d)+0));
+ FPU_put_user((u32) I387.soft.swd, (u32*)(((u8 *)d)+4));
+ FPU_put_user((u32) I387.soft.twd, (u32*)(((u8 *)d)+8));
+ FPU_put_user((u32) I387.soft.fip, (u32*)(((u8 *)d)+12));
+ FPU_put_user((u32) I387.soft.fcs, (u32*)(((u8 *)d)+16));
+ FPU_put_user((u32) I387.soft.foo, (u32*)(((u8 *)d)+20));
+ FPU_put_user((u32) I387.soft.fos, (u32*)(((u8 *)d)+24));
+#endif
+ RE_ENTRANT_CHECK_ON;
+ d += 0x1c;
+ }
+
+ control_word |= CW_Exceptions;
+ partial_status &= ~(SW_Summary | SW_Backward);
+
+ return d;
+}
+
+
+void fsave(fpu_addr_modes addr_modes, u_char *data_address)
+{
+ u_char *d;
+ int offset = (top & 7) * sizeof(FPU_REG), other = 8*sizeof(FPU_REG) - offset;
+
+ d = fstenv(addr_modes, data_address);
+
+ RE_ENTRANT_CHECK_OFF;
+ FPU_verify_area(VERIFY_WRITE,d,80);
+
+ /* Copy all registers in stack order. */
+#ifndef USE_WITH_CPU_SIM
+ __copy_to_user(d, register_base+offset, other);
+ if ( offset )
+ __copy_to_user(d+other, register_base, offset);
+#else
+ {
+ FPU_REG *fpu_reg_p;
+
+ fpu_reg_p = (FPU_REG *) (register_base+offset);
+ while (other>0) {
+ FPU_put_user(fpu_reg_p->sigl, (u32*)(d+0));
+ FPU_put_user(fpu_reg_p->sigh, (u32*)(d+4));
+ FPU_put_user(fpu_reg_p->exp, (u16*)(d+8));
+ fpu_reg_p++;
+ d += 10;
+ other -= sizeof(FPU_REG);
+ }
+ fpu_reg_p = (FPU_REG *) register_base;
+ while (offset>0) {
+ FPU_put_user(fpu_reg_p->sigl, (u32*)(d+0));
+ FPU_put_user(fpu_reg_p->sigh, (u32*)(d+4));
+ FPU_put_user(fpu_reg_p->exp, (u16*)(d+8));
+ fpu_reg_p++;
+ d += 10;
+ offset -= sizeof(FPU_REG);
+ }
+ }
+#endif
+ RE_ENTRANT_CHECK_ON;
+
+ finit();
+}
+
+/*===========================================================================*/
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_mul.c |
+ | |
+ | Multiply one FPU_REG by another, put the result in a destination FPU_REG. |
+ | |
+ | Copyright (C) 1992,1993,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | Returns the tag of the result if no exceptions or errors occurred. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "reg_constant.h"
+#include "fpu_system.h"
+
+
+/*
+ Multiply two registers to give a register result.
+ The sources are st(deststnr) and (b,tagb,signb).
+ The destination is st(deststnr).
+ */
+/* This routine must be called with non-empty source registers */
+int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w)
+{
+ FPU_REG *a = &st(deststnr);
+ FPU_REG *dest = a;
+ u_char taga = FPU_gettagi(deststnr);
+ u_char saved_sign = getsign(dest);
+ u_char sign = (getsign(a) ^ getsign(b));
+ int tag;
+
+
+ if ( !(taga | tagb) )
+ {
+ /* Both regs Valid, this should be the most common case. */
+
+ tag = FPU_u_mul(a, b, dest, control_w, sign, exponent(a) + exponent(b));
+ if ( tag < 0 )
+ {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+
+ if ( taga == TAG_Special )
+ taga = FPU_Special(a);
+ if ( tagb == TAG_Special )
+ tagb = FPU_Special(b);
+
+ if ( ((taga == TAG_Valid) && (tagb == TW_Denormal))
+ || ((taga == TW_Denormal) && (tagb == TAG_Valid))
+ || ((taga == TW_Denormal) && (tagb == TW_Denormal)) )
+ {
+ FPU_REG x, y;
+ if ( denormal_operand() < 0 )
+ return FPU_Exception;
+
+ FPU_to_exp16(a, &x);
+ FPU_to_exp16(b, &y);
+ tag = FPU_u_mul(&x, &y, dest, control_w, sign,
+ exponent16(&x) + exponent16(&y));
+ if ( tag < 0 )
+ {
+ setsign(dest, saved_sign);
+ return tag;
+ }
+ FPU_settagi(deststnr, tag);
+ return tag;
+ }
+ else if ( (taga <= TW_Denormal) && (tagb <= TW_Denormal) )
+ {
+ if ( ((tagb == TW_Denormal) || (taga == TW_Denormal))
+ && (denormal_operand() < 0) )
+ return FPU_Exception;
+
+ /* Must have either both arguments == zero, or
+ one valid and the other zero.
+ The result is therefore zero. */
+ FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+ /* The 80486 book says that the answer is +0, but a real
+ 80486 behaves this way.
+ IEEE-754 apparently says it should be this way. */
+ setsign(dest, sign);
+ return TAG_Zero;
+ }
+ /* Must have infinities, NaNs, etc */
+ else if ( (taga == TW_NaN) || (tagb == TW_NaN) )
+ {
+ return real_2op_NaN(b, tagb, deststnr, &st(0));
+ }
+ else if ( ((taga == TW_Infinity) && (tagb == TAG_Zero))
+ || ((tagb == TW_Infinity) && (taga == TAG_Zero)) )
+ {
+ return arith_invalid(deststnr); /* Zero*Infinity is invalid */
+ }
+ else if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
+ && (denormal_operand() < 0) )
+ {
+ return FPU_Exception;
+ }
+ else if (taga == TW_Infinity)
+ {
+ FPU_copy_to_regi(a, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return TAG_Special;
+ }
+ else if (tagb == TW_Infinity)
+ {
+ FPU_copy_to_regi(b, TAG_Special, deststnr);
+ setsign(dest, sign);
+ return TAG_Special;
+ }
+
+#ifdef PARANOID
+ else
+ {
+ EXCEPTION(EX_INTERNAL|0x102);
+ return FPU_Exception;
+ }
+#endif /* PARANOID */
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_norm.S |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Normalize the value in a FPU_REG. |
+ | |
+ | Call from C as: |
+ | int FPU_normalize_nuo(FPU_REG *n, int bias) |
+ | |
+ | Return value is the tag of the answer. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+
+/* Normalise without reporting underflow or overflow */
+ENTRY(FPU_normalize_nuo)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx
+
+ movl PARAM1,%ebx
+
+ movl SIGH(%ebx),%edx
+ movl SIGL(%ebx),%eax
+
+ orl %edx,%edx /* ms bits */
+ js L_exit_nuo_valid /* Already normalized */
+ jnz L_nuo_shift_1 /* Shift left 1 - 31 bits */
+
+ orl %eax,%eax
+ jz L_exit_nuo_zero /* The contents are zero */
+
+ movl %eax,%edx
+ xorl %eax,%eax
+ subw $32,EXP(%ebx) /* This can cause an underflow */
+
+/* We need to shift left by 1 - 31 bits */
+L_nuo_shift_1:
+ bsrl %edx,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%eax,%edx
+ shl %cl,%eax
+ subw %cx,EXP(%ebx) /* This can cause an underflow */
+
+ movl %edx,SIGH(%ebx)
+ movl %eax,SIGL(%ebx)
+
+L_exit_nuo_valid:
+ movl PARAM2,%eax
+ addw %ax,EXP(%ebx)
+ movl TAG_Valid,%eax
+
+ popl %ebx
+ leave
+ ret
+
+L_exit_nuo_zero:
+ movw EXP_UNDER,EXP(%ebx)
+ movl PARAM2,%eax
+ addw %ax,EXP(%ebx)
+ movl TAG_Zero,%eax
+
+ popl %ebx
+ leave
+ ret
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_norm.c |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Normalize the value in a FPU_REG. |
+ | |
+ | |
+ | Return value is the tag of the answer. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+
+
+int FPU_normalize_nuo(FPU_REG *x, int bias)
+{
+
+ if ( ! (x->sigh & 0x80000000) )
+ {
+ if ( x->sigh == 0 )
+ {
+ if ( x->sigl == 0 )
+ {
+ x->exp = EXP_UNDER;
+ return TAG_Zero;
+ }
+ x->sigh = x->sigl;
+ x->sigl = 0;
+ x->exp -= 32;
+ }
+ while ( !(x->sigh & 0x80000000) )
+ {
+ x->sigh <<= 1;
+ if ( x->sigl & 0x80000000 )
+ x->sigh |= 1;
+ x->sigl <<= 1;
+ x->exp --;
+ }
+ }
+
+ x->exp += bias;
+
+ return TAG_Valid;
+}
--- /dev/null
+ .file "reg_round.S"
+/*---------------------------------------------------------------------------+
+ | reg_round.S |
+ | |
+ | Rounding/truncation/etc for FPU basic arithmetic functions. |
+ | |
+ | Copyright (C) 1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | This code has four possible entry points. |
+ | The following must be entered by a jmp instruction: |
+ | fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit. |
+ | |
+ | The FPU_round entry point is intended to be used by C code. |
+ | From C, call as: |
+ | int FPU_round(FPU_REG *arg, unsigned int extent, unsigned int control_w) |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ | For correct "up" and "down" rounding, the argument must have the correct |
+ | sign. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Four entry points. |
+ | |
+ | Needed by both the fpu_reg_round and fpu_reg_round_sqrt entry points: |
+ | %eax:%ebx 64 bit significand |
+ | %edx 32 bit extension of the significand |
+ | %edi pointer to an FPU_REG for the result to be stored |
+ | stack calling function must have set up a C stack frame and |
+ | pushed %esi, %edi, and %ebx |
+ | |
+ | Needed just for the fpu_reg_round_sqrt entry point: |
+ | %cx A control word in the same format as the FPU control word. |
+ | Otherwise, PARAM4 must give such a value. |
+ | |
+ | |
+ | The significand and its extension are assumed to be exact in the |
+ | following sense: |
+ | If the significand by itself is the exact result then the significand |
+ | extension (%edx) must contain 0, otherwise the significand extension |
+ | must be non-zero. |
+ | If the significand extension is non-zero then the significand is |
+ | smaller than the magnitude of the correct exact result by an amount |
+ | greater than zero and less than one ls bit of the significand. |
+ | The significand extension is only required to have three possible |
+ | non-zero values: |
+ | less than 0x80000000 <=> the significand is less than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | exactly 0x80000000 <=> the significand is exactly 1/2 an ls bit |
+ | smaller than the magnitude of the true |
+ | exact result. |
+ | greater than 0x80000000 <=> the significand is more than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The code in this module has become quite complex, but it should handle |
+ | all of the FPU flags which are set at this stage of the basic arithmetic |
+ | computations. |
+ | There are a few rare cases where the results are not set identically to |
+ | a real FPU. These require a bit more thought because at this stage the |
+ | results of the code here appear to be more consistent... |
+ | This may be changed in a future version. |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+
+/* Flags for FPU_bits_lost */
+#define LOST_DOWN $1
+#define LOST_UP $2
+
+/* Flags for FPU_denormal */
+#define DENORMAL $1
+#define UNMASKED_UNDERFLOW $2
+
+
+#ifndef NON_REENTRANT_FPU
+/* Make the code re-entrant by putting
+ local storage on the stack: */
+#define FPU_bits_lost (%esp)
+#define FPU_denormal 1(%esp)
+
+#else
+/* Not re-entrant, so we can gain speed by putting
+ local storage in a static area: */
+.data
+ .align 4,0
+FPU_bits_lost:
+ .byte 0
+FPU_denormal:
+ .byte 0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+.globl fpu_reg_round
+.globl fpu_reg_round_sqrt
+.globl fpu_Arith_exit
+
+/* Entry point when called from C */
+ENTRY(FPU_round)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%edi
+ movl SIGH(%edi),%eax
+ movl SIGL(%edi),%ebx
+ movl PARAM2,%edx
+
+fpu_reg_round: /* Normal entry point */
+ movl PARAM4,%ecx
+
+#ifndef NON_REENTRANT_FPU
+ pushl %ebx /* adjust the stack pointer */
+#endif /* NON_REENTRANT_FPU */
+
+#ifdef PARANOID
+/* Cannot use this here yet */
+/* orl %eax,%eax */
+/* jns L_entry_bugged */
+#endif /* PARANOID */
+
+ cmpw EXP_UNDER,EXP(%edi)
+ jle L_Make_denorm /* The number is a de-normal */
+
+ movb $0,FPU_denormal /* 0 -> not a de-normal */
+
+Denorm_done:
+ movb $0,FPU_bits_lost /* No bits yet lost in rounding */
+
+ movl %ecx,%esi
+ andl CW_PC,%ecx
+ cmpl PR_64_BITS,%ecx
+ je LRound_To_64
+
+ cmpl PR_53_BITS,%ecx
+ je LRound_To_53
+
+ cmpl PR_24_BITS,%ecx
+ je LRound_To_24
+
+#ifdef PECULIAR_486
+/* With the precision control bits set to 01 "(reserved)", a real 80486
+ behaves as if the precision control bits were set to 11 "64 bits" */
+ cmpl PR_RESERVED_BITS,%ecx
+ je LRound_To_64
+#ifdef PARANOID
+ jmp L_bugged_denorm_486
+#endif /* PARANOID */
+#else
+#ifdef PARANOID
+ jmp L_bugged_denorm /* There is no bug, just a bad control word */
+#endif /* PARANOID */
+#endif /* PECULIAR_486 */
+
+
+/* Round etc to 24 bit precision */
+LRound_To_24:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_24
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_24
+
+ cmpl RC_UP,%ecx /* Towards +infinity */
+ je LUp_24
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity */
+ je LDown_24
+
+#ifdef PARANOID
+ jmp L_bugged_round24
+#endif /* PARANOID */
+
+LUp_24:
+ cmpb SIGN_POS,PARAM5
+ jne LCheck_truncate_24 /* If negative then up==truncate */
+
+ jmp LCheck_24_round_up
+
+LDown_24:
+ cmpb SIGN_POS,PARAM5
+ je LCheck_truncate_24 /* If positive then down==truncate */
+
+LCheck_24_round_up:
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ orl %ebx,%ecx
+ orl %edx,%ecx
+ jnz LDo_24_round_up
+ jmp L_Re_normalise
+
+LRound_nearest_24:
+ /* Do rounding of the 24th bit if needed (nearest or even) */
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ cmpl $0x00000080,%ecx
+ jc LCheck_truncate_24 /* less than half, no increment needed */
+
+ jne LGreater_Half_24 /* greater than half, increment needed */
+
+ /* Possibly half, we need to check the ls bits */
+ orl %ebx,%ebx
+ jnz LGreater_Half_24 /* greater than half, increment needed */
+
+ orl %edx,%edx
+ jnz LGreater_Half_24 /* greater than half, increment needed */
+
+ /* Exactly half, increment only if 24th bit is 1 (round to even) */
+ testl $0x00000100,%eax
+ jz LDo_truncate_24
+
+LGreater_Half_24: /* Rounding: increment at the 24th bit */
+LDo_24_round_up:
+ andl $0xffffff00,%eax /* Truncate to 24 bits */
+ xorl %ebx,%ebx
+ movb LOST_UP,FPU_bits_lost
+ addl $0x00000100,%eax
+ jmp LCheck_Round_Overflow
+
+LCheck_truncate_24:
+ movl %eax,%ecx
+ andl $0x000000ff,%ecx
+ orl %ebx,%ecx
+ orl %edx,%ecx
+ jz L_Re_normalise /* No truncation needed */
+
+LDo_truncate_24:
+ andl $0xffffff00,%eax /* Truncate to 24 bits */
+ xorl %ebx,%ebx
+ movb LOST_DOWN,FPU_bits_lost
+ jmp L_Re_normalise
+
+
+/* Round etc to 53 bit precision */
+LRound_To_53:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_53
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_53
+
+ cmpl RC_UP,%ecx /* Towards +infinity */
+ je LUp_53
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity */
+ je LDown_53
+
+#ifdef PARANOID
+ jmp L_bugged_round53
+#endif /* PARANOID */
+
+LUp_53:
+ cmpb SIGN_POS,PARAM5
+ jne LCheck_truncate_53 /* If negative then up==truncate */
+
+ jmp LCheck_53_round_up
+
+LDown_53:
+ cmpb SIGN_POS,PARAM5
+ je LCheck_truncate_53 /* If positive then down==truncate */
+
+LCheck_53_round_up:
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ orl %edx,%ecx
+ jnz LDo_53_round_up
+ jmp L_Re_normalise
+
+LRound_nearest_53:
+ /* Do rounding of the 53rd bit if needed (nearest or even) */
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ cmpl $0x00000400,%ecx
+ jc LCheck_truncate_53 /* less than half, no increment needed */
+
+ jnz LGreater_Half_53 /* greater than half, increment needed */
+
+ /* Possibly half, we need to check the ls bits */
+ orl %edx,%edx
+ jnz LGreater_Half_53 /* greater than half, increment needed */
+
+ /* Exactly half, increment only if 53rd bit is 1 (round to even) */
+ testl $0x00000800,%ebx
+ jz LTruncate_53
+
+LGreater_Half_53: /* Rounding: increment at the 53rd bit */
+LDo_53_round_up:
+ movb LOST_UP,FPU_bits_lost
+ andl $0xfffff800,%ebx /* Truncate to 53 bits */
+ addl $0x00000800,%ebx
+ adcl $0,%eax
+ jmp LCheck_Round_Overflow
+
+LCheck_truncate_53:
+ movl %ebx,%ecx
+ andl $0x000007ff,%ecx
+ orl %edx,%ecx
+ jz L_Re_normalise
+
+LTruncate_53:
+ movb LOST_DOWN,FPU_bits_lost
+ andl $0xfffff800,%ebx /* Truncate to 53 bits */
+ jmp L_Re_normalise
+
+
+/* Round etc to 64 bit precision */
+LRound_To_64:
+ movl %esi,%ecx
+ andl CW_RC,%ecx
+ cmpl RC_RND,%ecx
+ je LRound_nearest_64
+
+ cmpl RC_CHOP,%ecx
+ je LCheck_truncate_64
+
+ cmpl RC_UP,%ecx /* Towards +infinity */
+ je LUp_64
+
+ cmpl RC_DOWN,%ecx /* Towards -infinity */
+ je LDown_64
+
+#ifdef PARANOID
+ jmp L_bugged_round64
+#endif /* PARANOID */
+
+LUp_64:
+ cmpb SIGN_POS,PARAM5
+ jne LCheck_truncate_64 /* If negative then up==truncate */
+
+ orl %edx,%edx
+ jnz LDo_64_round_up
+ jmp L_Re_normalise
+
+LDown_64:
+ cmpb SIGN_POS,PARAM5
+ je LCheck_truncate_64 /* If positive then down==truncate */
+
+ orl %edx,%edx
+ jnz LDo_64_round_up
+ jmp L_Re_normalise
+
+LRound_nearest_64:
+ cmpl $0x80000000,%edx
+ jc LCheck_truncate_64
+
+ jne LDo_64_round_up
+
+ /* Now test for round-to-even */
+ testb $1,%bl
+ jz LCheck_truncate_64
+
+LDo_64_round_up:
+ movb LOST_UP,FPU_bits_lost
+ addl $1,%ebx
+ adcl $0,%eax
+
+LCheck_Round_Overflow:
+ jnc L_Re_normalise
+
+ /* Overflow, adjust the result (significand to 1.0) */
+ rcrl $1,%eax
+ rcrl $1,%ebx
+ incw EXP(%edi)
+ jmp L_Re_normalise
+
+LCheck_truncate_64:
+ orl %edx,%edx
+ jz L_Re_normalise
+
+LTruncate_64:
+ movb LOST_DOWN,FPU_bits_lost
+
+L_Re_normalise:
+ testb $0xff,FPU_denormal
+ jnz Normalise_result
+
+L_Normalised:
+ movl TAG_Valid,%edx
+
+L_deNormalised:
+ cmpb LOST_UP,FPU_bits_lost
+ je L_precision_lost_up
+
+ cmpb LOST_DOWN,FPU_bits_lost
+ je L_precision_lost_down
+
+L_no_precision_loss:
+ /* store the result */
+
+L_Store_significand:
+ movl %eax,SIGH(%edi)
+ movl %ebx,SIGL(%edi)
+
+ cmpw EXP_OVER,EXP(%edi)
+ jge L_overflow
+
+ movl %edx,%eax
+
+ /* Convert the exponent to 80x87 form. */
+ addw EXTENDED_Ebias,EXP(%edi)
+ andw $0x7fff,EXP(%edi)
+
+fpu_reg_round_signed_special_exit:
+
+ cmpb SIGN_POS,PARAM5
+ je fpu_reg_round_special_exit
+
+ orw $0x8000,EXP(%edi) /* Negative sign for the result. */
+
+fpu_reg_round_special_exit:
+
+#ifndef NON_REENTRANT_FPU
+ popl %ebx /* adjust the stack pointer */
+#endif /* NON_REENTRANT_FPU */
+
+fpu_Arith_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+
+
+/*
+ * Set the FPU status flags to represent precision loss due to
+ * round-up.
+ */
+L_precision_lost_up:
+ push %edx
+ push %eax
+ call SYMBOL_NAME(set_precision_flag_up)
+ popl %eax
+ popl %edx
+ jmp L_no_precision_loss
+
+/*
+ * Set the FPU status flags to represent precision loss due to
+ * truncation.
+ */
+L_precision_lost_down:
+ push %edx
+ push %eax
+ call SYMBOL_NAME(set_precision_flag_down)
+ popl %eax
+ popl %edx
+ jmp L_no_precision_loss
+
+
+/*
+ * The number is a denormal (which might get rounded up to a normal)
+ * Shift the number right the required number of bits, which will
+ * have to be undone later...
+ */
+L_Make_denorm:
+ /* The action to be taken depends upon whether the underflow
+ exception is masked */
+ testb CW_Underflow,%cl /* Underflow mask. */
+ jz Unmasked_underflow /* Do not make a denormal. */
+
+ movb DENORMAL,FPU_denormal
+
+ pushl %ecx /* Save */
+ movw EXP_UNDER+1,%cx
+ subw EXP(%edi),%cx
+
+ cmpw $64,%cx /* shrd only works for 0..31 bits */
+ jnc Denorm_shift_more_than_63
+
+ cmpw $32,%cx /* shrd only works for 0..31 bits */
+ jnc Denorm_shift_more_than_32
+
+/*
+ * We got here without jumps by assuming that the most common requirement
+ * is for a small de-normalising shift.
+ * Shift by [1..31] bits
+ */
+ addw %cx,EXP(%edi)
+ orl %edx,%edx /* extension */
+ setne %ch /* Save whether %edx is non-zero */
+ xorl %edx,%edx
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orb %ch,%dl
+ popl %ecx
+ jmp Denorm_done
+
+/* Shift by [32..63] bits */
+Denorm_shift_more_than_32:
+ addw %cx,EXP(%edi)
+ subb $32,%cl
+ orl %edx,%edx
+ setne %ch
+ orb %ch,%bl
+ xorl %edx,%edx
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orl %edx,%edx /* test these 32 bits */
+ setne %cl
+ orb %ch,%bl
+ orb %cl,%bl
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ popl %ecx
+ jmp Denorm_done
+
+/* Shift by [64..) bits */
+Denorm_shift_more_than_63:
+ cmpw $64,%cx
+ jne Denorm_shift_more_than_64
+
+/* Exactly 64 bit shift */
+ addw %cx,EXP(%edi)
+ xorl %ecx,%ecx
+ orl %edx,%edx
+ setne %cl
+ orl %ebx,%ebx
+ setne %ch
+ orb %ch,%cl
+ orb %cl,%al
+ movl %eax,%edx
+ xorl %eax,%eax
+ xorl %ebx,%ebx
+ popl %ecx
+ jmp Denorm_done
+
+Denorm_shift_more_than_64:
+ movw EXP_UNDER+1,EXP(%edi)
+/* This is easy, %eax must be non-zero, so.. */
+ movl $1,%edx
+ xorl %eax,%eax
+ xorl %ebx,%ebx
+ popl %ecx
+ jmp Denorm_done
+
+
+Unmasked_underflow:
+ movb UNMASKED_UNDERFLOW,FPU_denormal
+ jmp Denorm_done
+
+
+/* Undo the de-normalisation. */
+Normalise_result:
+ cmpb UNMASKED_UNDERFLOW,FPU_denormal
+ je Signal_underflow
+
+/* The number must be a denormal if we got here. */
+#ifdef PARANOID
+ /* But check it... just in case. */
+ cmpw EXP_UNDER+1,EXP(%edi)
+ jne L_norm_bugged
+#endif /* PARANOID */
+
+#ifdef PECULIAR_486
+ /*
+ * This implements a special feature of 80486 behaviour.
+ * Underflow will be signalled even if the number is
+ * not a denormal after rounding.
+ * This difference occurs only for masked underflow, and not
+ * in the unmasked case.
+ * Actual 80486 behaviour differs from this in some circumstances.
+ */
+ orl %eax,%eax /* ms bits */
+ js LPseudoDenormal /* Will be masked underflow */
+#else
+ orl %eax,%eax /* ms bits */
+ js L_Normalised /* No longer a denormal */
+#endif /* PECULIAR_486 */
+
+ jnz LDenormal_adj_exponent
+
+ orl %ebx,%ebx
+ jz L_underflow_to_zero /* The contents are zero */
+
+LDenormal_adj_exponent:
+ decw EXP(%edi)
+
+LPseudoDenormal:
+ testb $0xff,FPU_bits_lost /* bits lost == underflow */
+ movl TAG_Special,%edx
+ jz L_deNormalised
+
+ /* There must be a masked underflow */
+ push %eax
+ pushl EX_Underflow
+ call EXCEPTION
+ popl %eax
+ popl %eax
+ movl TAG_Special,%edx
+ jmp L_deNormalised
+
+
+/*
+ * The operations resulted in a number too small to represent.
+ * Masked response.
+ */
+L_underflow_to_zero:
+ push %eax
+ call SYMBOL_NAME(set_precision_flag_down)
+ popl %eax
+
+ push %eax
+ pushl EX_Underflow
+ call EXCEPTION
+ popl %eax
+ popl %eax
+
+/* Reduce the exponent to EXP_UNDER */
+ movw EXP_UNDER,EXP(%edi)
+ movl TAG_Zero,%edx
+ jmp L_Store_significand
+
+
+/* The operations resulted in a number too large to represent. */
+L_overflow:
+ pushw PARAM5
+ addw EXTENDED_Ebias,EXP(%edi) /* Set for unmasked response. */
+ push %edi
+ call SYMBOL_NAME(arith_round_overflow)
+ pop %edi
+ jmp fpu_reg_round_signed_special_exit
+
+
+Signal_underflow:
+ /* The number may have been changed to a non-denormal */
+ /* by the rounding operations. */
+ cmpw EXP_UNDER,EXP(%edi)
+ jle Do_unmasked_underflow
+
+ jmp L_Normalised
+
+Do_unmasked_underflow:
+ /* Increase the exponent by the magic number */
+ addw $(3*(1<<13)),EXP(%edi)
+ push %eax
+ pushl EX_Underflow
+ call EXCEPTION
+ popl %eax
+ popl %eax
+ jmp L_Normalised
+
+
+#ifdef PARANOID
+#ifdef PECULIAR_486
+L_bugged_denorm_486:
+ pushl EX_INTERNAL|0x236
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+#else
+L_bugged_denorm:
+ pushl EX_INTERNAL|0x230
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+#endif /* PECULIAR_486 */
+
+L_bugged_round24:
+ pushl EX_INTERNAL|0x231
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+
+L_bugged_round53:
+ pushl EX_INTERNAL|0x232
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+
+L_bugged_round64:
+ pushl EX_INTERNAL|0x233
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+
+L_norm_bugged:
+ pushl EX_INTERNAL|0x234
+ call EXCEPTION
+ popl %ebx
+ jmp L_exception_exit
+
+L_entry_bugged:
+ pushl EX_INTERNAL|0x235
+ call EXCEPTION
+ popl %ebx
+L_exception_exit:
+ mov $-1,%eax
+ jmp fpu_reg_round_special_exit
+#endif /* PARANOID */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_round.c |
+ | |
+ | Rounding/truncation/etc for FPU basic arithmetic functions. |
+ | |
+ | Copyright (C) 1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | This code has four possible entry points. |
+ | The following must be entered by a jmp instruction: |
+ | fpu_reg_round, fpu_reg_round_sqrt, and fpu_Arith_exit. |
+ | |
+ | The FPU_round entry point is intended to be used by C code. |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ | For correct "up" and "down" rounding, the argument must have the correct |
+ | sign. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | |
+ | The significand and its extension are assumed to be exact in the |
+ | following sense: |
+ | If the significand by itself is the exact result then the significand |
+ | extension (%edx) must contain 0, otherwise the significand extension |
+ | must be non-zero. |
+ | If the significand extension is non-zero then the significand is |
+ | smaller than the magnitude of the correct exact result by an amount |
+ | greater than zero and less than one ls bit of the significand. |
+ | The significand extension is only required to have three possible |
+ | non-zero values: |
+ | less than 0x80000000 <=> the significand is less than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | exactly 0x80000000 <=> the significand is exactly 1/2 an ls bit |
+ | smaller than the magnitude of the true |
+ | exact result. |
+ | greater than 0x80000000 <=> the significand is more than 1/2 an ls |
+ | bit smaller than the magnitude of the |
+ | true exact result. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | The code in this module has become quite complex, but it should handle |
+ | all of the FPU flags which are set at this stage of the basic arithmetic |
+ | computations. |
+ | There are a few rare cases where the results are not set identically to |
+ | a real FPU. These require a bit more thought because at this stage the |
+ | results of the code here appear to be more consistent... |
+ | This may be changed in a future version. |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+#include "exception.h"
+#include "control_w.h"
+
+/* Flags for FPU_bits_lost */
+#define LOST_DOWN 1
+#define LOST_UP 2
+
+/* Flags for FPU_denormal */
+#define DENORMAL 1
+#define UNMASKED_UNDERFLOW 2
+
+
+int round_up_64(FPU_REG *x, u32 extent)
+{
+ x->sigl ++;
+ if ( x->sigl == 0 )
+ {
+ x->sigh ++;
+ if ( x->sigh == 0 )
+ {
+ x->sigh = 0x80000000;
+ x->exp ++;
+ }
+ }
+ return LOST_UP;
+}
+
+
+int truncate_64(FPU_REG *x, u32 extent)
+{
+ return LOST_DOWN;
+}
+
+
+int round_up_53(FPU_REG *x, u32 extent)
+{
+ x->sigl &= 0xfffff800;
+ x->sigl += 0x800;
+ if ( x->sigl == 0 )
+ {
+ x->sigh ++;
+ if ( x->sigh == 0 )
+ {
+ x->sigh = 0x80000000;
+ x->exp ++;
+ }
+ }
+ return LOST_UP;
+}
+
+
+int truncate_53(FPU_REG *x, u32 extent)
+{
+ x->sigl &= 0xfffff800;
+ return LOST_DOWN;
+}
+
+
+int round_up_24(FPU_REG *x, u32 extent)
+{
+ x->sigl = 0;
+ x->sigh &= 0xffffff00;
+ x->sigh += 0x100;
+ if ( x->sigh == 0 )
+ {
+ x->sigh = 0x80000000;
+ x->exp ++;
+ }
+ return LOST_UP;
+}
+
+
+int truncate_24(FPU_REG *x, u32 extent)
+{
+ x->sigl = 0;
+ x->sigh &= 0xffffff00;
+ return LOST_DOWN;
+}
+
+
+int FPU_round(FPU_REG *x, u32 extent, int dummy, u16 control_w, u8 sign)
+{
+ u64 work;
+ u32 leading;
+ s16 expon = x->exp;
+ int FPU_bits_lost = 0, FPU_denormal, shift, tag;
+
+ if ( expon <= EXP_UNDER )
+ {
+ /* A denormal or zero */
+ if ( control_w & CW_Underflow )
+ {
+ /* Underflow is masked. */
+ FPU_denormal = DENORMAL;
+ shift = EXP_UNDER+1 - expon;
+ if ( shift >= 64 )
+ {
+ if ( shift == 64 )
+ {
+ x->exp += 64;
+ if ( extent | x->sigl )
+ extent = x->sigh | 1;
+ else
+ extent = x->sigh;
+ }
+ else
+ {
+ x->exp = EXP_UNDER+1;
+ extent = 1;
+ }
+ significand(x) = 0;
+ }
+ else
+ {
+ x->exp += shift;
+ if ( shift >= 32 )
+ {
+ shift -= 32;
+ if ( shift )
+ {
+ extent |= x->sigl;
+ work = significand(x) >> shift;
+ if ( extent )
+ extent = work | 1;
+ else
+ extent = work;
+ x->sigl = x->sigh >>= shift;
+ }
+ else
+ {
+ if ( extent )
+ extent = x->sigl | 1;
+ else
+ extent = x->sigl;
+ x->sigl = x->sigh;
+ }
+ x->sigh = 0;
+ }
+ else
+ {
+ /* Shift by 1 to 32 places. */
+ work = x->sigl;
+ work <<= 32;
+ work |= extent;
+ work >>= shift;
+ if ( extent )
+ extent = 1;
+ extent |= work;
+ significand(x) >>= shift;
+ }
+ }
+ }
+ else
+ {
+ /* Unmasked underflow. */
+ FPU_denormal = UNMASKED_UNDERFLOW;
+ }
+ }
+ else
+ FPU_denormal = 0;
+
+ switch ( control_w & CW_PC )
+ {
+ case 01:
+#ifndef PECULIAR_486
+ /* With the precision control bits set to 01 "(reserved)", a real 80486
+ behaves as if the precision control bits were set to 11 "64 bits" */
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL|0x236);
+ return -1;
+#endif
+#endif
+ /* Fall through to the 64 bit case. */
+ case PR_64_BITS:
+ if ( extent )
+ {
+ switch ( control_w & CW_RC )
+ {
+ case RC_RND: /* Nearest or even */
+ /* See if there is exactly half a ulp. */
+ if ( extent == 0x80000000 )
+ {
+ /* Round to even. */
+ if ( x->sigl & 0x1 )
+ /* Odd */
+ FPU_bits_lost = round_up_64(x, extent);
+ else
+ /* Even */
+ FPU_bits_lost = truncate_64(x, extent);
+ }
+ else if ( extent > 0x80000000 )
+ {
+ /* Greater than half */
+ FPU_bits_lost = round_up_64(x, extent);
+ }
+ else
+ {
+ /* Less than half */
+ FPU_bits_lost = truncate_64(x, extent);
+ }
+ break;
+
+ case RC_CHOP: /* Truncate */
+ FPU_bits_lost = truncate_64(x, extent);
+ break;
+
+ case RC_UP: /* Towards +infinity */
+ if ( sign == SIGN_POS)
+ {
+ FPU_bits_lost = round_up_64(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_64(x, extent);
+ }
+ break;
+
+ case RC_DOWN: /* Towards -infinity */
+ if ( sign != SIGN_POS)
+ {
+ FPU_bits_lost = round_up_64(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_64(x, extent);
+ }
+ break;
+
+ default:
+ EXCEPTION(EX_INTERNAL|0x231);
+ return -1;
+ }
+ }
+ break;
+
+ case PR_53_BITS:
+ leading = x->sigl & 0x7ff;
+ if ( extent || leading )
+ {
+ switch ( control_w & CW_RC )
+ {
+ case RC_RND: /* Nearest or even */
+ /* See if there is exactly half a ulp. */
+ if ( leading == 0x400 )
+ {
+ if ( extent == 0 )
+ {
+ /* Round to even. */
+ if ( x->sigl & 0x800 )
+ /* Odd */
+ FPU_bits_lost = round_up_53(x, extent);
+ else
+ /* Even */
+ FPU_bits_lost = truncate_53(x, extent);
+ }
+ else
+ {
+ /* Greater than half */
+ FPU_bits_lost = round_up_53(x, extent);
+ }
+ }
+ else if ( leading > 0x400 )
+ {
+ /* Greater than half */
+ FPU_bits_lost = round_up_53(x, extent);
+ }
+ else
+ {
+ /* Less than half */
+ FPU_bits_lost = truncate_53(x, extent);
+ }
+ break;
+
+ case RC_CHOP: /* Truncate */
+ FPU_bits_lost = truncate_53(x, extent);
+ break;
+
+ case RC_UP: /* Towards +infinity */
+ if ( sign == SIGN_POS)
+ {
+ FPU_bits_lost = round_up_53(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_53(x, extent);
+ }
+ break;
+
+ case RC_DOWN: /* Towards -infinity */
+ if ( sign != SIGN_POS)
+ {
+ FPU_bits_lost = round_up_53(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_53(x, extent);
+ }
+ break;
+
+ default:
+ EXCEPTION(EX_INTERNAL|0x231);
+ return -1;
+ }
+ }
+ break;
+
+ case PR_24_BITS:
+ leading = x->sigh & 0xff;
+ if ( leading || x->sigl || extent )
+ {
+ switch ( control_w & CW_RC )
+ {
+ case RC_RND: /* Nearest or even */
+ /* See if there is exactly half a ulp. */
+ if ( leading == 0x80 )
+ {
+ if ( (x->sigl == 0) && (extent == 0) )
+ {
+ /* Round to even. */
+ if ( x->sigh & 0x100 )
+ /* Odd */
+ FPU_bits_lost = round_up_24(x, extent);
+ else
+ /* Even */
+ FPU_bits_lost = truncate_24(x, extent);
+ }
+ else
+ {
+ /* Greater than half */
+ FPU_bits_lost = round_up_24(x, extent);
+ }
+ }
+ else if ( leading > 0x80 )
+ {
+ /* Greater than half */
+ FPU_bits_lost = round_up_24(x, extent);
+ }
+ else
+ {
+ /* Less than half */
+ FPU_bits_lost = truncate_24(x, extent);
+ }
+ break;
+
+ case RC_CHOP: /* Truncate */
+ FPU_bits_lost = truncate_24(x, extent);
+ break;
+
+ case RC_UP: /* Towards +infinity */
+ if ( sign == SIGN_POS)
+ {
+ FPU_bits_lost = round_up_24(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_24(x, extent);
+ }
+ break;
+
+ case RC_DOWN: /* Towards -infinity */
+ if ( sign != SIGN_POS)
+ {
+ FPU_bits_lost = round_up_24(x, extent);
+ }
+ else
+ {
+ FPU_bits_lost = truncate_24(x, extent);
+ }
+ break;
+
+ default:
+ EXCEPTION(EX_INTERNAL|0x231);
+ return -1;
+ }
+ }
+ break;
+
+ default:
+#ifdef PARANOID
+ EXCEPTION(EX_INTERNAL|0x230);
+ return -1;
+#endif
+ break;
+ }
+
+ tag = TAG_Valid;
+
+ if ( FPU_denormal )
+ {
+ /* Undo the de-normalisation. */
+ if ( FPU_denormal == UNMASKED_UNDERFLOW )
+ {
+ if ( x->exp <= EXP_UNDER )
+ {
+ /* Increase the exponent by the magic number */
+ x->exp += 3 * (1 << 13);
+ EXCEPTION(EX_Underflow);
+ }
+ }
+ else
+ {
+ if ( x->exp != EXP_UNDER+1 )
+ {
+ EXCEPTION(EX_INTERNAL|0x234);
+ }
+ if ( (x->sigh == 0) && (x->sigl == 0) )
+ {
+ /* Underflow to zero */
+ set_precision_flag_down();
+ EXCEPTION(EX_Underflow);
+ x->exp = EXP_UNDER;
+ tag = TAG_Zero;
+ FPU_bits_lost = 0; /* Stop another call to
+ set_precision_flag_down() */
+ }
+ else
+ {
+ if ( x->sigh & 0x80000000 )
+ {
+#ifdef PECULIAR_486
+ /*
+ * This implements a special feature of 80486 behaviour.
+ * Underflow will be signalled even if the number is
+ * not a denormal after rounding.
+ * This difference occurs only for masked underflow, and not
+ * in the unmasked case.
+ * Actual 80486 behaviour differs from this in some circumstances.
+ */
+ /* Will be masked underflow */
+#else
+ /* No longer a denormal */
+#endif
+ }
+ else
+#ifndef PECULIAR_486
+ {
+#endif
+ x->exp --;
+
+ if ( FPU_bits_lost )
+ {
+ /* There must be a masked underflow */
+ EXCEPTION(EX_Underflow);
+ }
+
+ tag = TAG_Special;
+#ifndef PECULIAR_486
+ }
+#endif
+ }
+ }
+ }
+
+
+ if ( FPU_bits_lost == LOST_UP )
+ set_precision_flag_up();
+ else if ( FPU_bits_lost == LOST_DOWN )
+ set_precision_flag_down();
+
+ if ( x->exp >= EXP_OVER )
+ {
+ x->exp += EXTENDED_Ebias;
+ tag = arith_round_overflow(x, sign);
+ }
+ else
+ {
+ x->exp += EXTENDED_Ebias;
+ x->exp &= 0x7fff;
+ }
+
+ if ( sign != SIGN_POS )
+ x->exp |= 0x8000;
+
+ return tag;
+
+}
+
+
+
--- /dev/null
+ .file "reg_u_add.S"
+/*---------------------------------------------------------------------------+
+ | reg_u_add.S |
+ | |
+ | Add two valid (TAG_Valid) FPU_REG numbers, of the same sign, and put the |
+ | result in a destination FPU_REG. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | Call from C as: |
+ | int FPU_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, |
+ | int control_w) |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*
+ | Kernel addition routine FPU_u_add(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TAG_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their sum as a TAG_Valid or TAG_Special f.p. number.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+.text
+ENTRY(FPU_u_add)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* source 1 */
+ movl PARAM2,%edi /* source 2 */
+
+ movl PARAM6,%ecx
+ movl %ecx,%edx
+ subl PARAM7,%ecx /* exp1 - exp2 */
+ jge L_arg1_larger
+
+ /* num1 is smaller */
+ movl SIGL(%esi),%ebx
+ movl SIGH(%esi),%eax
+
+ movl %edi,%esi
+ movl PARAM7,%edx
+ negw %cx
+ jmp L_accum_loaded
+
+L_arg1_larger:
+ /* num1 has larger or equal exponent */
+ movl SIGL(%edi),%ebx
+ movl SIGH(%edi),%eax
+
+L_accum_loaded:
+ movl PARAM3,%edi /* destination */
+ movw %dx,EXP(%edi) /* Copy exponent to destination */
+
+ xorl %edx,%edx /* clear the extension */
+
+#ifdef PARANOID
+ testl $0x80000000,%eax
+ je L_bugged
+
+ testl $0x80000000,SIGH(%esi)
+ je L_bugged
+#endif /* PARANOID */
+
+/* The number to be shifted is in %eax:%ebx:%edx */
+ cmpw $32,%cx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ jmp L_shift_done
+
+L_more_than_31:
+ cmpw $64,%cx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ jz L_exactly_32
+
+ shrd %cl,%eax,%edx
+ shr %cl,%eax
+ orl %ebx,%ebx
+ jz L_more_31_no_low /* none of the lowest bits is set */
+
+ orl $1,%edx /* record the fact in the extension */
+
+L_more_31_no_low:
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_exactly_32:
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_more_than_63:
+ cmpw $65,%cx
+ jnc L_more_than_64
+
+ movl %eax,%edx
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_64:
+ movl $1,%edx /* The shifted nr always at least one '1' */
+
+L_more_63_no_low:
+ xorl %ebx,%ebx
+ xorl %eax,%eax
+
+L_shift_done:
+ /* Now do the addition */
+ addl SIGL(%esi),%ebx
+ adcl SIGH(%esi),%eax
+ jnc L_round_the_result
+
+ /* Overflow, adjust the result */
+ rcrl $1,%eax
+ rcrl $1,%ebx
+ rcrl $1,%edx
+ jnc L_no_bit_lost
+
+ orl $1,%edx
+
+L_no_bit_lost:
+ incw EXP(%edi)
+
+L_round_the_result:
+ jmp fpu_reg_round /* Round the result */
+
+
+
+#ifdef PARANOID
+/* If we ever get here then we have problems! */
+L_bugged:
+ pushl EX_INTERNAL|0x201
+ call EXCEPTION
+ pop %ebx
+ movl $-1,%eax
+ jmp L_exit
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+#endif /* PARANOID */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_u_add.c |
+ | |
+ | Add two valid (TAG_Valid) FPU_REG numbers, of the same sign, and put the |
+ | result in a destination FPU_REG. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*
+ | Kernel addition routine FPU_u_add(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TAG_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their sum as a TAG_Valid or TAG_Special f.p. number.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+int FPU_u_add(const FPU_REG *arg1, const FPU_REG *arg2, FPU_REG *answ,
+ u16 control_w, u_char sign, s32 expa, s32 expb)
+{
+ const FPU_REG *rtmp;
+ FPU_REG shifted;
+ u32 extent = 0;
+ int ediff = expa - expb, ed2, eflag, ovfl, carry;
+
+ if ( ediff < 0 )
+ {
+ ediff = -ediff;
+ rtmp = arg1;
+ arg1 = arg2;
+ arg2 = rtmp;
+ expa = expb;
+ }
+
+ /* Now we have exponent of arg1 >= exponent of arg2 */
+
+ answ->exp = expa;
+
+#ifdef PARANOID
+ if ( !(arg1->sigh & 0x80000000) || !(arg2->sigh & 0x80000000) )
+ {
+ EXCEPTION(EX_INTERNAL|0x201);
+ return -1;
+ }
+#endif
+
+ if ( ediff == 0 )
+ {
+ extent = 0;
+ shifted.sigl = arg2->sigl;
+ shifted.sigh = arg2->sigh;
+ }
+ else if ( ediff < 32 )
+ {
+ ed2 = 32 - ediff;
+ extent = arg2->sigl << ed2;
+ shifted.sigl = arg2->sigl >> ediff;
+ shifted.sigl |= (arg2->sigh << ed2);
+ shifted.sigh = arg2->sigh >> ediff;
+ }
+ else if ( ediff < 64 )
+ {
+ ediff -= 32;
+ if ( ! ediff )
+ {
+ eflag = 0;
+ extent = arg2->sigl;
+ shifted.sigl = arg2->sigh;
+ }
+ else
+ {
+ ed2 = 32 - ediff;
+ eflag = arg2->sigl;
+ if ( eflag )
+ extent |= 1;
+ extent = arg2->sigl >> ediff;
+ extent |= (arg2->sigh << ed2);
+ shifted.sigl = arg2->sigh >> ediff;
+ }
+ shifted.sigh = 0;
+ }
+ else
+ {
+ ediff -= 64;
+ if ( ! ediff )
+ {
+ eflag = arg2->sigl;
+ extent = arg2->sigh;
+ }
+ else
+ {
+ ed2 = 64 - ediff;
+ eflag = arg2->sigl | arg2->sigh;
+ extent = arg2->sigh >> ediff;
+ }
+ shifted.sigl = 0;
+ shifted.sigh = 0;
+ if ( eflag )
+ extent |= 1;
+ }
+
+ answ->sigh = arg1->sigh + shifted.sigh;
+ ovfl = shifted.sigh > answ->sigh;
+ answ->sigl = arg1->sigl + shifted.sigl;
+ if ( shifted.sigl > answ->sigl )
+ {
+ answ->sigh ++;
+ if ( answ->sigh == 0 )
+ ovfl = 1;
+ }
+ if ( ovfl )
+ {
+ carry = extent & 1;
+ extent >>= 1;
+ extent |= carry;
+ if ( answ->sigl & 1 )
+ extent |= 0x80000000;
+ answ->sigl >>= 1;
+ if ( answ->sigh & 1 )
+ answ->sigl |= 0x80000000;
+ answ->sigh >>= 1;
+ answ->sigh |= 0x80000000;
+ answ->exp ++;
+ }
+
+ return FPU_round(answ, extent, 0, control_w, sign);
+
+}
--- /dev/null
+ .file "reg_u_div.S"
+/*---------------------------------------------------------------------------+
+ | reg_u_div.S |
+ | |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ | |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Call from C as: |
+ | int FPU_u_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest, |
+ | unsigned int control_word, char *sign) |
+ | |
+ | Does not compute the destination exponent, but does adjust it. |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+/* #define dSIGL(x) (x) */
+/* #define dSIGH(x) 4(x) */
+
+
+#ifndef NON_REENTRANT_FPU
+/*
+ Local storage on the stack:
+ Result: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ Overflow flag: ovfl_flag
+ */
+#define FPU_accum_3 -4(%ebp)
+#define FPU_accum_2 -8(%ebp)
+#define FPU_accum_1 -12(%ebp)
+#define FPU_accum_0 -16(%ebp)
+#define FPU_result_1 -20(%ebp)
+#define FPU_result_2 -24(%ebp)
+#define FPU_ovfl_flag -28(%ebp)
+
+#else
+.data
+/*
+ Local storage in a static area:
+ Result: FPU_accum_3:FPU_accum_2:FPU_accum_1:FPU_accum_0
+ Overflow flag: ovfl_flag
+ */
+ .align 4,0
+FPU_accum_3:
+ .long 0
+FPU_accum_2:
+ .long 0
+FPU_accum_1:
+ .long 0
+FPU_accum_0:
+ .long 0
+FPU_result_1:
+ .long 0
+FPU_result_2:
+ .long 0
+FPU_ovfl_flag:
+ .byte 0
+#endif /* NON_REENTRANT_FPU */
+
+#define REGA PARAM1
+#define REGB PARAM2
+#define DEST PARAM3
+
+.text
+ENTRY(FPU_u_div)
+ pushl %ebp
+ movl %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+ subl $28,%esp
+#endif /* NON_REENTRANT_FPU */
+
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl REGA,%esi
+ movl REGB,%ebx
+ movl DEST,%edi
+
+ movw EXP(%esi),%dx
+ movw EXP(%ebx),%ax
+ .byte 0x0f,0xbf,0xc0 /* movsx %ax,%eax */
+ .byte 0x0f,0xbf,0xd2 /* movsx %dx,%edx */
+ subl %eax,%edx
+ addl EXP_BIAS,%edx
+
+ /* A denormal and a large number can cause an exponent underflow */
+ cmpl EXP_WAY_UNDER,%edx
+ jg xExp_not_underflow
+
+ /* Set to a really low value allow correct handling */
+ movl EXP_WAY_UNDER,%edx
+
+xExp_not_underflow:
+
+ movw %dx,EXP(%edi)
+
+#ifdef PARANOID
+/* testl $0x80000000, SIGH(%esi) // Dividend */
+/* je L_bugged */
+ testl $0x80000000, SIGH(%ebx) /* Divisor */
+ je L_bugged
+#endif /* PARANOID */
+
+/* Check if the divisor can be treated as having just 32 bits */
+ cmpl $0,SIGL(%ebx)
+ jnz L_Full_Division /* Can't do a quick divide */
+
+/* We should be able to zip through the division here */
+ movl SIGH(%ebx),%ecx /* The divisor */
+ movl SIGH(%esi),%edx /* Dividend */
+ movl SIGL(%esi),%eax /* Dividend */
+
+ cmpl %ecx,%edx
+ setaeb FPU_ovfl_flag /* Keep a record */
+ jb L_no_adjust
+
+ subl %ecx,%edx /* Prevent the overflow */
+
+L_no_adjust:
+ /* Divide the 64 bit number by the 32 bit denominator */
+ divl %ecx
+ movl %eax,FPU_result_2
+
+ /* Work on the remainder of the first division */
+ xorl %eax,%eax
+ divl %ecx
+ movl %eax,FPU_result_1
+
+ /* Work on the remainder of the 64 bit division */
+ xorl %eax,%eax
+ divl %ecx
+
+ testb $255,FPU_ovfl_flag /* was the num > denom ? */
+ je L_no_overflow
+
+ /* Do the shifting here */
+ /* increase the exponent */
+ incw EXP(%edi)
+
+ /* shift the mantissa right one bit */
+ stc /* To set the ms bit */
+ rcrl FPU_result_2
+ rcrl FPU_result_1
+ rcrl %eax
+
+L_no_overflow:
+ jmp LRound_precision /* Do the rounding as required */
+
+
+/*---------------------------------------------------------------------------+
+ | Divide: Return arg1/arg2 to arg3. |
+ | |
+ | This routine does not use the exponents of arg1 and arg2, but does |
+ | adjust the exponent of arg3. |
+ | |
+ | The maximum returned value is (ignoring exponents) |
+ | .ffffffff ffffffff |
+ | ------------------ = 1.ffffffff fffffffe |
+ | .80000000 00000000 |
+ | and the minimum is |
+ | .80000000 00000000 |
+ | ------------------ = .80000000 00000001 (rounded) |
+ | .ffffffff ffffffff |
+ | |
+ +---------------------------------------------------------------------------*/
+
+
+L_Full_Division:
+ /* Save extended dividend in local register */
+ movl SIGL(%esi),%eax
+ movl %eax,FPU_accum_2
+ movl SIGH(%esi),%eax
+ movl %eax,FPU_accum_3
+ xorl %eax,%eax
+ movl %eax,FPU_accum_1 /* zero the extension */
+ movl %eax,FPU_accum_0 /* zero the extension */
+
+ movl SIGL(%esi),%eax /* Get the current num */
+ movl SIGH(%esi),%edx
+
+/*----------------------------------------------------------------------*/
+/* Initialization done.
+ Do the first 32 bits. */
+
+ movb $0,FPU_ovfl_flag
+ cmpl SIGH(%ebx),%edx /* Test for imminent overflow */
+ jb LLess_than_1
+ ja LGreater_than_1
+
+ cmpl SIGL(%ebx),%eax
+ jb LLess_than_1
+
+LGreater_than_1:
+/* The dividend is greater or equal, would cause overflow */
+ setaeb FPU_ovfl_flag /* Keep a record */
+
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx /* Prevent the overflow */
+ movl %eax,FPU_accum_2
+ movl %edx,FPU_accum_3
+
+LLess_than_1:
+/* At this point, we have a dividend < divisor, with a record of
+ adjustment in FPU_ovfl_flag */
+
+ /* We will divide by a number which is too large */
+ movl SIGH(%ebx),%ecx
+ addl $1,%ecx
+ jnc LFirst_div_not_1
+
+ /* here we need to divide by 100000000h,
+ i.e., no division at all.. */
+ mov %edx,%eax
+ jmp LFirst_div_done
+
+LFirst_div_not_1:
+ divl %ecx /* Divide the numerator by the augmented
+ denom ms dw */
+
+LFirst_div_done:
+ movl %eax,FPU_result_2 /* Put the result in the answer */
+
+ mull SIGH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,FPU_accum_2 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_3
+
+ movl FPU_result_2,%eax /* Get the result back */
+ mull SIGL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+ sbbl $0,FPU_accum_3
+ je LDo_2nd_32_bits /* Must check for non-zero result here */
+
+#ifdef PARANOID
+ jb L_bugged_1
+#endif /* PARANOID */
+
+ /* need to subtract another once of the denom */
+ incl FPU_result_2 /* Correct the answer */
+
+ movl SIGL(%ebx),%eax
+ movl SIGH(%ebx),%edx
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+
+#ifdef PARANOID
+ sbbl $0,FPU_accum_3
+ jne L_bugged_1 /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* Half of the main problem is done, there is just a reduced numerator
+ to handle now.
+ Work with the second 32 bits, FPU_accum_0 not used from now on */
+LDo_2nd_32_bits:
+ movl FPU_accum_2,%edx /* get the reduced num */
+ movl FPU_accum_1,%eax
+
+ /* need to check for possible subsequent overflow */
+ cmpl SIGH(%ebx),%edx
+ jb LDo_2nd_div
+ ja LPrevent_2nd_overflow
+
+ cmpl SIGL(%ebx),%eax
+ jb LDo_2nd_div
+
+LPrevent_2nd_overflow:
+/* The numerator is greater or equal, would cause overflow */
+ /* prevent overflow */
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx
+ movl %edx,FPU_accum_2
+ movl %eax,FPU_accum_1
+
+ incl FPU_result_2 /* Reflect the subtraction in the answer */
+
+#ifdef PARANOID
+ je L_bugged_2 /* Can't bump the result to 1.0 */
+#endif /* PARANOID */
+
+LDo_2nd_div:
+ cmpl $0,%ecx /* augmented denom msw */
+ jnz LSecond_div_not_1
+
+ /* %ecx == 0, we are dividing by 1.0 */
+ mov %edx,%eax
+ jmp LSecond_div_done
+
+LSecond_div_not_1:
+ divl %ecx /* Divide the numerator by the denom ms dw */
+
+LSecond_div_done:
+ movl %eax,FPU_result_1 /* Put the result in the answer */
+
+ mull SIGH(%ebx) /* mul by the ms dw of the denom */
+
+ subl %eax,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif /* PARANOID */
+
+ movl FPU_result_1,%eax /* Get the result back */
+ mull SIGL(%ebx) /* now mul the ls dw of the denom */
+
+ subl %eax,FPU_accum_0 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_1 /* Subtract from the num local reg */
+ sbbl $0,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+#endif /* PARANOID */
+
+ jz LDo_3rd_32_bits
+
+#ifdef PARANOID
+ cmpl $1,FPU_accum_2
+ jne L_bugged_2
+#endif /* PARANOID */
+
+ /* need to subtract another once of the denom */
+ movl SIGL(%ebx),%eax
+ movl SIGH(%ebx),%edx
+ subl %eax,FPU_accum_0 /* Subtract from the num local reg */
+ sbbl %edx,FPU_accum_1
+ sbbl $0,FPU_accum_2
+
+#ifdef PARANOID
+ jc L_bugged_2
+ jne L_bugged_2
+#endif /* PARANOID */
+
+ addl $1,FPU_result_1 /* Correct the answer */
+ adcl $0,FPU_result_2
+
+#ifdef PARANOID
+ jc L_bugged_2 /* Must check for non-zero result here */
+#endif /* PARANOID */
+
+/*----------------------------------------------------------------------*/
+/* The division is essentially finished here, we just need to perform
+ tidying operations.
+ Deal with the 3rd 32 bits */
+LDo_3rd_32_bits:
+ movl FPU_accum_1,%edx /* get the reduced num */
+ movl FPU_accum_0,%eax
+
+ /* need to check for possible subsequent overflow */
+ cmpl SIGH(%ebx),%edx /* denom */
+ jb LRound_prep
+ ja LPrevent_3rd_overflow
+
+ cmpl SIGL(%ebx),%eax /* denom */
+ jb LRound_prep
+
+LPrevent_3rd_overflow:
+ /* prevent overflow */
+ subl SIGL(%ebx),%eax
+ sbbl SIGH(%ebx),%edx
+ movl %edx,FPU_accum_1
+ movl %eax,FPU_accum_0
+
+ addl $1,FPU_result_1 /* Reflect the subtraction in the answer */
+ adcl $0,FPU_result_2
+ jne LRound_prep
+ jnc LRound_prep
+
+ /* This is a tricky spot, there is an overflow of the answer */
+ movb $255,FPU_ovfl_flag /* Overflow -> 1.000 */
+
+LRound_prep:
+/*
+ * Prepare for rounding.
+ * To test for rounding, we just need to compare 2*accum with the
+ * denom.
+ */
+ movl FPU_accum_0,%ecx
+ movl FPU_accum_1,%edx
+ movl %ecx,%eax
+ orl %edx,%eax
+ jz LRound_ovfl /* The accumulator contains zero. */
+
+ /* Multiply by 2 */
+ clc
+ rcll $1,%ecx
+ rcll $1,%edx
+ jc LRound_large /* No need to compare, denom smaller */
+
+ subl SIGL(%ebx),%ecx
+ sbbl SIGH(%ebx),%edx
+ jnc LRound_not_small
+
+ movl $0x70000000,%eax /* Denom was larger */
+ jmp LRound_ovfl
+
+LRound_not_small:
+ jnz LRound_large
+
+ movl $0x80000000,%eax /* Remainder was exactly 1/2 denom */
+ jmp LRound_ovfl
+
+LRound_large:
+ movl $0xff000000,%eax /* Denom was smaller */
+
+LRound_ovfl:
+/* We are now ready to deal with rounding, but first we must get
+ the bits properly aligned */
+ testb $255,FPU_ovfl_flag /* was the num > denom ? */
+ je LRound_precision
+
+ incw EXP(%edi)
+
+ /* shift the mantissa right one bit */
+ stc /* Will set the ms bit */
+ rcrl FPU_result_2
+ rcrl FPU_result_1
+ rcrl %eax
+
+/* Round the result as required */
+LRound_precision:
+ decw EXP(%edi) /* binary point between 1st & 2nd bits */
+
+ movl %eax,%edx
+ movl FPU_result_1,%ebx
+ movl FPU_result_2,%eax
+ jmp fpu_reg_round
+
+
+#ifdef PARANOID
+/* The logic is wrong if we got here */
+L_bugged:
+ pushl EX_INTERNAL|0x202
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_1:
+ pushl EX_INTERNAL|0x203
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_bugged_2:
+ pushl EX_INTERNAL|0x204
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_exit:
+ movl $-1,%eax
+ popl %ebx
+ popl %edi
+ popl %esi
+
+ leave
+ ret
+#endif /* PARANOID */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_u_div.c |
+ | |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
+ | |
+ | Copyright (C) 1992,1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | |
+ | Does not compute the destination exponent, but does adjust it. |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+#include <asm/types.h>
+
+
+int FPU_u_div(const FPU_REG *a, const FPU_REG *b, FPU_REG *dest,
+ u16 control_w, u8 sign)
+{
+ s32 exp;
+ u32 divr32, rem, rat1, rat2, work32, accum3, prodh;
+ u64 work64, divr64, prod64, accum64;
+ u8 ovfl;
+
+ exp = (s32)a->exp - (s32)b->exp;
+
+ if ( exp < EXP_WAY_UNDER )
+ exp = EXP_WAY_UNDER;
+
+ dest->exp = exp;
+#ifdef PARANOID
+ if ( !(b->sigh & 0x80000000) )
+ {
+ EXCEPTION(EX_INTERNAL|0x202);
+ }
+#endif
+
+ work64 = significand(a);
+
+ /* We can save a lot of time if the divisor has all its lowest
+ 32 bits equal to zero. */
+ if ( b->sigl == 0 )
+ {
+ divr32 = b->sigh;
+ ovfl = a->sigh >= divr32;
+ rat1 = work64 / divr32;
+ rem = work64 % divr32;
+ work64 = rem;
+ work64 <<= 32;
+ rat2 = work64 / divr32;
+ rem = work64 % divr32;
+
+ work64 = rem;
+ work64 <<= 32;
+ rem = work64 / divr32;
+
+ if ( ovfl )
+ {
+ rem >>= 1;
+ if ( rat2 & 1 )
+ rem |= 0x80000000;
+ rat2 >>= 1;
+ if ( rat1 & 1 )
+ rat2 |= 0x80000000;
+ rat1 >>= 1;
+ rat1 |= 0x80000000;
+ dest->exp ++;
+ }
+ dest->sigh = rat1;
+ dest->sigl = rat2;
+
+ dest->exp --;
+ return FPU_round(dest, rem, 0, control_w, sign);
+ }
+
+ /* This may take a little time... */
+
+ accum64 = work64;
+ divr64 = significand(b);
+
+ if ( (ovfl = accum64 >= divr64) )
+ accum64 -= divr64;
+ divr32 = b->sigh+1;
+
+ if ( divr32 != 0 )
+ {
+ rat1 = accum64 / divr32;
+ }
+ else
+ rat1 = accum64 >> 32;
+ prod64 = rat1 * (u64)b->sigh;
+
+ accum64 -= prod64;
+ prod64 = rat1 * (u64)b->sigl;
+ accum3 = prod64;
+ if ( accum3 )
+ {
+ accum3 = -accum3;
+ accum64 --;
+ }
+ prodh = prod64 >> 32;
+ accum64 -= prodh;
+
+ work32 = accum64 >> 32;
+ if ( work32 )
+ {
+#ifdef PARANOID
+ if ( work32 != 1 )
+ {
+ EXCEPTION(EX_INTERNAL|0x203);
+ }
+#endif
+
+ /* Need to subtract the divisor once more. */
+ work32 = accum3;
+ accum3 = work32 - b->sigl;
+ if ( accum3 > work32 )
+ accum64 --;
+ rat1 ++;
+ accum64 -= b->sigh;
+
+#ifdef PARANOID
+ if ( (accum64 >> 32) )
+ {
+ EXCEPTION(EX_INTERNAL|0x203);
+ }
+#endif
+ }
+
+ /* Now we essentially repeat what we have just done, but shifted
+ 32 bits. */
+
+ accum64 <<= 32;
+ accum64 |= accum3;
+ if ( accum64 >= divr64 )
+ {
+ accum64 -= divr64;
+ rat1 ++;
+ }
+ if ( divr32 != 0 )
+ {
+ rat2 = accum64 / divr32;
+ }
+ else
+ rat2 = accum64 >> 32;
+ prod64 = rat2 * (u64)b->sigh;
+
+ accum64 -= prod64;
+ prod64 = rat2 * (u64)b->sigl;
+ accum3 = prod64;
+ if ( accum3 )
+ {
+ accum3 = -accum3;
+ accum64 --;
+ }
+ prodh = prod64 >> 32;
+ accum64 -= prodh;
+
+ work32 = accum64 >> 32;
+ if ( work32 )
+ {
+#ifdef PARANOID
+ if ( work32 != 1 )
+ {
+ EXCEPTION(EX_INTERNAL|0x203);
+ }
+#endif
+
+ /* Need to subtract the divisor once more. */
+ work32 = accum3;
+ accum3 = work32 - b->sigl;
+ if ( accum3 > work32 )
+ accum64 --;
+ rat2 ++;
+ if ( rat2 == 0 )
+ rat1 ++;
+ accum64 -= b->sigh;
+
+#ifdef PARANOID
+ if ( (accum64 >> 32) )
+ {
+ EXCEPTION(EX_INTERNAL|0x203);
+ }
+#endif
+ }
+
+ /* Tidy up the remainder */
+
+ accum64 <<= 32;
+ accum64 |= accum3;
+ if ( accum64 >= divr64 )
+ {
+ accum64 -= divr64;
+ rat2 ++;
+ if ( rat2 == 0 )
+ {
+ rat1 ++;
+#ifdef PARANOID
+ /* No overflow should be possible here */
+ if ( rat1 == 0 )
+ {
+ EXCEPTION(EX_INTERNAL|0x203);
+ }
+ }
+#endif
+ }
+
+ /* The basic division is done, now we must be careful with the
+ remainder. */
+
+ if ( ovfl )
+ {
+ if ( rat2 & 1 )
+ rem = 0x80000000;
+ else
+ rem = 0;
+ rat2 >>= 1;
+ if ( rat1 & 1 )
+ rat2 |= 0x80000000;
+ rat1 >>= 1;
+ rat1 |= 0x80000000;
+
+ if ( accum64 )
+ rem |= 0xff0000;
+
+ dest->exp ++;
+ }
+ else
+ {
+ /* Now we just need to know how large the remainder is
+ relative to half the divisor. */
+ if ( accum64 == 0 )
+ rem = 0;
+ else
+ {
+ accum3 = accum64 >> 32;
+ if ( accum3 & 0x80000000 )
+ {
+ /* The remainder is definitely larger than 1/2 divisor. */
+ rem = 0xff000000;
+ }
+ else
+ {
+ accum64 <<= 1;
+ if ( accum64 >= divr64 )
+ {
+ accum64 -= divr64;
+ if ( accum64 == 0 )
+ rem = 0x80000000;
+ else
+ rem = 0xff000000;
+ }
+ else
+ rem = 0x7f000000;
+ }
+ }
+ }
+
+ dest->sigh = rat1;
+ dest->sigl = rat2;
+
+ dest->exp --;
+ return FPU_round(dest, rem, 0, control_w, sign);
+
+}
+
--- /dev/null
+ .file "reg_u_mul.S"
+/*---------------------------------------------------------------------------+
+ | reg_u_mul.S |
+ | |
+ | Core multiplication routine |
+ | |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Basic multiplication routine. |
+ | Does not check the resulting exponent for overflow/underflow |
+ | |
+ | FPU_u_mul(FPU_REG *a, FPU_REG *b, FPU_REG *c, unsigned int cw); |
+ | |
+ | Internal working is at approx 128 bits. |
+ | Result is rounded to nearest 53 or 64 bits, using "nearest or even". |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+
+#ifndef NON_REENTRANT_FPU
+/* Local storage on the stack: */
+#define FPU_accum_0 -4(%ebp) /* ms word */
+#define FPU_accum_1 -8(%ebp)
+
+#else
+/* Local storage in a static area: */
+.data
+ .align 4,0
+FPU_accum_0:
+ .long 0
+FPU_accum_1:
+ .long 0
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(FPU_u_mul)
+ pushl %ebp
+ movl %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+ subl $8,%esp
+#endif /* NON_REENTRANT_FPU */
+
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi
+ movl PARAM2,%edi
+
+#ifdef PARANOID
+ testl $0x80000000,SIGH(%esi)
+ jz L_bugged
+ testl $0x80000000,SIGH(%edi)
+ jz L_bugged
+#endif /* PARANOID */
+
+ xorl %ecx,%ecx
+ xorl %ebx,%ebx
+
+ movl SIGL(%esi),%eax
+ mull SIGL(%edi)
+ movl %eax,FPU_accum_0
+ movl %edx,FPU_accum_1
+
+ movl SIGL(%esi),%eax
+ mull SIGH(%edi)
+ addl %eax,FPU_accum_1
+ adcl %edx,%ebx
+/* adcl $0,%ecx // overflow here is not possible */
+
+ movl SIGH(%esi),%eax
+ mull SIGL(%edi)
+ addl %eax,FPU_accum_1
+ adcl %edx,%ebx
+ adcl $0,%ecx
+
+ movl SIGH(%esi),%eax
+ mull SIGH(%edi)
+ addl %eax,%ebx
+ adcl %edx,%ecx
+
+ /* Get the sum of the exponents. */
+ movl PARAM6,%eax
+ subl EXP_BIAS-1,%eax
+
+ /* Two denormals can cause an exponent underflow */
+ cmpl EXP_WAY_UNDER,%eax
+ jg Exp_not_underflow
+
+ /* Set to a really low value allow correct handling */
+ movl EXP_WAY_UNDER,%eax
+
+Exp_not_underflow:
+
+/* Have now finished with the sources */
+ movl PARAM3,%edi /* Point to the destination */
+ movw %ax,EXP(%edi)
+
+/* Now make sure that the result is normalized */
+ testl $0x80000000,%ecx
+ jnz LResult_Normalised
+
+ /* Normalize by shifting left one bit */
+ shll $1,FPU_accum_0
+ rcll $1,FPU_accum_1
+ rcll $1,%ebx
+ rcll $1,%ecx
+ decw EXP(%edi)
+
+LResult_Normalised:
+ movl FPU_accum_0,%eax
+ movl FPU_accum_1,%edx
+ orl %eax,%eax
+ jz L_extent_zero
+
+ orl $1,%edx
+
+L_extent_zero:
+ movl %ecx,%eax
+ jmp fpu_reg_round
+
+
+#ifdef PARANOID
+L_bugged:
+ pushl EX_INTERNAL|0x205
+ call EXCEPTION
+ pop %ebx
+ jmp L_exit
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
+#endif /* PARANOID */
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_u_mul.c |
+ | |
+ | Core multiplication routine |
+ | |
+ | Copyright (C) 1992,1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | Basic multiplication routine. |
+ | Does not check the resulting exponent for overflow/underflow |
+ | |
+ | Internal working is at approx 128 bits. |
+ | Result is rounded to nearest 53 or 64 bits, using "nearest or even". |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+int FPU_u_mul(const FPU_REG *a, const FPU_REG *b, FPU_REG *c, u16 cw,
+ u_char sign, int expon)
+{
+ u64 mu, ml, mi;
+ u32 lh, ll, th, tl;
+
+#ifdef PARANOID
+ if ( ! (a->sigh & 0x80000000) || ! (b->sigh & 0x80000000) )
+ {
+ EXCEPTION(EX_INTERNAL|0x205);
+ }
+#endif
+
+ ml = a->sigl;
+ ml *= b->sigl;
+ ll = ml;
+ lh = ml >> 32;
+
+ mu = a->sigh;
+ mu *= b->sigh;
+
+ mi = a->sigh;
+ mi *= b->sigl;
+ tl = mi;
+ th = mi >> 32;
+ lh += tl;
+ if ( tl > lh )
+ mu ++;
+ mu += th;
+
+ mi = a->sigl;
+ mi *= b->sigh;
+ tl = mi;
+ th = mi >> 32;
+ lh += tl;
+ if ( tl > lh )
+ mu ++;
+ mu += th;
+
+ ml = lh;
+ ml <<= 32;
+ ml += ll;
+
+ expon -= EXP_BIAS-1;
+ if ( expon <= EXP_WAY_UNDER )
+ expon = EXP_WAY_UNDER;
+
+ c->exp = expon;
+
+ if ( ! (mu & BX_CONST64(0x8000000000000000)) )
+ {
+ mu <<= 1;
+ if ( ml & BX_CONST64(0x8000000000000000) )
+ mu |= 1;
+ ml <<= 1;
+ c->exp --;
+ }
+
+ ll = ml;
+ lh = ml >> 32;
+
+ if ( ll )
+ lh |= 1;
+
+ c->sigl = mu;
+ c->sigh = mu >> 32;
+
+ return FPU_round(c, lh, 0, cw, sign);
+
+}
--- /dev/null
+ .file "reg_u_sub.S"
+/*---------------------------------------------------------------------------+
+ | reg_u_sub.S |
+ | |
+ | Core floating point subtraction routine. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@suburbia.net |
+ | |
+ | Call from C as: |
+ | int FPU_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ, |
+ | int control_w) |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*
+ | Kernel subtraction routine FPU_u_sub(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TAG_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their difference as a TAG_Valid or TAG_Zero f.p.
+ | number.
+ | The first number (arg1) must be the larger.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+.text
+ENTRY(FPU_u_sub)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi /* source 1 */
+ movl PARAM2,%edi /* source 2 */
+
+ movl PARAM6,%ecx
+ subl PARAM7,%ecx /* exp1 - exp2 */
+
+#ifdef PARANOID
+ /* source 2 is always smaller than source 1 */
+ js L_bugged_1
+
+ testl $0x80000000,SIGH(%edi) /* The args are assumed to be be normalized */
+ je L_bugged_2
+
+ testl $0x80000000,SIGH(%esi)
+ je L_bugged_2
+#endif /* PARANOID */
+
+/*--------------------------------------+
+ | Form a register holding the |
+ | smaller number |
+ +--------------------------------------*/
+ movl SIGH(%edi),%eax /* register ms word */
+ movl SIGL(%edi),%ebx /* register ls word */
+
+ movl PARAM3,%edi /* destination */
+ movl PARAM6,%edx
+ movw %dx,EXP(%edi) /* Copy exponent to destination */
+
+ xorl %edx,%edx /* register extension */
+
+/*--------------------------------------+
+ | Shift the temporary register |
+ | right the required number of |
+ | places. |
+ +--------------------------------------*/
+
+ cmpw $32,%cx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ jmp L_shift_done
+
+L_more_than_31:
+ cmpw $64,%cx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ jz L_exactly_32
+
+ shrd %cl,%eax,%edx
+ shr %cl,%eax
+ orl %ebx,%ebx
+ jz L_more_31_no_low /* none of the lowest bits is set */
+
+ orl $1,%edx /* record the fact in the extension */
+
+L_more_31_no_low:
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_exactly_32:
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ jmp L_shift_done
+
+L_more_than_63:
+ cmpw $65,%cx
+ jnc L_more_than_64
+
+ /* Shift right by 64 bits */
+ movl %eax,%edx
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_64:
+ jne L_more_than_65
+
+ /* Shift right by 65 bits */
+ /* Carry is clear if we get here */
+ movl %eax,%edx
+ rcrl %edx
+ jnc L_shift_65_nc
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_shift_65_nc:
+ orl %ebx,%ebx
+ jz L_more_63_no_low
+
+ orl $1,%edx
+ jmp L_more_63_no_low
+
+L_more_than_65:
+ movl $1,%edx /* The shifted nr always at least one '1' */
+
+L_more_63_no_low:
+ xorl %ebx,%ebx
+ xorl %eax,%eax
+
+L_shift_done:
+L_subtr:
+/*------------------------------+
+ | Do the subtraction |
+ +------------------------------*/
+ xorl %ecx,%ecx
+ subl %edx,%ecx
+ movl %ecx,%edx
+ movl SIGL(%esi),%ecx
+ sbbl %ebx,%ecx
+ movl %ecx,%ebx
+ movl SIGH(%esi),%ecx
+ sbbl %eax,%ecx
+ movl %ecx,%eax
+
+#ifdef PARANOID
+ /* We can never get a borrow */
+ jc L_bugged
+#endif /* PARANOID */
+
+/*--------------------------------------+
+ | Normalize the result |
+ +--------------------------------------*/
+ testl $0x80000000,%eax
+ jnz L_round /* no shifting needed */
+
+ orl %eax,%eax
+ jnz L_shift_1 /* shift left 1 - 31 bits */
+
+ orl %ebx,%ebx
+ jnz L_shift_32 /* shift left 32 - 63 bits */
+
+/*
+ * A rare case, the only one which is non-zero if we got here
+ * is: 1000000 .... 0000
+ * -0111111 .... 1111 1
+ * --------------------
+ * 0000000 .... 0000 1
+ */
+
+ cmpl $0x80000000,%edx
+ jnz L_must_be_zero
+
+ /* Shift left 64 bits */
+ subw $64,EXP(%edi)
+ xchg %edx,%eax
+ jmp fpu_reg_round
+
+L_must_be_zero:
+#ifdef PARANOID
+ orl %edx,%edx
+ jnz L_bugged_3
+#endif /* PARANOID */
+
+ /* The result is zero */
+ movw $0,EXP(%edi) /* exponent */
+ movl $0,SIGL(%edi)
+ movl $0,SIGH(%edi)
+ movl TAG_Zero,%eax
+ jmp L_exit
+
+L_shift_32:
+ movl %ebx,%eax
+ movl %edx,%ebx
+ movl $0,%edx
+ subw $32,EXP(%edi) /* Can get underflow here */
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+ bsrl %eax,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ shld %cl,%ebx,%eax
+ shld %cl,%edx,%ebx
+ shl %cl,%edx
+ subw %cx,EXP(%edi) /* Can get underflow here */
+
+L_round:
+ jmp fpu_reg_round /* Round the result */
+
+
+#ifdef PARANOID
+L_bugged_1:
+ pushl EX_INTERNAL|0x206
+ call EXCEPTION
+ pop %ebx
+ jmp L_error_exit
+
+L_bugged_2:
+ pushl EX_INTERNAL|0x209
+ call EXCEPTION
+ pop %ebx
+ jmp L_error_exit
+
+L_bugged_3:
+ pushl EX_INTERNAL|0x210
+ call EXCEPTION
+ pop %ebx
+ jmp L_error_exit
+
+L_bugged_4:
+ pushl EX_INTERNAL|0x211
+ call EXCEPTION
+ pop %ebx
+ jmp L_error_exit
+
+L_bugged:
+ pushl EX_INTERNAL|0x212
+ call EXCEPTION
+ pop %ebx
+ jmp L_error_exit
+
+L_error_exit:
+ movl $-1,%eax
+
+#endif /* PARANOID */
+
+L_exit:
+ popl %ebx
+ popl %edi
+ popl %esi
+ leave
+ ret
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | reg_u_sub.c |
+ | |
+ | Core floating point subtraction routine. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | Return value is the tag of the answer, or-ed with FPU_Exception if |
+ | one was raised, or -1 on internal error. |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*
+ | Kernel subtraction routine FPU_u_sub(reg *arg1, reg *arg2, reg *answ).
+ | Takes two valid reg f.p. numbers (TAG_Valid), which are
+ | treated as unsigned numbers,
+ | and returns their difference as a TAG_Valid or TAG_Zero f.p.
+ | number.
+ | The first number (arg1) must be the larger.
+ | The returned number is normalized.
+ | Basic checks are performed if PARANOID is defined.
+ */
+
+#include "exception.h"
+#include "fpu_emu.h"
+#include "control_w.h"
+
+
+
+int FPU_u_sub(const FPU_REG *arg1, const FPU_REG *arg2, FPU_REG *dest,
+ u16 control_w, u_char sign, int expa, int expb)
+{
+ FPU_REG shifted, answ;
+ u32 extent;
+ int ediff = expa - expb, ed2, borrow;
+
+#ifdef PARANOID
+ if ( ediff < 0 )
+ {
+ EXCEPTION(EX_INTERNAL|0x206);
+ return -1;
+ }
+#endif
+
+ answ.exp = expa;
+
+#ifdef PARANOID
+ if ( !(arg1->sigh & 0x80000000) || !(arg2->sigh & 0x80000000) )
+ {
+ EXCEPTION(EX_INTERNAL|0x209);
+ return -1;
+ }
+#endif
+
+ if ( ediff == 0 )
+ {
+ shifted.sigl = arg2->sigl;
+ shifted.sigh = arg2->sigh;
+ extent = 0;
+ }
+ else if ( ediff < 32 )
+ {
+ ed2 = 32 - ediff;
+ extent = arg2->sigl << ed2;
+ shifted.sigl = arg2->sigl >> ediff;
+ shifted.sigl |= (arg2->sigh << ed2);
+ shifted.sigh = arg2->sigh >> ediff;
+ }
+ else if ( ediff < 64 )
+ {
+ ediff -= 32;
+ if ( ! ediff )
+ {
+ extent = arg2->sigl;
+ shifted.sigl = arg2->sigh;
+ shifted.sigh = 0;
+ }
+ else
+ {
+ ed2 = 32 - ediff;
+ extent = arg2->sigl >> ediff;
+ extent |= (arg2->sigh << ed2);
+ if ( arg2->sigl << ed2 )
+ extent |= 1;
+ shifted.sigl = arg2->sigh >> ediff;
+ shifted.sigh = 0;
+ }
+ }
+ else
+ {
+ ediff -= 64;
+ if ( ! ediff )
+ {
+ extent = arg2->sigh;
+ if ( arg2->sigl )
+ extent |= 1;
+ shifted.sigl = 0;
+ shifted.sigh = 0;
+ }
+ else
+ {
+ if ( ediff < 32 )
+ {
+ extent = arg2->sigh >> ediff;
+ if ( arg2->sigl || (arg2->sigh << (32-ediff)) )
+ extent |= 1;
+ }
+ else
+ extent = 1;
+ shifted.sigl = 0;
+ shifted.sigh = 0;
+ }
+ }
+
+ extent = -extent;
+ borrow = extent;
+ answ.sigl = arg1->sigl - shifted.sigl;
+ if ( answ.sigl > arg1->sigl )
+ {
+ if ( borrow )
+ answ.sigl --;
+ borrow = 1;
+ }
+ else if ( borrow )
+ {
+ answ.sigl --;
+ if ( answ.sigl != 0xffffffff )
+ borrow = 0;
+ }
+ answ.sigh = arg1->sigh - shifted.sigh;
+ if ( answ.sigh > arg1->sigh )
+ {
+ if ( borrow )
+ answ.sigh --;
+ borrow = 1;
+ }
+ else if ( borrow )
+ {
+ answ.sigh --;
+ if ( answ.sigh != 0xffffffff )
+ borrow = 0;
+ }
+
+#ifdef PARANOID
+ if ( borrow )
+ {
+ /* This can only occur if the code is bugged */
+ EXCEPTION(EX_INTERNAL|0x212);
+ return -1;
+ }
+#endif
+
+ if ( answ.sigh & 0x80000000 )
+ {
+ /*
+ The simpler "*dest = answ" is broken in gcc
+ */
+ dest->exp = answ.exp;
+ dest->sigh = answ.sigh;
+ dest->sigl = answ.sigl;
+ return FPU_round(dest, extent, 0, control_w, sign);
+ }
+
+ if ( answ.sigh == 0 )
+ {
+ if ( answ.sigl )
+ {
+ answ.sigh = answ.sigl;
+ answ.sigl = extent;
+ extent = 0;
+ answ.exp -= 32;
+ }
+ else if ( extent )
+ {
+/*
+ * A rare case, the only one which is non-zero if we got here
+ * is: 1000000 .... 0000
+ * -0111111 .... 1111 1
+ * --------------------
+ * 0000000 .... 0000 1
+ */
+ if ( extent != 0x80000000 )
+ {
+ /* This can only occur if the code is bugged */
+ EXCEPTION(EX_INTERNAL|0x210);
+ return -1;
+ }
+ dest->sigh = extent;
+ dest->sigl = extent = 0;
+ dest->exp -= 64;
+ return FPU_round(dest, extent, 0, control_w, sign);
+ }
+ else
+ {
+ dest->exp = 0;
+ dest->sigh = dest->sigl = 0;
+ return TAG_Zero;
+ }
+ }
+
+ while ( !(answ.sigh & 0x80000000) )
+ {
+ answ.sigh <<= 1;
+ if ( answ.sigl & 0x80000000 )
+ answ.sigh |= 1;
+ answ.sigl <<= 1;
+ if ( extent & 0x80000000 )
+ answ.sigl |= 1;
+ extent <<= 1;
+ answ.exp --;
+ }
+
+ dest->exp = answ.exp;
+ dest->sigh = answ.sigh;
+ dest->sigl = answ.sigl;
+
+ return FPU_round(dest, extent, 0, control_w, sign);
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | round_Xsig.S |
+ | |
+ | Copyright (C) 1992,1993,1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | Normalize and round a 12 byte quantity. |
+ | Call from C as: |
+ | int round_Xsig(Xsig *n) |
+ | |
+ | Normalize a 12 byte quantity. |
+ | Call from C as: |
+ | int norm_Xsig(Xsig *n) |
+ | |
+ | Each function returns the size of the shift (nr of bits). |
+ | |
+ +---------------------------------------------------------------------------*/
+ .file "round_Xsig.S"
+
+#include "fpu_emu.h"
+
+
+.text
+ENTRY(round_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx /* Reserve some space */
+ pushl %ebx
+ pushl %esi
+
+ movl PARAM1,%esi
+
+ movl 8(%esi),%edx
+ movl 4(%esi),%ebx
+ movl (%esi),%eax
+
+ movl $0,-4(%ebp)
+
+ orl %edx,%edx /* ms bits */
+ js L_round /* Already normalized */
+ jnz L_shift_1 /* Shift left 1 - 31 bits */
+
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ movl $-32,-4(%ebp)
+
+/* We need to shift left by 1 - 31 bits */
+L_shift_1:
+ bsrl %edx,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ subl %ecx,-4(%ebp)
+ shld %cl,%ebx,%edx
+ shld %cl,%eax,%ebx
+ shl %cl,%eax
+
+L_round:
+ testl $0x80000000,%eax
+ jz L_exit
+
+ addl $1,%ebx
+ adcl $0,%edx
+ jnz L_exit
+
+ movl $0x80000000,%edx
+ incl -4(%ebp)
+
+L_exit:
+ movl %edx,8(%esi)
+ movl %ebx,4(%esi)
+ movl %eax,(%esi)
+
+ movl -4(%ebp),%eax
+
+ popl %esi
+ popl %ebx
+ leave
+ ret
+
+
+
+
+ENTRY(norm_Xsig)
+ pushl %ebp
+ movl %esp,%ebp
+ pushl %ebx /* Reserve some space */
+ pushl %ebx
+ pushl %esi
+
+ movl PARAM1,%esi
+
+ movl 8(%esi),%edx
+ movl 4(%esi),%ebx
+ movl (%esi),%eax
+
+ movl $0,-4(%ebp)
+
+ orl %edx,%edx /* ms bits */
+ js L_n_exit /* Already normalized */
+ jnz L_n_shift_1 /* Shift left 1 - 31 bits */
+
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ movl $-32,-4(%ebp)
+
+ orl %edx,%edx /* ms bits */
+ js L_n_exit /* Normalized now */
+ jnz L_n_shift_1 /* Shift left 1 - 31 bits */
+
+ movl %ebx,%edx
+ movl %eax,%ebx
+ xorl %eax,%eax
+ addl $-32,-4(%ebp)
+ jmp L_n_exit /* Might not be normalized,
+ but shift no more. */
+
+/* We need to shift left by 1 - 31 bits */
+L_n_shift_1:
+ bsrl %edx,%ecx /* get the required shift in %ecx */
+ subl $31,%ecx
+ negl %ecx
+ subl %ecx,-4(%ebp)
+ shld %cl,%ebx,%edx
+ shld %cl,%eax,%ebx
+ shl %cl,%eax
+
+L_n_exit:
+ movl %edx,8(%esi)
+ movl %ebx,4(%esi)
+ movl %eax,(%esi)
+
+ movl -4(%ebp),%eax
+
+ popl %esi
+ popl %ebx
+ leave
+ ret
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | round_Xsig.c |
+ | |
+ | Copyright (C) 1992,1993,1994,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | Normalize and round a 12 byte quantity. |
+ | int round_Xsig(Xsig *n) |
+ | |
+ | Normalize a 12 byte quantity. |
+ | int norm_Xsig(Xsig *n) |
+ | |
+ | Each function returns the size of the shift (nr of bits). |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+int round_Xsig(Xsig *x)
+{
+ int n = 0;
+
+ if ( x->msw == 0 )
+ {
+ x->msw = x->midw;
+ x->midw = x->lsw;
+ x->lsw = 0;
+ n = 32;
+ }
+ while ( !(x->msw & 0x80000000) )
+ {
+ x->msw <<= 1;
+ if ( x->midw & 0x80000000 ) x->msw |= 1;
+ x->midw <<= 1;
+ if ( x->lsw & 0x80000000 ) x->midw |= 1;
+ x->lsw <<= 1;
+ n++;
+ }
+ if ( x->lsw & 0x80000000 )
+ {
+ x->midw ++;
+ if ( x->midw == 0 )
+ x->msw ++;
+ if ( x->msw == 0 )
+ {
+ x->msw = 0x80000000;
+ n--;
+ }
+ }
+
+
+ return -n;
+}
+
+
+int norm_Xsig(Xsig *x)
+{
+ int n = 0;
+
+ if ( x->msw == 0 )
+ {
+ if ( x->midw == 0 )
+ {
+ x->msw = x->lsw;
+ x->midw = 0;
+ x->lsw = 0;
+ n = 64;
+ }
+ else
+ {
+ x->msw = x->midw;
+ x->midw = x->lsw;
+ x->lsw = 0;
+ n = 32;
+ }
+ }
+ while ( !(x->msw & 0x80000000) )
+ {
+ x->msw <<= 1;
+ if ( x->midw & 0x80000000 ) x->msw |= 1;
+ x->midw <<= 1;
+ if ( x->lsw & 0x80000000 ) x->midw |= 1;
+ x->lsw <<= 1;
+ n++;
+ }
+
+ return -n;
+}
+
+
+
+
+
--- /dev/null
+ .file "shr_Xsig.S"
+/*---------------------------------------------------------------------------+
+ | shr_Xsig.S |
+ | |
+ | 12 byte right shift function |
+ | |
+ | Copyright (C) 1992,1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | Call from C as: |
+ | void shr_Xsig(Xsig *arg, unsigned nr) |
+ | |
+ | Extended shift right function. |
+ | Fastest for small shifts. |
+ | Shifts the 12 byte quantity pointed to by the first arg (arg) |
+ | right by the number of bits specified by the second arg (nr). |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+ENTRY(shr_Xsig)
+ push %ebp
+ movl %esp,%ebp
+ pushl %esi
+ movl PARAM2,%ecx
+ movl PARAM1,%esi
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ pushl %ebx
+ movl (%esi),%eax /* lsl */
+ movl 4(%esi),%ebx /* midl */
+ movl 8(%esi),%edx /* msl */
+ shrd %cl,%ebx,%eax
+ shrd %cl,%edx,%ebx
+ shr %cl,%edx
+ movl %eax,(%esi)
+ movl %ebx,4(%esi)
+ movl %edx,8(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+L_more_than_31:
+ cmpl $64,%ecx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ movl 4(%esi),%eax /* midl */
+ movl 8(%esi),%edx /* msl */
+ shrd %cl,%edx,%eax
+ shr %cl,%edx
+ movl %eax,(%esi)
+ movl %edx,4(%esi)
+ movl $0,8(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_63:
+ cmpl $96,%ecx
+ jnc L_more_than_95
+
+ subb $64,%cl
+ movl 8(%esi),%eax /* msl */
+ shr %cl,%eax
+ xorl %edx,%edx
+ movl %eax,(%esi)
+ movl %edx,4(%esi)
+ movl %edx,8(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_95:
+ xorl %eax,%eax
+ movl %eax,(%esi)
+ movl %eax,4(%esi)
+ movl %eax,8(%esi)
+ popl %esi
+ leave
+ ret
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | shr_Xsig.S |
+ | |
+ | 12 byte right shift function |
+ | |
+ | Copyright (C) 1992,1994,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | |
+ | Extended shift right function. |
+ | Fastest for small shifts. |
+ | Shifts the 12 byte quantity pointed to by the first arg (arg) |
+ | right by the number of bits specified by the second arg (nr). |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+#include "poly.h"
+
+void shr_Xsig(Xsig *arg, const int nr)
+{
+ int n = nr;
+
+ while ( n >= 32 )
+ {
+ arg->lsw = arg->midw;
+ arg->midw = arg->msw;
+ arg->msw = 0;
+ n -= 32;
+ }
+
+ if ( n <= 0 )
+ return;
+
+ arg->lsw = (arg->lsw >> n) | (arg->midw << (32-n));
+ arg->midw = (arg->midw >> n) | (arg->msw << (32-n));
+ arg->msw >>= n;
+
+}
+
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | status_w.h |
+ | |
+ | Copyright (C) 1992,1993 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _STATUS_H_
+#define _STATUS_H_
+
+#include "fpu_emu.h" /* for definition of PECULIAR_486 */
+
+#ifdef __ASSEMBLY__
+#define Const__(x) $##x
+#else
+#define Const__(x) x
+#endif
+
+#define SW_Backward Const__(0x8000) /* backward compatibility */
+#define SW_C3 Const__(0x4000) /* condition bit 3 */
+#define SW_Top Const__(0x3800) /* top of stack */
+#define SW_Top_Shift Const__(11) /* shift for top of stack bits */
+#define SW_C2 Const__(0x0400) /* condition bit 2 */
+#define SW_C1 Const__(0x0200) /* condition bit 1 */
+#define SW_C0 Const__(0x0100) /* condition bit 0 */
+#define SW_Summary Const__(0x0080) /* exception summary */
+#define SW_Stack_Fault Const__(0x0040) /* stack fault */
+#define SW_Precision Const__(0x0020) /* loss of precision */
+#define SW_Underflow Const__(0x0010) /* underflow */
+#define SW_Overflow Const__(0x0008) /* overflow */
+#define SW_Zero_Div Const__(0x0004) /* divide by zero */
+#define SW_Denorm_Op Const__(0x0002) /* denormalized operand */
+#define SW_Invalid Const__(0x0001) /* invalid operation */
+
+#define SW_Exc_Mask Const__(0x27f) /* Status word exception bit mask */
+
+#ifndef __ASSEMBLY__
+
+#define COMP_A_gt_B 1
+#define COMP_A_eq_B 2
+#define COMP_A_lt_B 3
+#define COMP_No_Comp 4
+#define COMP_Denormal 0x20
+#define COMP_NaN 0x40
+#define COMP_SNaN 0x80
+
+#define status_word() \
+ ((partial_status & ~SW_Top & 0xffff) | ((top << SW_Top_Shift) & SW_Top))
+// bbd: use do {...} while (0) structure instead of using curly brackets
+// inside parens, which most compilers do not like.
+#define setcc(cc) do { \
+ partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \
+ partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); } while(0)
+
+#ifdef PECULIAR_486
+ /* Default, this conveys no information, but an 80486 does it. */
+ /* Clear the SW_C1 bit, "other bits undefined". */
+# define clear_C1() { partial_status &= ~SW_C1; }
+# else
+# define clear_C1()
+#endif /* PECULIAR_486 */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _STATUS_H_ */
--- /dev/null
+#ifndef __ARCH_DESC_H
+#define __ARCH_DESC_H
+
+struct desc_struct {
+ unsigned long a,b;
+};
+
+extern struct desc_struct gdt_table[];
+extern struct desc_struct *idt, *gdt;
+
+struct Xgt_desc_struct {
+ unsigned short size;
+ unsigned long address GCC_ATTRIBUTE((packed));
+};
+
+#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
+#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
+
+/*
+ * Entry into gdt where to find first TSS. GDT layout:
+ * 0 - null
+ * 1 - not used
+ * 2 - kernel code segment
+ * 3 - kernel data segment
+ * 4 - user code segment
+ * 5 - user data segment
+ * 6 - not used
+ * 7 - not used
+ * 8 - APM BIOS support
+ * 9 - APM BIOS support
+ * 10 - APM BIOS support
+ * 11 - APM BIOS support
+ * 12 - TSS #0
+ * 13 - LDT #0
+ * 14 - TSS #1
+ * 15 - LDT #1
+ */
+#define FIRST_TSS_ENTRY 12
+#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
+#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
+#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
+#define load_TR(n) __asm__ __volatile__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
+#define load_ldt(n) __asm__ __volatile__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
+#define store_TR(n) \
+__asm__("str %%ax\n\t" \
+ "subl %2,%%eax\n\t" \
+ "shrl $4,%%eax" \
+ :"=a" (n) \
+ :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
+
+extern void set_intr_gate(unsigned int irq, void * addr);
+extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size);
+extern void set_tss_desc(unsigned int n, void *addr);
+
+/*
+ * This is the ldt that every process will get unless we need
+ * something other than this.
+ */
+extern struct desc_struct default_ldt;
+
+#endif
--- /dev/null
+#ifndef _I386_MATH_EMU_H
+#define _I386_MATH_EMU_H
+
+// Don't really need anything in here.
+
+#endif
--- /dev/null
+#ifndef _ASMi386_SIGCONTEXT_H
+#define _ASMi386_SIGCONTEXT_H
+
+/*
+ * As documented in the iBCS2 standard..
+ *
+ * The first part of "struct _fpstate" is just the
+ * normal i387 hardware setup, the extra "status"
+ * word is used to save the coprocessor status word
+ * before entering the handler.
+ */
+struct _fpreg {
+ unsigned short significand[4];
+ unsigned short exponent;
+};
+
+struct _fpstate {
+ unsigned long cw,
+ sw,
+ tag,
+ ipoff,
+ cssel,
+ dataoff,
+ datasel;
+ struct _fpreg _st[8];
+ unsigned long status;
+};
+
+#if 0
+/* sigcontext is not needed by bochs, and it conflicts with some other
+ machine types (DEC OSF1) */
+struct sigcontext {
+ unsigned short gs, __gsh;
+ unsigned short fs, __fsh;
+ unsigned short es, __esh;
+ unsigned short ds, __dsh;
+ unsigned long edi;
+ unsigned long esi;
+ unsigned long ebp;
+ unsigned long esp;
+ unsigned long ebx;
+ unsigned long edx;
+ unsigned long ecx;
+ unsigned long eax;
+ unsigned long trapno;
+ unsigned long err;
+ unsigned long eip;
+ unsigned short cs, __csh;
+ unsigned long eflags;
+ unsigned long esp_at_signal;
+ unsigned short ss, __ssh;
+ struct _fpstate * fpstate;
+ unsigned long oldmask;
+ unsigned long cr2;
+};
+#endif
+
+
+#endif
--- /dev/null
+#ifndef _I386_TYPES_H
+#define _I386_TYPES_H
+
+#ifndef __ASSEMBLY__
+#endif
+
+#endif /* _I386_TYPES_H */
--- /dev/null
+#ifndef _I386_UACCESS_H
+#define _I386_UACCESS_H
+
+
+
+#endif
--- /dev/null
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+int printk(const char * fmt, ...)
+ GCC_ATTRIBUTE((format (printf, 1, 2)));
+
+#endif
--- /dev/null
+#ifndef _LINUX_LINKAGE_H
+#define _LINUX_LINKAGE_H
+
+#ifdef __cplusplus
+#define CPP_ASMLINKAGE extern "C"
+#else
+#define CPP_ASMLINKAGE
+#endif
+
+#if defined __i386__ && (__GNUC__ > 2 || __GNUC_MINOR__ > 7)
+#define asmlinkage CPP_ASMLINKAGE GCC_ATTRIBUTE((regparm(0)))
+#else
+#define asmlinkage CPP_ASMLINKAGE
+#endif
+
+#define SYMBOL_NAME_STR(X) #X
+#define SYMBOL_NAME(X) X
+#ifdef __STDC__
+#define SYMBOL_NAME_LABEL(X) X##:
+#else
+#define SYMBOL_NAME_LABEL(X) X/**/:
+#endif
+
+#ifdef __arm__
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+#else
+#ifdef __mc68000__
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+#else
+#if !defined(__i486__) && !defined(__i586__)
+#define __ALIGN .align 4,0x90
+#define __ALIGN_STR ".align 4,0x90"
+#else /* __i486__/__i586__ */
+#define __ALIGN .align 16,0x90
+#define __ALIGN_STR ".align 16,0x90"
+#endif /* __i486__/__i586__ */
+#endif /* __mc68000__ */
+#endif /* __arm__ */
+
+#ifdef __ASSEMBLY__
+
+#define ALIGN __ALIGN
+#define ALIGN_STR __ALIGN_STR
+
+#define ENTRY(name) \
+ .globl SYMBOL_NAME(name); \
+ ALIGN; \
+ SYMBOL_NAME_LABEL(name)
+
+#endif
+
+#endif
--- /dev/null
+#ifndef _LINUX_MM_H
+#define _LINUX_MM_H
+
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+#endif
--- /dev/null
+#ifndef _ASMi386_SIGNAL_H
+#define _ASMi386_SIGNAL_H
+
+#define SIGILL 4
+#define SIGFPE 8
+#define SIGSEGV 11
+
+#endif
--- /dev/null
+#ifndef _LINUX_STDDEF_H
+#define _LINUX_STDDEF_H
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+
+#undef NULL
+#define NULL ((void *)0)
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif
--- /dev/null
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+#define u_char bx_u_char
+#define u_short bx_u_short
+#define u_int bx_u_int
+#define u_long bx_u_long
+#define unchar bx_unchar
+#define ushort bx_ushort
+#define uint bx_uint
+#define ulong bx_ulong
+
+/* bsd */
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+/* sysv */
+typedef unsigned char unchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#endif
+
+#endif /* _LINUX_TYPES_H */
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | version.h |
+ | |
+ | |
+ | Copyright (C) 1992,1993,1994,1996,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ | E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#define FPU_VERSION "wm-FPU-emu version 2.05"
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+//
+// This is the glue logic needed to connect the wm-FPU-emu
+// FPU emulator written by Bill Metzenthen to bochs.
+//
+
+
+#include "bochs.h"
+extern "C" {
+#include "fpu_emu.h"
+#include "linux/signal.h"
+}
+
+#define LOG_THIS genlog->
+#if BX_USE_CPU_SMF
+#define this (BX_CPU(0))
+#endif
+
+// Use this to hold a pointer to the instruction since
+// we can't pass this to the FPU emulation routines, which
+// will ultimately call routines here.
+static BxInstruction_t *fpu_iptr = NULL;
+static BX_CPU_C *fpu_cpu_ptr = NULL;
+
+i387_t i387;
+
+extern "C" void
+math_emulate2(fpu_addr_modes addr_modes,
+ u_char FPU_modrm,
+ u_char byte1,
+ void *data_address,
+ struct address data_sel_off,
+ struct address entry_sel_off);
+
+extern "C" void printfp(char *s, FPU_REG *r);
+
+
+ // This is called by bochs upon reset
+ void
+BX_CPU_C::fpu_init(void)
+{
+ finit();
+}
+
+ void
+BX_CPU_C::fpu_execute(BxInstruction_t *i)
+{
+ fpu_addr_modes addr_modes;
+ void *data_address;
+ struct address data_sel_off;
+ struct address entry_sel_off;
+ Boolean is_32;
+
+ fpu_iptr = i;
+ fpu_cpu_ptr = this;
+
+#if 0
+ addr_modes.default_mode = VM86;
+ addr_modes.default_mode = 0; // FPU_CS == __USER_CS && FPU_DS == __USER_DS
+ addr_modes.default_mode = SEG32;
+ addr_modes.default_mode = PM16;
+#endif
+ if (protected_mode()) {
+ addr_modes.default_mode = SEG32;
+ }
+ else if (v8086_mode()) {
+ addr_modes.default_mode = VM86;
+ }
+ else {
+ // real mode, use vm86 for now
+ addr_modes.default_mode = VM86;
+ }
+
+
+ // Mark if instruction used opsize or addrsize prefixes
+ // Actually, addr_modes.override.address_size is not used,
+ // could delete that code.
+ is_32 = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b;
+ if (i->as_32 == is_32)
+ addr_modes.override.address_size = 0;
+ else
+ addr_modes.override.address_size = ADDR_SIZE_PREFIX;
+ if (i->os_32 == is_32)
+ addr_modes.override.operand_size = 0;
+ else
+ addr_modes.override.operand_size = OP_SIZE_PREFIX;
+
+ // For now set access_limit to max. It seems to be
+ // a number from 0..255 denoting how many bytes the
+ // current instruction can access according to its
+ // memory operand. 255 means >= 255.
+access_limit = 0xff;
+
+ // fill in orig eip here in offset
+ // fill in CS in selector
+ entry_sel_off.offset = BX_CPU_THIS_PTR prev_eip;
+ entry_sel_off.selector = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
+
+// should set these fields to 0 if mem operand not used
+ data_address = (void *) i->rm_addr;
+ data_sel_off.offset = i->rm_addr;
+ data_sel_off.selector = BX_CPU_THIS_PTR sregs[i->seg].selector.value;
+
+ math_emulate2(addr_modes, i->modrm, i->b1, data_address,
+ data_sel_off, entry_sel_off);
+}
+
+
+ unsigned
+fpu_get_ds(void)
+{
+ return(fpu_cpu_ptr->sregs[BX_SEG_REG_DS].selector.value);
+}
+
+ void
+fpu_set_ax(unsigned short val16)
+{
+// define to set AX in the current CPU -- not ideal.
+#undef AX
+#define AX (fpu_cpu_ptr->gen_reg[0].word.rx)
+ AX = val16;
+#undef AX
+//BX_DEBUG(( "fpu_set_ax(0x%04x)\n", (unsigned) val16));
+}
+
+ void
+fpu_verify_area(unsigned what, void *ptr, unsigned n)
+{
+ bx_segment_reg_t *seg;
+
+ seg = &fpu_cpu_ptr->sregs[fpu_iptr->seg];
+
+ if (what == VERIFY_READ) {
+ fpu_cpu_ptr->read_virtual_checks(seg, PTR2INT(ptr), n);
+ }
+ else { // VERIFY_WRITE
+ fpu_cpu_ptr->write_virtual_checks(seg, PTR2INT(ptr), n);
+ }
+//BX_DEBUG(( "verify_area: 0x%x\n", PTR2INT(ptr)));
+}
+
+
+ void
+FPU_printall(void)
+{
+ BX_PANIC(("FPU_printall\n"));
+}
+
+
+ unsigned
+fpu_get_user(void *ptr, unsigned len)
+{
+ Bit32u val32;
+ Bit16u val16;
+ Bit8u val8;
+
+ switch (len) {
+ case 1:
+ fpu_cpu_ptr->read_virtual_byte(fpu_iptr->seg, PTR2INT(ptr), &val8);
+ val32 = val8;
+ break;
+ case 2:
+ fpu_cpu_ptr->read_virtual_word(fpu_iptr->seg, PTR2INT(ptr), &val16);
+ val32 = val16;
+ break;
+ case 4:
+ fpu_cpu_ptr->read_virtual_dword(fpu_iptr->seg, PTR2INT(ptr), &val32);
+ break;
+ default:
+ BX_PANIC(("fpu_get_user: len=%u\n", len));
+ }
+ return(val32);
+}
+
+ void
+fpu_put_user(unsigned val, void *ptr, unsigned len)
+{
+ Bit32u val32;
+ Bit16u val16;
+ Bit8u val8;
+
+ switch (len) {
+ case 1:
+ val8 = val;
+ fpu_cpu_ptr->write_virtual_byte(fpu_iptr->seg, PTR2INT(ptr), &val8);
+ break;
+ case 2:
+ val16 = val;
+ fpu_cpu_ptr->write_virtual_word(fpu_iptr->seg, PTR2INT(ptr), &val16);
+ break;
+ case 4:
+ val32 = val;
+ fpu_cpu_ptr->write_virtual_dword(fpu_iptr->seg, PTR2INT(ptr), &val32);
+ break;
+ default:
+ BX_PANIC(("fpu_put_user: len=%u\n", len));
+ }
+}
+
+ void
+math_abort(struct info *info, unsigned int signal)
+{
+ UNUSED(info); // info is always passed NULL
+#if BX_CPU_LEVEL >= 4
+
+// values of signal:
+// SIGILL : opcodes which are illegal
+// SIGFPE : unmasked FP exception before WAIT or non-control instruction
+// SIGSEGV : access data beyond segment violation
+ switch (signal) {
+ case SIGFPE:
+ if (fpu_cpu_ptr->cr0.ne == 0) {
+ // MSDOS compatibility external interrupt (IRQ13)
+ BX_PANIC (("math_abort: MSDOS compatibility not supported yet\n"));
+ }
+ fpu_cpu_ptr->exception(BX_MF_EXCEPTION, 0, 0);
+ // execution does not reach here
+
+ case SIGILL:
+ BX_PANIC (("math_abort: SIGILL not implemented yet.\n"));
+ break;
+ case SIGSEGV:
+ BX_PANIC (("math_abort: SIGSEGV not implemented yet.\n"));
+ break;
+ }
+
+#else
+ UNUSED(signal);
+ BX_INFO(("math_abort: CPU<4 not supported yet\n"));
+#endif
+}
+
+ int
+printk(const char * fmt, ...)
+{
+ BX_INFO(("printk not complete: %s\n", fmt));
+ return(0); // for now
+}
--- /dev/null
+ .file "wm_shrx.S"
+/*---------------------------------------------------------------------------+
+ | wm_shrx.S |
+ | |
+ | 64 bit right shift functions |
+ | |
+ | Copyright (C) 1992,1995 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@jacobi.maths.monash.edu.au |
+ | |
+ | Call from C as: |
+ | unsigned FPU_shrx(void *arg1, unsigned arg2) |
+ | and |
+ | unsigned FPU_shrxs(void *arg1, unsigned arg2) |
+ | |
+ +---------------------------------------------------------------------------*/
+
+#include "fpu_emu.h"
+
+.text
+/*---------------------------------------------------------------------------+
+ | unsigned FPU_shrx(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function. |
+ | Fastest for small shifts. |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+
+ENTRY(FPU_shrx)
+ push %ebp
+ movl %esp,%ebp
+ pushl %esi
+ movl PARAM2,%ecx
+ movl PARAM1,%esi
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jnc L_more_than_31
+
+/* less than 32 bits */
+ pushl %ebx
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %eax,%eax /* extension */
+ shrd %cl,%ebx,%eax
+ shrd %cl,%edx,%ebx
+ shr %cl,%edx
+ movl %ebx,(%esi)
+ movl %edx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+L_more_than_31:
+ cmpl $64,%ecx
+ jnc L_more_than_63
+
+ subb $32,%cl
+ movl (%esi),%eax /* lsl */
+ movl 4(%esi),%edx /* msl */
+ shrd %cl,%edx,%eax
+ shr %cl,%edx
+ movl %edx,(%esi)
+ movl $0,4(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_63:
+ cmpl $96,%ecx
+ jnc L_more_than_95
+
+ subb $64,%cl
+ movl 4(%esi),%eax /* msl */
+ shr %cl,%eax
+ xorl %edx,%edx
+ movl %edx,(%esi)
+ movl %edx,4(%esi)
+ popl %esi
+ leave
+ ret
+
+L_more_than_95:
+ xorl %eax,%eax
+ movl %eax,(%esi)
+ movl %eax,4(%esi)
+ popl %esi
+ leave
+ ret
+
+
+/*---------------------------------------------------------------------------+
+ | unsigned FPU_shrxs(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function (optimized for small floating point |
+ | integers). |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | The lower 8 bits of eax are lost and replaced by a flag which is |
+ | set (to 0x01) if any bit, apart from the first one, is set in the |
+ | part which has been shifted out of the arg. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+ENTRY(FPU_shrxs)
+ push %ebp
+ movl %esp,%ebp
+ pushl %esi
+ pushl %ebx
+ movl PARAM2,%ecx
+ movl PARAM1,%esi
+ cmpl $64,%ecx /* shrd only works for 0..31 bits */
+ jnc Ls_more_than_63
+
+ cmpl $32,%ecx /* shrd only works for 0..31 bits */
+ jc Ls_less_than_32
+
+/* We got here without jumps by assuming that the most common requirement
+ is for small integers */
+/* Shift by [32..63] bits */
+ subb $32,%cl
+ movl (%esi),%eax /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %ebx,%ebx
+ shrd %cl,%eax,%ebx
+ shrd %cl,%edx,%eax
+ shr %cl,%edx
+ orl %ebx,%ebx /* test these 32 bits */
+ setne %bl
+ test $0x7fffffff,%eax /* and 31 bits here */
+ setne %bh
+ orw %bx,%bx /* Any of the 63 bit set ? */
+ setne %al
+ movl %edx,(%esi)
+ movl $0,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+/* Shift by [0..31] bits */
+Ls_less_than_32:
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%edx /* msl */
+ xorl %eax,%eax /* extension */
+ shrd %cl,%ebx,%eax
+ shrd %cl,%edx,%ebx
+ shr %cl,%edx
+ test $0x7fffffff,%eax /* only need to look at eax here */
+ setne %al
+ movl %ebx,(%esi)
+ movl %edx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+/* Shift by [64..95] bits */
+Ls_more_than_63:
+ cmpl $96,%ecx
+ jnc Ls_more_than_95
+
+ subb $64,%cl
+ movl (%esi),%ebx /* lsl */
+ movl 4(%esi),%eax /* msl */
+ xorl %edx,%edx /* extension */
+ shrd %cl,%ebx,%edx
+ shrd %cl,%eax,%ebx
+ shr %cl,%eax
+ orl %ebx,%edx
+ setne %bl
+ test $0x7fffffff,%eax /* only need to look at eax here */
+ setne %bh
+ orw %bx,%bx
+ setne %al
+ xorl %edx,%edx
+ movl %edx,(%esi) /* set to zero */
+ movl %edx,4(%esi) /* set to zero */
+ popl %ebx
+ popl %esi
+ leave
+ ret
+
+Ls_more_than_95:
+/* Shift by [96..inf) bits */
+ xorl %eax,%eax
+ movl (%esi),%ebx
+ orl 4(%esi),%ebx
+ setne %al
+ xorl %ebx,%ebx
+ movl %ebx,(%esi)
+ movl %ebx,4(%esi)
+ popl %ebx
+ popl %esi
+ leave
+ ret
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | wm_shrx.c |
+ | |
+ | 64 bit right shift functions |
+ | |
+ | Copyright (C) 1992,1995,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | unsigned FPU_shrx(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function. |
+ | Fastest for small shifts. |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+
+
+#include "fpu_emu.h"
+
+unsigned FPU_shrx(void *arg1, u32 arg2)
+{
+ u32 x;
+
+ if ( arg2 >= 64 )
+ {
+ if ( arg2 >= 96 )
+ {
+ *(u64 *)arg1 = 0;
+ return 0;
+ }
+ arg2 -= 64;
+ x = (*(u64 *)arg1) >> 32;
+ *(u64 *)arg1 = 0;
+
+ if ( arg2 )
+ return x >> arg2;
+ else
+ return x;
+ }
+
+ if ( arg2 < 32 )
+ {
+ if ( arg2 == 0 )
+ return 0;
+
+ x = (*(u64 *)arg1) << (32 - arg2);
+ }
+ else if ( arg2 > 32 )
+ {
+ x = (*(u64 *)arg1) >> (arg2 - 32);
+ }
+ else
+ {
+ /* arg2 == 32 */
+ x = *(u64 *)arg1;
+ }
+
+ (*(u64 *)arg1) >>= arg2;
+
+ return x;
+
+}
+
+
+/*---------------------------------------------------------------------------+
+ | unsigned FPU_shrxs(void *arg1, unsigned arg2) |
+ | |
+ | Extended shift right function (optimized for small floating point |
+ | integers). |
+ | Shifts the 64 bit quantity pointed to by the first arg (arg1) |
+ | right by the number of bits specified by the second arg (arg2). |
+ | Forms a 96 bit quantity from the 64 bit arg and eax: |
+ | [ 64 bit arg ][ eax ] |
+ | shift right ---------> |
+ | The eax register is initialized to 0 before the shifting. |
+ | The lower 8 bits of eax are lost and replaced by a flag which is |
+ | set (to 0x01) if any bit, apart from the first one, is set in the |
+ | part which has been shifted out of the arg. |
+ | Results returned in the 64 bit arg and eax. |
+ +---------------------------------------------------------------------------*/
+
+unsigned FPU_shrxs(void *arg1, u32 arg2)
+{
+ u32 x, bits;
+ u64 lost;
+
+ if ( arg2 >= 64 )
+ {
+ if ( arg2 >= 96 )
+ {
+ bits = *(u64 *)arg1 != 0;
+ *(u64 *)arg1 = 0;
+ return bits ? 1 : 0;
+ }
+ arg2 -= 64;
+ lost = (*(u64 *)arg1) << (32 - arg2);
+ x = (*(u64 *)arg1) >> 32;
+ *(u64 *)arg1 = 0;
+
+ if ( arg2 )
+ x >>= arg2;
+
+ if ( lost )
+ x |= 1;
+
+ return x;
+ }
+
+ if ( arg2 < 32 )
+ {
+ if ( arg2 == 0 )
+ /* No bits are lost */
+ return 0;
+
+ /* No bits are lost */
+ x = (*(u64 *)arg1) << (32 - arg2);
+ }
+ else if ( arg2 > 32 )
+ {
+ bits = (*(u64 *)arg1);
+ bits <<= (64 - arg2);
+ x = (*(u64 *)arg1) >> (arg2 - 32);
+ if ( bits )
+ x |= 1;
+ }
+ else
+ {
+ /* arg2 == 32 */
+ /* No bits are lost */
+ x = *(u64 *)arg1;
+ }
+
+ (*(u64 *)arg1) >>= arg2;
+
+ if ( x & 0x7fffffff )
+ x |= 1;
+
+ return x;
+
+}
+
--- /dev/null
+ .file "wm_sqrt.S"
+/*---------------------------------------------------------------------------+
+ | wm_sqrt.S |
+ | |
+ | Fixed point arithmetic square root evaluation. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@suburbia.net |
+ | |
+ | Call from C as: |
+ | int wm_sqrt(FPU_REG *n, unsigned int control_word) |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | wm_sqrt(FPU_REG *n, unsigned int control_word) |
+ | returns the square root of n in n. |
+ | |
+ | Use Newton's method to compute the square root of a number, which must |
+ | be in the range [1.0 .. 4.0), to 64 bits accuracy. |
+ | Does not check the sign or tag of the argument. |
+ | Sets the exponent, but not the sign or tag of the result. |
+ | |
+ | The guess is kept in %esi:%edi |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+
+#ifndef NON_REENTRANT_FPU
+/* Local storage on the stack: */
+#define FPU_accum_3 -4(%ebp) /* ms word */
+#define FPU_accum_2 -8(%ebp)
+#define FPU_accum_1 -12(%ebp)
+#define FPU_accum_0 -16(%ebp)
+
+/*
+ * The de-normalised argument:
+ * sq_2 sq_1 sq_0
+ * b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0
+ * ^ binary point here
+ */
+#define FPU_fsqrt_arg_2 -20(%ebp) /* ms word */
+#define FPU_fsqrt_arg_1 -24(%ebp)
+#define FPU_fsqrt_arg_0 -28(%ebp) /* ls word, at most the ms bit is set */
+
+#else
+/* Local storage in a static area: */
+.data
+ .align 4,0
+FPU_accum_3:
+ .long 0 /* ms word */
+FPU_accum_2:
+ .long 0
+FPU_accum_1:
+ .long 0
+FPU_accum_0:
+ .long 0
+
+/* The de-normalised argument:
+ sq_2 sq_1 sq_0
+ b b b b b b b ... b b b b b b .... b b b b 0 0 0 ... 0
+ ^ binary point here
+ */
+FPU_fsqrt_arg_2:
+ .long 0 /* ms word */
+FPU_fsqrt_arg_1:
+ .long 0
+FPU_fsqrt_arg_0:
+ .long 0 /* ls word, at most the ms bit is set */
+#endif /* NON_REENTRANT_FPU */
+
+
+.text
+ENTRY(wm_sqrt)
+ pushl %ebp
+ movl %esp,%ebp
+#ifndef NON_REENTRANT_FPU
+ subl $28,%esp
+#endif /* NON_REENTRANT_FPU */
+ pushl %esi
+ pushl %edi
+ pushl %ebx
+
+ movl PARAM1,%esi
+
+ movl SIGH(%esi),%eax
+ movl SIGL(%esi),%ecx
+ xorl %edx,%edx
+
+/* We use a rough linear estimate for the first guess.. */
+
+ cmpw EXP_BIAS,EXP(%esi)
+ jnz sqrt_arg_ge_2
+
+ shrl $1,%eax /* arg is in the range [1.0 .. 2.0) */
+ rcrl $1,%ecx
+ rcrl $1,%edx
+
+sqrt_arg_ge_2:
+/* From here on, n is never accessed directly again until it is
+ replaced by the answer. */
+
+ movl %eax,FPU_fsqrt_arg_2 /* ms word of n */
+ movl %ecx,FPU_fsqrt_arg_1
+ movl %edx,FPU_fsqrt_arg_0
+
+/* Make a linear first estimate */
+ shrl $1,%eax
+ addl $0x40000000,%eax
+ movl $0xaaaaaaaa,%ecx
+ mull %ecx
+ shll %edx /* max result was 7fff... */
+ testl $0x80000000,%edx /* but min was 3fff... */
+ jnz sqrt_prelim_no_adjust
+
+ movl $0x80000000,%edx /* round up */
+
+sqrt_prelim_no_adjust:
+ movl %edx,%esi /* Our first guess */
+
+/* We have now computed (approx) (2 + x) / 3, which forms the basis
+ for a few iterations of Newton's method */
+
+ movl FPU_fsqrt_arg_2,%ecx /* ms word */
+
+/*
+ * From our initial estimate, three iterations are enough to get us
+ * to 30 bits or so. This will then allow two iterations at better
+ * precision to complete the process.
+ */
+
+/* Compute (g + n/g)/2 at each iteration (g is the guess). */
+ shrl %ecx /* Doing this first will prevent a divide */
+ /* overflow later. */
+
+ movl %ecx,%edx /* msw of the arg / 2 */
+ divl %esi /* current estimate */
+ shrl %esi /* divide by 2 */
+ addl %eax,%esi /* the new estimate */
+
+ movl %ecx,%edx
+ divl %esi
+ shrl %esi
+ addl %eax,%esi
+
+ movl %ecx,%edx
+ divl %esi
+ shrl %esi
+ addl %eax,%esi
+
+/*
+ * Now that an estimate accurate to about 30 bits has been obtained (in %esi),
+ * we improve it to 60 bits or so.
+ *
+ * The strategy from now on is to compute new estimates from
+ * guess := guess + (n - guess^2) / (2 * guess)
+ */
+
+/* First, find the square of the guess */
+ movl %esi,%eax
+ mull %esi
+/* guess^2 now in %edx:%eax */
+
+ movl FPU_fsqrt_arg_1,%ecx
+ subl %ecx,%eax
+ movl FPU_fsqrt_arg_2,%ecx /* ms word of normalized n */
+ sbbl %ecx,%edx
+ jnc sqrt_stage_2_positive
+
+/* Subtraction gives a negative result,
+ negate the result before division. */
+ notl %edx
+ notl %eax
+ addl $1,%eax
+ adcl $0,%edx
+
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+ jmp sqrt_stage_2_finish
+
+sqrt_stage_2_positive:
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ notl %ecx
+ notl %eax
+ addl $1,%eax
+ adcl $0,%ecx
+
+sqrt_stage_2_finish:
+ sarl $1,%ecx /* divide by 2 */
+ rcrl $1,%eax
+
+ /* Form the new estimate in %esi:%edi */
+ movl %eax,%edi
+ addl %ecx,%esi
+
+ jnz sqrt_stage_2_done /* result should be [1..2) */
+
+#ifdef PARANOID
+/* It should be possible to get here only if the arg is ffff....ffff */
+ cmp $0xffffffff,FPU_fsqrt_arg_1
+ jnz sqrt_stage_2_error
+#endif /* PARANOID */
+
+/* The best rounded result. */
+ xorl %eax,%eax
+ decl %eax
+ movl %eax,%edi
+ movl %eax,%esi
+ movl $0x7fffffff,%eax
+ jmp sqrt_round_result
+
+#ifdef PARANOID
+sqrt_stage_2_error:
+ pushl EX_INTERNAL|0x213
+ call EXCEPTION
+#endif /* PARANOID */
+
+sqrt_stage_2_done:
+
+/* Now the square root has been computed to better than 60 bits. */
+
+/* Find the square of the guess. */
+ movl %edi,%eax /* ls word of guess */
+ mull %edi
+ movl %edx,FPU_accum_1
+
+ movl %esi,%eax
+ mull %esi
+ movl %edx,FPU_accum_3
+ movl %eax,FPU_accum_2
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,FPU_accum_1
+ adcl %edx,FPU_accum_2
+ adcl $0,FPU_accum_3
+
+/* movl %esi,%eax */
+/* mull %edi */
+ addl %eax,FPU_accum_1
+ adcl %edx,FPU_accum_2
+ adcl $0,FPU_accum_3
+
+/* guess^2 now in FPU_accum_3:FPU_accum_2:FPU_accum_1 */
+
+ movl FPU_fsqrt_arg_0,%eax /* get normalized n */
+ subl %eax,FPU_accum_1
+ movl FPU_fsqrt_arg_1,%eax
+ sbbl %eax,FPU_accum_2
+ movl FPU_fsqrt_arg_2,%eax /* ms word of normalized n */
+ sbbl %eax,FPU_accum_3
+ jnc sqrt_stage_3_positive
+
+/* Subtraction gives a negative result,
+ negate the result before division */
+ notl FPU_accum_1
+ notl FPU_accum_2
+ notl FPU_accum_3
+ addl $1,FPU_accum_1
+ adcl $0,FPU_accum_2
+
+#ifdef PARANOID
+ adcl $0,FPU_accum_3 /* This must be zero */
+ jz sqrt_stage_3_no_error
+
+sqrt_stage_3_error:
+ pushl EX_INTERNAL|0x207
+ call EXCEPTION
+
+sqrt_stage_3_no_error:
+#endif /* PARANOID */
+
+ movl FPU_accum_2,%edx
+ movl FPU_accum_1,%eax
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ sarl $1,%ecx /* divide by 2 */
+ rcrl $1,%eax
+
+ /* prepare to round the result */
+
+ addl %ecx,%edi
+ adcl $0,%esi
+
+ jmp sqrt_stage_3_finished
+
+sqrt_stage_3_positive:
+ movl FPU_accum_2,%edx
+ movl FPU_accum_1,%eax
+ divl %esi
+ movl %eax,%ecx
+
+ movl %edx,%eax
+ divl %esi
+
+ sarl $1,%ecx /* divide by 2 */
+ rcrl $1,%eax
+
+ /* prepare to round the result */
+
+ notl %eax /* Negate the correction term */
+ notl %ecx
+ addl $1,%eax
+ adcl $0,%ecx /* carry here ==> correction == 0 */
+ adcl $0xffffffff,%esi
+
+ addl %ecx,%edi
+ adcl $0,%esi
+
+sqrt_stage_3_finished:
+
+/*
+ * The result in %esi:%edi:%eax should be good to about 90 bits here,
+ * and the rounding information here does not have sufficient accuracy
+ * in a few rare cases.
+ */
+ cmpl $0xffffffe0,%eax
+ ja sqrt_near_exact_x
+
+ cmpl $0x00000020,%eax
+ jb sqrt_near_exact
+
+ cmpl $0x7fffffe0,%eax
+ jb sqrt_round_result
+
+ cmpl $0x80000020,%eax
+ jb sqrt_get_more_precision
+
+sqrt_round_result:
+/* Set up for rounding operations */
+ movl %eax,%edx
+ movl %esi,%eax
+ movl %edi,%ebx
+ movl PARAM1,%edi
+ movw EXP_BIAS,EXP(%edi) /* Result is in [1.0 .. 2.0) */
+ jmp fpu_reg_round
+
+
+sqrt_near_exact_x:
+/* First, the estimate must be rounded up. */
+ addl $1,%edi
+ adcl $0,%esi
+
+sqrt_near_exact:
+/*
+ * This is an easy case because x^1/2 is monotonic.
+ * We need just find the square of our estimate, compare it
+ * with the argument, and deduce whether our estimate is
+ * above, below, or exact. We use the fact that the estimate
+ * is known to be accurate to about 90 bits.
+ */
+ movl %edi,%eax /* ls word of guess */
+ mull %edi
+ movl %edx,%ebx /* 2nd ls word of square */
+ movl %eax,%ecx /* ls word of square */
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,%ebx
+ addl %eax,%ebx
+
+#ifdef PARANOID
+ cmp $0xffffffb0,%ebx
+ jb sqrt_near_exact_ok
+
+ cmp $0x00000050,%ebx
+ ja sqrt_near_exact_ok
+
+ pushl EX_INTERNAL|0x214
+ call EXCEPTION
+
+sqrt_near_exact_ok:
+#endif /* PARANOID */
+
+ or %ebx,%ebx
+ js sqrt_near_exact_small
+
+ jnz sqrt_near_exact_large
+
+ or %ebx,%edx
+ jnz sqrt_near_exact_large
+
+/* Our estimate is exactly the right answer */
+ xorl %eax,%eax
+ jmp sqrt_round_result
+
+sqrt_near_exact_small:
+/* Our estimate is too small */
+ movl $0x000000ff,%eax
+ jmp sqrt_round_result
+
+sqrt_near_exact_large:
+/* Our estimate is too large, we need to decrement it */
+ subl $1,%edi
+ sbbl $0,%esi
+ movl $0xffffff00,%eax
+ jmp sqrt_round_result
+
+
+sqrt_get_more_precision:
+/* This case is almost the same as the above, except we start
+ with an extra bit of precision in the estimate. */
+ stc /* The extra bit. */
+ rcll $1,%edi /* Shift the estimate left one bit */
+ rcll $1,%esi
+
+ movl %edi,%eax /* ls word of guess */
+ mull %edi
+ movl %edx,%ebx /* 2nd ls word of square */
+ movl %eax,%ecx /* ls word of square */
+
+ movl %edi,%eax
+ mull %esi
+ addl %eax,%ebx
+ addl %eax,%ebx
+
+/* Put our estimate back to its original value */
+ stc /* The ms bit. */
+ rcrl $1,%esi /* Shift the estimate left one bit */
+ rcrl $1,%edi
+
+#ifdef PARANOID
+ cmp $0xffffff60,%ebx
+ jb sqrt_more_prec_ok
+
+ cmp $0x000000a0,%ebx
+ ja sqrt_more_prec_ok
+
+ pushl EX_INTERNAL|0x215
+ call EXCEPTION
+
+sqrt_more_prec_ok:
+#endif /* PARANOID */
+
+ or %ebx,%ebx
+ js sqrt_more_prec_small
+
+ jnz sqrt_more_prec_large
+
+ or %ebx,%ecx
+ jnz sqrt_more_prec_large
+
+/* Our estimate is exactly the right answer */
+ movl $0x80000000,%eax
+ jmp sqrt_round_result
+
+sqrt_more_prec_small:
+/* Our estimate is too small */
+ movl $0x800000ff,%eax
+ jmp sqrt_round_result
+
+sqrt_more_prec_large:
+/* Our estimate is too large */
+ movl $0x7fffff00,%eax
+ jmp sqrt_round_result
--- /dev/null
+/*---------------------------------------------------------------------------+
+ | wm_sqrt.c |
+ | |
+ | Fixed point arithmetic square root evaluation. |
+ | |
+ | Copyright (C) 1992,1993,1995,1997,1999 |
+ | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
+ | Australia. E-mail billm@melbpc.org.au |
+ | |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
+ | returns the square root of n in n. |
+ | |
+ | Use Newton's method to compute the square root of a number, which must |
+ | be in the range [1.0 .. 4.0), to 64 bits accuracy. |
+ | Does not check the sign or tag of the argument. |
+ | Sets the exponent, but not the sign or tag of the result. |
+ | |
+ | The guess is kept in %esi:%edi |
+ +---------------------------------------------------------------------------*/
+
+#include "exception.h"
+#include "fpu_emu.h"
+
+/*
+ The following value indicates the trailing bits (of 96 bits)
+ which may be in error when the final Newton iteration is finished
+ (0x20 corresponds to the last 5 bits in error, i.e. 91 bits precision).
+ A check of the following code with more than 3 billion (3.0e9) random
+ and selected values showed that 0x10 was always a large enough value,
+ so 0x20 should be a conservative choice.
+ */
+#define ERR_MARGIN 0x20
+
+
+int wm_sqrt(FPU_REG *n, s32 dummy1, s32 dummy2, u16 control_w, u8 sign)
+{
+ u64 nn, guess, halfn, lowr, mid, upr, diff, uwork;
+ s64 work;
+ u32 ne, guess32, work32, diff32, mid32;
+ int shifted;
+
+ nn = significand(n);
+ ne = 0;
+ if ( exponent16(n) == EXP_BIAS )
+ {
+ /* Shift the argument right one position. */
+ if ( nn & 1 )
+ ne = 0x80000000;
+ nn >>= 1;
+ guess = n->sigh >> 2;
+ shifted = 1;
+ }
+ else
+ {
+ guess = n->sigh >> 1;
+ shifted = 0;
+ }
+
+ guess += 0x40000000;
+ guess *= 0xaaaaaaaa;
+ guess <<= 1;
+ guess32 = guess >> 32;
+ if ( !(guess32 & 0x80000000) )
+ guess32 = 0x80000000;
+ halfn = nn >> 1;
+
+ guess32 = halfn / guess32 + (guess32 >> 1);
+ guess32 = halfn / guess32 + (guess32 >> 1);
+ guess32 = halfn / guess32 + (guess32 >> 1);
+
+
+/*
+ * Now that an estimate accurate to about 30 bits has been obtained,
+ * we improve it to 60 bits or so.
+ *
+ * The strategy from now on is to compute new estimates from
+ * guess := guess + (n - guess^2) / (2 * guess)
+ */
+
+ work = guess32;
+ work = nn - work * guess32;
+ work <<= 28; /* 29 - 1 */
+ work /= guess32;
+ work <<= 3; /* 29 + 3 = 32 */
+ work += ((u64)guess32) << 32;
+
+ if ( work == 0 ) /* This happens in one or two special cases */
+ work = BX_CONST64(0xffffffffffffffff);
+
+ guess = work;
+
+ /* guess is now accurate to about 60 bits */
+
+
+ if ( work > 0 )
+ {
+#ifdef PARANOID
+ if ( (n->sigh != 0xffffffff) && (n->sigl != 0xffffffff) )
+ {
+ EXCEPTION(EX_INTERNAL|0x213);
+ }
+#endif
+ /* We know the answer here. */
+ return FPU_round(n, 0x7fffffff, 0, control_w, sign);
+ }
+
+ /* Refine the guess to significantly more than 64 bits. */
+
+ /* First, square the current guess. */
+
+ guess32 = guess >> 32;
+ work32 = guess;
+
+ /* lower 32 times lower 32 */
+ lowr = work32;
+ lowr *= work32;
+
+ /* lower 32 times upper 32 */
+ mid = guess32;
+ mid *= work32;
+
+ /* upper 32 times upper 32 */
+ upr = guess32;
+ upr *= guess32;
+
+ /* upper 32 bits of the middle product times 2 */
+ upr += mid >> (32-1);
+
+ /* lower 32 bits of the middle product times 2 */
+ work32 = mid << 1;
+
+ /* upper 32 bits of the lower product */
+ mid32 = lowr >> 32;
+ mid32 += work32;
+ if ( mid32 < work32 )
+ upr ++;
+
+ /* We now have the first 96 bits (truncated) of the square of the guess */
+
+ diff = upr - nn;
+ diff32 = mid32 - ne;
+ if ( diff32 > mid32 )
+ diff --;
+
+ if ( ((s64)diff) < 0 )
+ {
+ /* The difference is negative, negate it. */
+ diff32 = -((s32)diff32);
+ diff = ~diff;
+ if ( diff32 == 0 )
+ diff ++;
+#ifdef PARANOID
+ if ( (diff >> 32) != 0 )
+ {
+ EXCEPTION(EX_INTERNAL|0x207);
+ }
+#endif
+
+ diff <<= 32;
+ diff |= diff32;
+ work32 = diff / guess32;
+ work = work32;
+ work <<= 32;
+
+ diff = diff % guess32;
+ diff <<= 32;
+ work32 = diff / guess32;
+
+ work |= work32;
+
+ work >>= 1;
+ work32 = work >> 32;
+
+
+ guess += work32; /* The first 64 bits */
+ guess32 = work; /* The next 32 bits */
+ /* The guess should now be good to about 90 bits */
+ }
+ else
+ {
+ /* The difference is positive. */
+ diff <<= 32;
+ diff |= diff32;
+
+ work32 = diff / guess32;
+ work = work32;
+ work <<= 32;
+
+ diff = diff % guess32;
+ diff <<= 32;
+ work32 = diff / guess32;
+
+ work |= work32;
+
+ work >>= 1;
+ work32 = work >> 32;
+
+ guess32 = work; /* The last 32 bits (of 96) */
+ guess32 = -guess32;
+ if ( guess32 )
+ guess --;
+ guess -= work32; /* The first 64 bits */
+ /* The guess should now be good to about 90 bits */
+ }
+
+
+ setexponent16(n, 0);
+
+ if ( guess32 >= (u32) -ERR_MARGIN )
+ {
+ /* Nearly exact, we round the 64 bit result upward. */
+ guess ++;
+ }
+ else if ( (guess32 > ERR_MARGIN) &&
+ ((guess32 < 0x80000000-ERR_MARGIN)
+ || (guess32 > 0x80000000+ERR_MARGIN)) )
+ {
+ /* We have enough accuracy to decide rounding */
+ significand(n) = guess;
+ return FPU_round(n, guess32, 0, control_w, sign);
+ }
+
+ if ( (guess32 <= ERR_MARGIN) || (guess32 >= (u32) -ERR_MARGIN) )
+ {
+ /*
+ * This is an easy case because x^1/2 is monotonic.
+ * We need just find the square of our estimate, compare it
+ * with the argument, and deduce whether our estimate is
+ * above, below, or exact. We use the fact that the estimate
+ * is known to be accurate to about 90 bits.
+ */
+
+
+ /* We compute the lower 64 bits of the 128 bit product */
+ work32 = guess;
+ lowr = work32;
+ lowr *= work32;
+
+ uwork = guess >> 32;
+ work32 = guess;
+ uwork *= work32;
+ uwork <<= 33; /* 33 = 32+1 (for two times the product) */
+
+ lowr += uwork; /* We now have the 64 bits */
+
+ /* We need only look at bits 65..96 of the square of guess. */
+ if ( shifted )
+ work32 = lowr >> 31;
+ else
+ work32 = lowr >> 32;
+
+#ifdef PARANOID
+ if ( ((s32)work32 > 3*ERR_MARGIN) || ((s32)work32 < -3*ERR_MARGIN) )
+ {
+ EXCEPTION(EX_INTERNAL|0x214);
+ }
+#endif
+
+ significand(n) = guess;
+ if ( (s32)work32 > 0 )
+ {
+ /* guess is too large */
+ significand(n) --;
+ return FPU_round(n, 0xffffff00, 0, control_w, sign);
+ }
+ else if ( (s32)work32 < 0 )
+ {
+ /* guess is a little too small */
+ return FPU_round(n, 0x000000ff, 0, control_w, sign);
+ }
+
+ else if ( (u32)lowr != 0 )
+ {
+
+ /* guess is too large */
+ significand(n) --;
+ return FPU_round(n, 0xffffff00, 0, control_w, sign);
+ }
+
+ /* Our guess is precise. */
+ return FPU_round(n, 0, 0, control_w, sign);
+ }
+
+ /* Very similar to the case above, but the last bit is near 0.5.
+ We handle this just like the case above but we shift everything
+ by one bit. */
+
+
+ uwork = guess;
+ uwork <<= 1;
+ uwork |= 1; /* add the half bit */
+
+ /* We compute the lower 64 bits of the 128 bit product */
+ work32 = uwork;
+ lowr = work32;
+ lowr *= work32;
+
+ work32 = uwork >> 32;
+ uwork &= 0xffffffff;
+ uwork *= work32;
+ uwork <<= 33; /* 33 = 32+1 (for two times the product) */
+
+ lowr += uwork; /* We now have the 64 bits. The lowest 32 bits of lowr
+ are not all zero (the lsb is 1). */
+
+ /* We need only look at bits 65..96 of the square of guess. */
+ if ( shifted )
+ work32 = lowr >> 31;
+ else
+ work32 = lowr >> 32;
+
+#ifdef PARANOID
+ if ( ((s32)work32 > 4*3*ERR_MARGIN) || ((s32)work32 < -4*3*ERR_MARGIN) )
+ {
+ EXCEPTION(EX_INTERNAL|0x215);
+ }
+#endif
+
+ significand(n) = guess;
+ if ( (s32)work32 < 0 )
+ {
+ /* guess plus half bit is a little too small */
+ return FPU_round(n, 0x800000ff, 0, control_w, sign);
+ }
+ else /* Note that the lower 64 bits of the product are not all zero */
+ {
+ /* guess plus half bit is too large */
+ return FPU_round(n, 0x7fffff00, 0, control_w, sign);
+ }
+
+ /*
+ Note that the result of a square root cannot have precisely a half bit
+ of a least significant place (it is left as an exercise for the reader
+ to prove this! (hint: 65 bit*65 bit => n bits)).
+ */
+
+}
+
--- /dev/null
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+// possible types passed to BX_INSTR_TLB_CNTRL()
+#define BX_INSTR_MOV_CR3 10
+#define BX_INSTR_INVLPG 11
+#define BX_INSTR_TASKSWITCH 12
+
+// possible types passed to BX_INSTR_CACHE_CNTRL()
+#define BX_INSTR_INVD 20
+#define BX_INSTR_WBINVD 21
+
+
+
+#if BX_INSTRUMENTATION
+
+#define BX_INSTR_IS_CALL 10
+#define BX_INSTR_IS_RET 11
+#define BX_INSTR_IS_IRET 12
+#define BX_INSTR_IS_JMP 13
+#define BX_INSTR_IS_INT 14
+
+
+// called from the CPU core
+void bx_instr_cnear_branch_taken(Bit32u new_eip);
+void bx_instr_cnear_branch_not_taken(void);
+void bx_instr_ucnear_branch(unsigned what, Bit32u new_eip);
+void bx_instr_far_branch(unsigned what, Bit32u new_cs, Bit32u new_eip);
+void bx_instr_opcode_byte1(Bit8u);
+void bx_instr_opcode_byte2(Bit8u);
+void bx_instr_opcode_g1ebib(unsigned nnn);
+void bx_instr_opcode_g1eviv(unsigned nnn);
+void bx_instr_opcode_g1evib(unsigned nnn);
+void bx_instr_opcode_g2ebib(unsigned nnn);
+void bx_instr_opcode_g2evib(unsigned nnn);
+void bx_instr_opcode_g2eb1(unsigned nnn);
+void bx_instr_opcode_g2ev1(unsigned nnn);
+void bx_instr_opcode_g2ebcl(unsigned nnn);
+void bx_instr_opcode_g2evcl(unsigned nnn);
+void bx_instr_opcode_g3eb(unsigned nnn);
+void bx_instr_opcode_g3ev(unsigned nnn);
+void bx_instr_opcode_g4(unsigned nnn);
+void bx_instr_opcode_g5(unsigned nnn);
+void bx_instr_opcode_g6(unsigned nnn);
+void bx_instr_opcode_g7(unsigned nnn);
+void bx_instr_opcode_g8evib(unsigned nnn);
+void bx_instr_mem_code(Bit32u linear, unsigned size);
+void bx_instr_mem_data(Bit32u linear, unsigned size, unsigned rw);
+void bx_instr_opcode_begin(Bit32u linear);
+void bx_instr_opcode_end(Bit32u linear);
+void bx_instr_fetch_byte(Bit8u val8);
+void bx_instr_fetch_word(Bit16u val16);
+void bx_instr_fetch_dword(Bit32u val32);
+void bx_instr_phy_write(Bit32u addr, unsigned len);
+void bx_instr_phy_read(Bit32u addr, unsigned len);
+void bx_instr_interrupt(unsigned vector);
+void bx_instr_exception(unsigned vector);
+void bx_instr_inp(Bit16u addr, unsigned len);
+void bx_instr_outp(Bit16u addr, unsigned len);
+void bx_instr_tlb_cntrl(unsigned what, Bit32u newval);
+void bx_instr_cache_cntrl(unsigned what);
+void bx_instr_hwinterrupt(unsigned vector, Bit32u cs, Bit32u eip);
+void bx_instr_init(void);
+void bx_instr_shutdown(void);
+void bx_instr_opcode_repeating(void);
+void bx_instr_prefix_as(void);
+void bx_instr_prefix_os(void);
+void bx_instr_prefix_rep(void);
+void bx_instr_prefix_repne(void);
+void bx_instr_prefix_lock(void);
+void bx_instr_prefix_cs(void);
+void bx_instr_prefix_ss(void);
+void bx_instr_prefix_ds(void);
+void bx_instr_prefix_es(void);
+void bx_instr_prefix_fs(void);
+void bx_instr_prefix_gs(void);
+void bx_instr_modrm32(unsigned modrm);
+void bx_instr_sib32(unsigned sib);
+void bx_instr_modrm16(unsigned modrm);
+void bx_instr_iret(void);
+void bx_instr_debug_prompt(void);
+void bx_instr_lin_read(Bit32u lin, Bit32u phy, unsigned len);
+void bx_instr_lin_write(Bit32u lin, Bit32u phy, unsigned len);
+
+// called from the debug prompt
+void bx_instr_start(void);
+void bx_instr_stop(void);
+void bx_instr_reset(void);
+void bx_instr_print(void);
+
+# define BX_INSTR_INIT() bx_instr_init()
+# define BX_INSTR_SHUTDOWN() bx_instr_shutdown()
+# define BX_INSTR_CNEAR_BRANCH_TAKEN(new_eip) bx_instr_cnear_branch_taken(new_eip)
+# define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN() bx_instr_cnear_branch_not_taken()
+# define BX_INSTR_UCNEAR_BRANCH(what, new_eip) bx_instr_ucnear_branch(what, new_eip)
+# define BX_INSTR_FAR_BRANCH(what, new_cs, new_eip) bx_instr_far_branch(what, new_cs, new_eip)
+# define BX_INSTR_OPCODE_BEGIN(linear) bx_instr_opcode_begin(linear)
+# define BX_INSTR_OPCODE_END(linear) bx_instr_opcode_end(linear)
+# define BX_INSTR_OPCODE_BYTE1(b) bx_instr_opcode_byte1(b)
+# define BX_INSTR_OPCODE_BYTE2(b) bx_instr_opcode_byte2(b)
+# define BX_INSTR_OPCODE_G1EbIb(nnn) bx_instr_opcode_g1ebib(nnn)
+# define BX_INSTR_OPCODE_G1EvIv(nnn) bx_instr_opcode_g1eviv(nnn)
+# define BX_INSTR_OPCODE_G1EvIb(nnn) bx_instr_opcode_g1evib(nnn)
+# define BX_INSTR_OPCODE_G2EbIb(nnn) bx_instr_opcode_g2ebib(nnn)
+# define BX_INSTR_OPCODE_G2EvIb(nnn) bx_instr_opcode_g2evib(nnn)
+# define BX_INSTR_OPCODE_G2Eb1(nnn) bx_instr_opcode_g2eb1(nnn)
+# define BX_INSTR_OPCODE_G2Ev1(nnn) bx_instr_opcode_g2ev1(nnn)
+# define BX_INSTR_OPCODE_G2EbCL(nnn) bx_instr_opcode_g2ebcl(nnn)
+# define BX_INSTR_OPCODE_G2EvCL(nnn) bx_instr_opcode_g2evcl(nnn)
+# define BX_INSTR_OPCODE_G3Eb(nnn) bx_instr_opcode_g3eb(nnn)
+# define BX_INSTR_OPCODE_G3Ev(nnn) bx_instr_opcode_g3ev(nnn)
+# define BX_INSTR_OPCODE_G4(nnn) bx_instr_opcode_g4(nnn)
+# define BX_INSTR_OPCODE_G5(nnn) bx_instr_opcode_g5(nnn)
+# define BX_INSTR_OPCODE_G6(nnn) bx_instr_opcode_g6(nnn)
+# define BX_INSTR_OPCODE_G7(nnn) bx_instr_opcode_g7(nnn)
+# define BX_INSTR_OPCODE_G8EvIb(nnn) bx_instr_opcode_g8evib(nnn)
+# define BX_INSTR_MEM_CODE(linear, size) bx_instr_mem_code(linear, size)
+# define BX_INSTR_MEM_DATA(linear, size, rw) bx_instr_mem_data(linear, size, rw)
+# define BX_INSTR_EXCEPTION(vector) bx_instr_exception(vector)
+# define BX_INSTR_INP(addr, len) bx_instr_inp(addr, len)
+# define BX_INSTR_OUTP(addr, len) bx_instr_outp(addr, len)
+# define BX_INSTR_FETCH_BYTE(val8) bx_instr_fetch_byte(val8)
+# define BX_INSTR_FETCH_WORD(val16) bx_instr_fetch_word(val16)
+# define BX_INSTR_FETCH_DWORD(val32) bx_instr_fetch_dword(val32)
+# define BX_INSTR_PHY_WRITE(addr, len) bx_instr_phy_write(addr, len)
+# define BX_INSTR_PHY_READ(addr, len) bx_instr_phy_read(addr, len)
+# define BX_INSTR_INTERRUPT(vector) bx_instr_interrupt(vector)
+
+# define BX_INSTR_TLB_CNTRL(what, newval) bx_instr_tlb_cntrl(what, newval)
+# define BX_INSTR_CACHE_CNTRL(what) bx_instr_cache_cntrl(what)
+# define BX_INSTR_HWINTERRUPT(vector, cs, eip) bx_instr_hwinterrupt(vector, cs, eip)
+# define BX_INSTR_OPCODE_REPEATING() bx_instr_opcode_repeating()
+
+# define BX_INSTR_PREFIX_AS() bx_instr_prefix_as()
+# define BX_INSTR_PREFIX_OS() bx_instr_prefix_os()
+# define BX_INSTR_PREFIX_REP() bx_instr_prefix_rep()
+# define BX_INSTR_PREFIX_REPNE() bx_instr_prefix_repne()
+# define BX_INSTR_PREFIX_LOCK() bx_instr_prefix_lock()
+# define BX_INSTR_PREFIX_CS() bx_instr_prefix_cs()
+# define BX_INSTR_PREFIX_SS() bx_instr_prefix_ss()
+# define BX_INSTR_PREFIX_DS() bx_instr_prefix_ds()
+# define BX_INSTR_PREFIX_ES() bx_instr_prefix_es()
+# define BX_INSTR_PREFIX_FS() bx_instr_prefix_fs()
+# define BX_INSTR_PREFIX_GS() bx_instr_prefix_gs()
+
+# define BX_INSTR_MODRM32(modrm) bx_instr_modrm32(modrm)
+# define BX_INSTR_SIB32(sib) bx_instr_sib32(sib)
+# define BX_INSTR_MODRM16(modrm) bx_instr_modrm16(modrm)
+# define BX_INSTR_SIB_mod0_base5(ss)
+# define BX_INSTR_SIB_MOD0_IND4()
+# define BX_INSTR_SIB_MOD1_IND4()
+# define BX_INSTR_SIB_MOD2_IND4()
+
+# define BX_INSTR_IRET() bx_instr_iret()
+# define BX_INSTR_DEBUG_PROMPT() bx_instr_debug_prompt()
+
+# define BX_INSTR_LIN_READ(lin, phy, len) bx_instr_lin_read(lin, phy, len)
+# define BX_INSTR_LIN_WRITE(lin, phy, len) bx_instr_lin_write(lin, phy, len)
+
+#else // #if BX_INSTRUMENTATION
+# define BX_INSTR_INIT()
+# define BX_INSTR_SHUTDOWN()
+# define BX_INSTR_CNEAR_BRANCH_TAKEN(new_eip)
+# define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN()
+# define BX_INSTR_UCNEAR_BRANCH(what, new_eip)
+# define BX_INSTR_FAR_BRANCH(what, new_cs, new_eip)
+# define BX_INSTR_OPCODE_BEGIN(linear)
+# define BX_INSTR_OPCODE_END(linear)
+# define BX_INSTR_OPCODE_BYTE1(b)
+# define BX_INSTR_OPCODE_BYTE2(b)
+# define BX_INSTR_OPCODE_G1EbIb(nnn)
+# define BX_INSTR_OPCODE_G1EvIv(nnn)
+# define BX_INSTR_OPCODE_G1EvIb(nnn)
+# define BX_INSTR_OPCODE_G2EbIb(nnn)
+# define BX_INSTR_OPCODE_G2EvIb(nnn)
+# define BX_INSTR_OPCODE_G2Eb1(nnn)
+# define BX_INSTR_OPCODE_G2Ev1(nnn)
+# define BX_INSTR_OPCODE_G2EbCL(nnn)
+# define BX_INSTR_OPCODE_G2EvCL(nnn)
+# define BX_INSTR_OPCODE_G3Eb(nnn)
+# define BX_INSTR_OPCODE_G3Ev(nnn)
+# define BX_INSTR_OPCODE_G4(nnn)
+# define BX_INSTR_OPCODE_G5(nnn)
+# define BX_INSTR_OPCODE_G6(nnn)
+# define BX_INSTR_OPCODE_G7(nnn)
+# define BX_INSTR_OPCODE_G8EvIb(nnn)
+# define BX_INSTR_MEM_CODE(linear, size)
+# define BX_INSTR_MEM_DATA(linear, size, rw)
+# define BX_INSTR_EXCEPTION(vector)
+# define BX_INSTR_INP(addr, len)
+# define BX_INSTR_OUTP(addr, len)
+# define BX_INSTR_FETCH_BYTE(val8)
+# define BX_INSTR_FETCH_WORD(val16)
+# define BX_INSTR_FETCH_DWORD(val32)
+# define BX_INSTR_PHY_WRITE(addr, len)
+# define BX_INSTR_PHY_READ(addr, len)
+# define BX_INSTR_INTERRUPT(vector)
+# define BX_INSTR_TLB_CNTRL(what, newval)
+# define BX_INSTR_CACHE_CNTRL(what)
+# define BX_INSTR_HWINTERRUPT(vector, cs, eip)
+# define BX_INSTR_OPCODE_REPEATING()
+
+# define BX_INSTR_PREFIX_AS()
+# define BX_INSTR_PREFIX_OS()
+# define BX_INSTR_PREFIX_REP()
+# define BX_INSTR_PREFIX_REPNE()
+# define BX_INSTR_PREFIX_LOCK()
+# define BX_INSTR_PREFIX_CS()
+# define BX_INSTR_PREFIX_SS()
+# define BX_INSTR_PREFIX_DS()
+# define BX_INSTR_PREFIX_ES()
+# define BX_INSTR_PREFIX_FS()
+# define BX_INSTR_PREFIX_GS()
+
+# define BX_INSTR_MODRM32(modrm)
+# define BX_INSTR_SIB32(sib)
+# define BX_INSTR_MODRM16(modrm)
+# define BX_INSTR_SIB_mod0_base5(ss)
+# define BX_INSTR_SIB_MOD0_IND4()
+# define BX_INSTR_SIB_MOD1_IND4()
+# define BX_INSTR_SIB_MOD2_IND4()
+
+# define BX_INSTR_IRET()
+# define BX_INSTR_DEBUG_PROMPT()
+
+# define BX_INSTR_LIN_READ(lin, phy, len)
+# define BX_INSTR_LIN_WRITE(lin, phy, len)
+
+#endif // #if BX_INSTRUMENTATION
+
--- /dev/null
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) PATH_SEPARATOR=';' ;;
+ *) PATH_SEPARATOR=':' ;;
+ esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+ test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running ltconfig again with it.
+ ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf "%s\n"'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+ --debug enable verbose shell tracing
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --disable-fast-install do not optimize for fast installation
+ --enable-dlopen enable dlopen support
+ --enable-win32-dll enable building dlls on win32 hosts
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+-o, --output=FILE specify the output file [default=$default_ofile]
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+ --disable-lock disable file locking
+ --cache-file=FILE configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --disable-fast-install) enable_fast_install=no ;;
+
+ --enable-dlopen) enable_dlopen=yes ;;
+
+ --enable-win32-dll) enable_win32_dll=yes ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --output | -o) prev=ofile ;;
+ --output=*) ofile="$optarg" ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ --disable-lock) need_locks=no ;;
+
+ --cache-file=*) cache_file="$optarg" ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test ! -f "$ltmain"; then
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+ echo "loading cache $cache_file within ltconfig"
+ . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to LTMAIN.
+ srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$SHELL $ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$SHELL $ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:581: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_exeext="no"
+ $rm conftest*
+ echo 'main () { return 0; }' > conftest.c
+ echo "$progname:629: checking for executable suffix" >& 5
+ if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c | *.err | *.$objext ) ;;
+ *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+ else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+ exeext=""
+else
+ exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+
+ case "$host_os" in
+ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # we not sure about C++ programs.
+ link_static_flag="$link_static_flag ${wl}-lC"
+ ;;
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ pic_flag=-Kconform_pic
+ fi
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ pic_flag='-Kconform_pic'
+ link_static_flag='-Bstatic'
+ fi
+ ;;
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ case "$host_os" in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ ;;
+ *)
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ ;;
+ esac
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_c_o=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ compiler_c_o=no
+ echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_o_lo=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_o_lo=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_o_lo=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t$hard_links" 1>&6
+ $rm conftest*
+ if test "$hard_links" = no; then
+ echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+ echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_rtti_exceptions=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_rtti_exceptions=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_rtti_exceptions=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftest.dat
+ if ln -s X conftest.dat 2>/dev/null; then
+ $rm conftest.dat
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:991: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:1015: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:1018: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$with_gcc" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case "$host_os" in
+ aix3* | aix4*)
+ # On AIX, the GNU linker is very broken
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left by newer dlltools.
+ export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols'
+
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \$# in
+ 2) echo " \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;;
+ *) echo " \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done~
+ test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+ # can we support soname and/or expsyms with a.out? -oliva
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+ hardcode_libdir_separator=':'
+ if test "$with_gcc" = yes; then
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ shared_flag='-shared'
+ else
+ shared_flag='${wl}-bM:SRE'
+ hardcode_direct=yes
+ fi
+ allow_undefined_flag=' ${wl}-berok'
+ archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+ archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+ case "$host_os" in aix4.[01]|aix4.[01].*)
+ # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+ always_export_symbols=yes ;;
+ esac
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case "$host_os" in
+ hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF
+ fi
+ hardcode_libdir_flag_spec='${wl}-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # As osf3* with the addition of the -msym flag
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ rhapsody*)
+ archive_cmds='$CC -bundle -undefined suppress -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flags_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case "$host_os" in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $linkopts'
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ unixware7*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ break
+ else
+ NM=${NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+ global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ $rm conftest*
+ cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ echo "$progname:1653: checking if global_symbol_pipe works" >&5
+ if { (eval echo $progname:1654: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:1657: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$objext conftstm.$objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ global_symbol_pipe=
+ fi
+done
+if test "$pipe_works" = yes; then
+ echo "${ac_t}ok" 1>&6
+else
+ echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4*)
+ version_type=linux
+ # AIX has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ # We preserve .a as extension for shared libraries though AIX4.2
+ # and later linker supports .so
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+ shlibpath_var=LIBPATH
+ deplibs_check_method=pass_all
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ deplibs_check_method=pass_all
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ if test "$with_gcc" = yes; then
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+ else
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ fi
+ dynamic_linker='Win32 ld.exe'
+ deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ file_magic_cmd='${OBJDUMP} -f'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case "$version_type" in
+ freebsd-elf*)
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ deplibs_check_method=unknown
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_os" in
+ freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *) # from 3.2 on
+ shlibpath_overrides_runpath=no
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ case "$host_os" in
+ hpux10.20*)
+ # TODO: Does this work for hpux-11 too?
+ deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so.$major'
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+ case "$host_os" in
+ irix5*)
+ libsuff= shlibsuff=
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case "$LD" in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ deplibs_check_method='pass_all'
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ deplibs_check_method=pass_all
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd*)
+ version_type=sunos
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+openbsd*)
+ version_type=sunos
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ need_version=no
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method='file_magic COFF format alpha shared library'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ deplibs_check_method='pass_all'
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rhapsody*)
+ version_type=sunos
+ library_names_spec='${libname}.so'
+ soname_spec='${libname}.so'
+ shlibpath_var=DYLD_LIBRARY_PATH
+ deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/lib/libc.so
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_vendor" in
+ sequent)
+ file_magic_cmd='/bin/file'
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ ncr)
+ deplibs_check_method='pass_all'
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+ if test x$can_build_shared = xyes; then
+ test x$enable_win32_dll = xno && can_build_shared=no
+ echo "checking if package supports dlls... $can_build_shared" 1>&6
+ fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+ case "$deplibs_check_method" in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ test "$enable_shared" = yes && enable_static=no
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+ lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2248: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2256 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2288: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2293 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2335: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2343 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2375: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2380 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2423: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2431 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+fi
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ fi
+
+ case "$lt_cv_dlopen" in
+ dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2488: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2493 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ if test "x$ac_cv_header_dlfcn_h" = xyes; then
+ CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ fi
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2526: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self=cross
+ else
+ cat > conftest.c <<EOF
+#line 2534 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "$lt_cv_dlopen_self" = yes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2599: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self_static=cross
+ else
+ cat > conftest.c <<EOF
+#line 2607 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self_static=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+ ;;
+ esac
+
+ case "$lt_cv_dlopen_self" in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case "$lt_cv_dlopen_self_static" in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+ # Now quote all the things that may contain metacharacters.
+ for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+ AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+ file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case "$ltecho" in
+ *'\$0 --fallback-echo"')
+ ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+ esac
+
+ trap "$rm \"$ofile\"; exit 1" 1 2 15
+ echo "creating $ofile"
+ $rm "$ofile"
+ cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+ cfgfile="$ofile"
+ ;;
+
+*)
+ # Double-quote the variables that need it (for aesthetics).
+ for var in old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+ eval "$var=\\\"\$var\\\""
+ done
+
+ # Just create a config file.
+ cfgfile="$ofile.cfg"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ echo "creating $cfgfile"
+ $rm "$cfgfile"
+ cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+ ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+ echo '### END LIBTOOL CONFIG' >> "$ofile"
+ echo >> "$ofile"
+ case "$host_os" in
+ aix3*)
+ cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # Append the ltmain.sh script.
+ sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+
+ chmod +x "$ofile"
+ ;;
+
+*)
+ # Compile the libtool program.
+ echo "FIXME: would compile $ltmain"
+ ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+ libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ # Now arrange that obj and lo_libobj become the same file
+ $show "(cd $xdir && $LN_S $baseobj $libobj)"
+ if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (!dll)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ linkopts=
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ lib_search_path=
+ fi
+ # now prepend the system-specific ones
+ eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case "$arg" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: not more than one -exported-symbols argument allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case " $deplibs " in
+ *" $arg "*) ;;
+ *) deplibs="$deplibs $arg";;
+ esac
+ case " $lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir";;
+ esac
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ case ":$dllsearchpath:" in
+ ::) dllsearchpath="$dllsearchdir";;
+ *":$dllsearchdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+ esac
+ ;;
+ esac
+ ;;
+
+ -l*)
+ if test "$arg" = "-lc"; then
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # These systems don't actually have c library (as such)
+ continue
+ ;;
+ esac
+ elif test "$arg" = "-lm"; then
+ case "$host" in
+ *-*-cygwin* | *-*-beos*)
+ # These systems don't actually have math library (as such)
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -n "$dependency_libs"; then
+ # Extract -R and -L from dependency_libs
+ temp_deplibs=
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ case " $rpath $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ -L*) case "$compile_command $temp_deplibs " in
+ *" $deplib "*) ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ case " $lib_search_path " in
+ *" $temp_dir "*) ;;
+ *) lib_search_path="$lib_search_path $temp_dir";;
+ esac
+ ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # We need an absolute path.
+ case "$dir" in
+ [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+
+ # This is the magic to use -rpath.
+ # Skip directories that are in the system default run-time
+ # search path, unless they have been requested with -R.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ deplibs="$deplibs $dir/$linklib"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ if test -n "$dllsearchpath"; then
+ dllsearchpath="$dllsearchpath:$dllsearchdir"
+ else
+ dllsearchpath="$dllsearchdir"
+ fi
+ ;;
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ case ":$compile_shlibpath:" in
+ *":$dir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$dir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $absdir/$linklib"
+ deplibs="$deplibs $absdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$compile_command " in
+ *" -L$absdir "*) ;;
+ *) compile_command="$compile_command -L$absdir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$absdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$compile_shlibpath:" in
+ *":$absdir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$absdir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$finalize_command " in
+ *" -L$libdir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$dir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ versuffix="$major.$revision"
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ dependency_libs="$deplibs"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody*)
+ # rhapsody is a little odd...
+ deplibs="$deplibs -framework System"
+ ;;
+ *)
+ # Add libc to deplibs on all other systems.
+ deplibs="$deplibs -lc"
+ ;;
+ esac
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case "$deplibs_check_method" in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $CC -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm conftest
+ $CC -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case "$potliblink" in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) in case we are running --disable-static
+ for obj in $libobjs; do
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ if test ! -f $xdir/$oldobj; then
+ $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+ $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linkopts="$linkopts $flag"
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$libobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+ $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$compile_rpath " in
+ *" $libdir "*) ;;
+ *) compile_rpath="$compile_rpath $libdir" ;;
+ esac
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
+ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
+ < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$host" in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)\r
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ link_against_libtool_libs='$link_against_libtool_libs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if (cd \"\$thisdir\" && eval \$relink_command); then :
+ else
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ *-*-cygwin*)
+ $echo >> $output "\
+ exec \$progdir/\$program \${1+\"\$@\"}
+"
+ ;;
+
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2*)
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place in case we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$oldobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+ obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+ $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ if test -n "$xrpath"; then
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ done
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ fi
+ $rm $output
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null`
+ if test $? = 0 ; then :
+ else
+ tmpdir="$tmpdir/libtool-$$"
+ fi
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+## sid/include in build tree bochs/cpu component/bochs sid/include in src tree bochs/memory
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../cpu
+
+noinst_LTLIBRARIES = libmemory.la
+
+libmemory_la_SOURCES = memory.cc memory-sid.cc misc_mem.cc memory.h memory-sid.h
+
+libmemory_la_LDFLAGS = -no-undefined
--- /dev/null
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+APIC_OBJS = @APIC_OBJS@
+AR = @AR@
+AS = @AS@
+AS_DYNAMIC_INCS = @AS_DYNAMIC_INCS@
+AS_DYNAMIC_OBJS = @AS_DYNAMIC_OBJS@
+BX_LOADER_OBJS = @BX_LOADER_OBJS@
+BX_SPLIT_HD_SUPPORT = @BX_SPLIT_HD_SUPPORT@
+CC = @CC@
+CDROM_OBJS = @CDROM_OBJS@
+CD_UP_ONE = @CD_UP_ONE@
+CD_UP_TWO = @CD_UP_TWO@
+CFP = @CFP@
+COMMAND_SEPARATOR = @COMMAND_SEPARATOR@
+CPP_SUFFIX = @CPP_SUFFIX@
+CXX = @CXX@
+CXXFP = @CXXFP@
+DASH = @DASH@
+DEBUGGER_VAR = @DEBUGGER_VAR@
+DISASM_VAR = @DISASM_VAR@
+DLLTOOL = @DLLTOOL@
+DYNAMIC_VAR = @DYNAMIC_VAR@
+EXE = @EXE@
+EXEEXT = @EXEEXT@
+EXTERNAL_DEPENDENCY = @EXTERNAL_DEPENDENCY@
+FPU_GLUE_OBJ = @FPU_GLUE_OBJ@
+FPU_VAR = @FPU_VAR@
+GUI_LINK_OPTS = @GUI_LINK_OPTS@
+GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
+GUI_OBJS = @GUI_OBJS@
+GZIP = @GZIP@
+INLINE_VAR = @INLINE_VAR@
+INSTRUMENT_DIR = @INSTRUMENT_DIR@
+INSTRUMENT_VAR = @INSTRUMENT_VAR@
+IOAPIC_OBJS = @IOAPIC_OBJS@
+IODEV_LIB_VAR = @IODEV_LIB_VAR@
+LD = @LD@
+LIBTOOL = @LIBTOOL@
+LINK = @LINK@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MAKELIB = @MAKELIB@
+NE2K_OBJS = @NE2K_OBJS@
+NM = @NM@
+NONINLINE_VAR = @NONINLINE_VAR@
+OBJDUMP = @OBJDUMP@
+OFP = @OFP@
+PACKAGE = @PACKAGE@
+PCI_OBJ = @PCI_OBJ@
+PRIMARY_TARGET = @PRIMARY_TARGET@
+RANLIB = @RANLIB@
+READLINE_LIB = @READLINE_LIB@
+RFB_LIBS = @RFB_LIBS@
+RMCOMMAND = @RMCOMMAND@
+SB16_OBJS = @SB16_OBJS@
+SLASH = @SLASH@
+SUFFIX_LINE = @SUFFIX_LINE@
+TAR = @TAR@
+VERSION = @VERSION@
+VIDEO_OBJS = @VIDEO_OBJS@
+sidtarget_arm = @sidtarget_arm@
+sidtarget_m32r = @sidtarget_m32r@
+sidtarget_m68k = @sidtarget_m68k@
+sidtarget_mips = @sidtarget_mips@
+sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
+
+AUTOMAKE_OPTIONS = foreign
+
+INCLUDES = -I$(top_builddir)/../../include -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../../include -I$(srcdir)/../cpu
+
+noinst_LTLIBRARIES = libmemory.la
+
+libmemory_la_SOURCES = memory.cc memory-sid.cc misc_mem.cc memory.h memory-sid.h
+
+libmemory_la_LDFLAGS = -no-undefined
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../config/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+libmemory_la_LIBADD =
+libmemory_la_OBJECTS = memory.lo memory-sid.lo misc_mem.lo
+CXXFLAGS = @CXXFLAGS@
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+GZIP_ENV = --best
+DEP_FILES = .deps/memory-sid.P .deps/memory.P .deps/misc_mem.P
+SOURCES = $(libmemory_la_SOURCES)
+OBJECTS = $(libmemory_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign memory/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmemory.la: $(libmemory_la_OBJECTS) $(libmemory_la_DEPENDENCIES)
+ $(CXXLINK) $(libmemory_la_LDFLAGS) $(libmemory_la_OBJECTS) $(libmemory_la_LIBADD) $(LIBS)
+.cc.o:
+ $(CXXCOMPILE) -c $<
+.cc.lo:
+ $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = memory
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign memory/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cc
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cc
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+ clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+// memory-sid.cc - override bx_mem_c physical memory access functions. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#include "bochs.h"
+#include "x86.h"
+#define LOG_THIS BX_MEM_THIS
+
+ void
+sid_mem_c::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+ try {
+ switch(len)
+ {
+ case 4:
+ {
+ Bit32u data32 = * ((Bit32u *) data);
+ sid_cpu->write_data_memory_4 (cpu->eip, addr, data32);
+ break;
+ }
+ case 2:
+ {
+ Bit16u data16 = * ((Bit16u *) data);
+ sid_cpu->write_data_memory_2 (cpu->eip, addr, data16);
+ break;
+ }
+ case 1:
+ {
+ Bit8u data8 = * ((Bit8u *) data);
+ sid_cpu->write_data_memory_1 (cpu->eip, addr, data8);
+ break;
+ }
+ default:
+ {
+ Bit8u data8;
+ Bit8u *data_ptr = (Bit8u *) data;
+
+ for (unsigned i = 0; i < len; i++)
+ {
+ data8 = * data_ptr;
+ sid_cpu->write_data_memory_1 (cpu->eip, addr, data8);
+ data_ptr++;
+ addr++;
+ }
+ break;
+ }
+ }
+ } catch (sidutil::cpu_memory_fault e) {
+ cerr << "[MEM ] caught cpu_memory_fault exeception" << endl;
+ cerr << "[MEM ] pc = " << setbase(16) << e.pc << endl;
+ cerr << "[MEM ] address = " << e.address << endl;
+ cerr << "[MEM ] status: " << (e.status == sid::bus::ok ? "ok" :
+ (e.status == sid::bus::misaligned ? "misaligned" :
+ (e.status == sid::bus::unmapped ? "unmapped" : "unpermitted"))) << endl;
+
+ cerr << "[MEM ] operation: " << e.operation << setbase(10) << endl;
+ BX_PANIC(("sid_mem_c::write_physical: error\n"));
+ }
+}
+
+ void
+sid_mem_c::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+ try {
+ switch (len)
+ {
+ case 4:
+ * ((Bit32u *) data) = sid_cpu->read_data_memory_4 (cpu->eip, addr);
+ break;
+ case 2:
+ * ((Bit16u *) data) = sid_cpu->read_data_memory_2 (cpu->eip, addr);
+ break;
+ case 1:
+ * ((Bit8u *) data) = sid_cpu->read_data_memory_1 (cpu->eip, addr);
+ break;
+ default:
+ Bit8u data8;
+ Bit8u * data_ptr = (Bit8u *) data;
+
+ for (unsigned i = 0; i < len; i++)
+ {
+ * data_ptr = sid_cpu->read_data_memory_1 (cpu->eip, addr);
+ data_ptr++;
+ addr++;
+ }
+ break;
+ }
+ } catch (sidutil::cpu_memory_fault e) {
+ cerr << "[MEM ] caught cpu_memory_fault exeception" << endl;
+ cerr << "[MEM ] pc = " << setbase(16) << e.pc << endl;
+ cerr << "[MEM ] address = " << e.address << endl;
+ cerr << "[MEM ] status: " << (e.status == sid::bus::ok ? "ok" :
+ (e.status == sid::bus::misaligned ? "misaligned" :
+ (e.status == sid::bus::unmapped ? "unmapped" : "unpermitted"))) << endl;
+
+ cerr << "[MEM ] operation: " << e.operation << setbase(10) << endl;
+ BX_PANIC(("sid_mem_c::read_physical: error\n"));
+ }
+}
--- /dev/null
+// memory-sid.h - declaration of the sid_mem_c class. -*- C++ -*-
+//
+// Copyright (C) 2001 Red Hat.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#ifndef __MEMORY_SID_H__
+#define __MEMORY_SID_H__
+
+#include "memory.h"
+
+class x86_cpu;
+
+class sid_mem_c : public BX_MEM_C {
+
+public:
+ x86_cpu *sid_cpu;
+
+ void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+ void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+};
+
+extern sid_mem_c bx_mem;
+
+#endif // __MEMORY_SID_H__
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#include "bochs.h"
+#define LOG_THIS BX_MEM_THIS
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+
+ void
+BX_MEM_C::write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+ Bit8u *data_ptr;
+ Bit32u a20addr;
+
+
+ a20addr = A20ADDR(addr);
+ BX_INSTR_PHY_WRITE(a20addr, len);
+
+#if BX_DEBUGGER
+ // (mch) Check for physical write break points, TODO
+ // (bbd) Each breakpoint should have an associated CPU#, TODO
+ for (int i = 0; i < num_write_watchpoints; i++)
+ if (write_watchpoint[i] == a20addr) {
+ BX_CPU(0)->break_point = BREAK_POINT_WRITE;
+ break;
+ }
+#endif
+
+
+ if ( (a20addr + len) <= BX_MEM_THIS len ) {
+ // all of data is within limits of physical memory
+ if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+ if (len == 4) {
+ if ((a20addr & 0x00000003) == 0) {
+ // write 4byte data to aligned memory location
+ Bit32u data32;
+
+ data32 = * (Bit32u *) data;
+#ifdef BX_BIG_ENDIAN
+ data32 = (data32 << 24) | (data32 >> 24) |
+ ((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
+#endif
+ * ((Bit32u *) (&vector[a20addr])) = data32;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ return;
+ }
+ else {
+ Bit32u data32;
+
+ data32 = * (Bit32u *) data;
+ * ((Bit8u *) (&vector[a20addr])) = data32; data32 >>= 8;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ * ((Bit8u *) (&vector[A20ADDR(addr+1)])) = data32; data32 >>= 8;
+ * ((Bit8u *) (&vector[A20ADDR(addr+2)])) = data32; data32 >>= 8;
+ * ((Bit8u *) (&vector[A20ADDR(addr+3)])) = data32;
+ // worst case, last byte is in different page; possible extra dirty page
+ BX_DBG_DIRTY_PAGE(A20ADDR(addr+3) >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ return;
+ }
+ }
+ if (len == 2) {
+ if ((a20addr & 0x00000001) == 0) {
+ // write 2-byte data to aligned memory location
+ Bit16u data16;
+
+ data16 = * (Bit16u *) data;
+#ifdef BX_BIG_ENDIAN
+ data16 = (data16 >> 8) | (data16 << 8);
+#endif
+ * ((Bit16u *) (&vector[a20addr])) = data16;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ return;
+ }
+ else {
+ Bit16u data16;
+
+ data16 = * (Bit16u *) data;
+ * ((Bit8u *) (&vector[a20addr])) = (Bit8u) data16;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ * ((Bit8u *) (&vector[A20ADDR(a20addr+1)])) = (data16 >> 8);
+ BX_DBG_DIRTY_PAGE(A20ADDR(a20addr+1) >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ return;
+ }
+ }
+ if (len == 1) {
+ Bit8u data8;
+
+ data8 = * (Bit8u *) data;
+ * ((Bit8u *) (&vector[a20addr])) = data8;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ return;
+ }
+ // len == 3 case can just fall thru to special cases handling
+ }
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+write_one:
+ if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+ // addr *not* in range 00080000 .. 000FFFFF
+ vector[a20addr] = *data_ptr;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+inc_one:
+ if (len == 1) return;
+ len--;
+ addr++;
+ a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ goto write_one;
+ }
+
+ // addr in range 00080000 .. 000FFFFF
+
+ if (a20addr <= 0x0009ffff) {
+ // regular memory 80000 .. 9FFFF
+ vector[a20addr] = *data_ptr;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ goto inc_one;
+ }
+ if (a20addr <= 0x000bffff) {
+ // VGA memory A0000 .. BFFFF
+ BX_VGA_MEM_WRITE(a20addr, *data_ptr);
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ BX_DBG_UCMEM_REPORT(a20addr, 1, BX_WRITE, *data_ptr); // obsolete
+ goto inc_one;
+ }
+ // adapter ROM C0000 .. DFFFF
+ // ROM BIOS memory E0000 .. FFFFF
+ // (ignore write)
+ //BX_INFO(("ROM lock %08x: len=%u\n",
+ // (unsigned) a20addr, (unsigned) len));
+#if BX_PCI_SUPPORT == 0
+#if BX_SHADOW_RAM
+ // Write it since its in shadow RAM
+ vector[a20addr] = *data_ptr;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+#else
+ // ignore write to ROM
+#endif
+#else
+ // Write Based on 440fx Programming
+ if (bx_options.i440FXSupport &&
+ ((a20addr >= 0xC0000) && (a20addr <= 0xFFFFF))) {
+ switch (bx_devices.pci->wr_memType(a20addr & 0xFC000)) {
+ case 0x0: // Writes to ShadowRAM
+// BX_INFO(("Writing to ShadowRAM %08x, len %u ! \n", (unsigned) a20addr, (unsigned) len));
+ vector[a20addr] = *data_ptr;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ goto inc_one;
+
+ case 0x1: // Writes to ROM, Inhibit
+// bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)] = *data_ptr;
+// BX_INFO(("Writing to ROM %08x, Data %02x ! \n", (unsigned) a20addr, *data_ptr));
+ goto inc_one;
+ default:
+ BX_PANIC(("write_physical: default case\n"));
+ goto inc_one;
+ }
+ }
+#endif
+ goto inc_one;
+ }
+
+ else {
+ // some or all of data is outside limits of physical memory
+ unsigned i;
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+#if BX_SUPPORT_APIC
+ bx_generic_apic_c *local_apic = &cpu->local_apic;
+ bx_generic_apic_c *ioapic = bx_devices.ioapic;
+ if (local_apic->is_selected (a20addr, len)) {
+ local_apic->write (a20addr, (Bit32u *)data, len);
+ return;
+ } else if (ioapic->is_selected (a20addr, len)) {
+ ioapic->write (a20addr, (Bit32u *)data, len);
+ return;
+ }
+ else
+#endif
+ for (i = 0; i < len; i++) {
+ if (a20addr < BX_MEM_THIS len) {
+ vector[a20addr] = *data_ptr;
+ BX_DBG_DIRTY_PAGE(a20addr >> 12);
+ BX_DYN_DIRTY_PAGE(a20addr >> 12);
+ }
+ // otherwise ignore byte, since it overruns memory
+ addr++;
+ a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ }
+ return;
+ }
+}
+
+
+ void
+BX_MEM_C::read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
+{
+ Bit8u *data_ptr;
+ Bit32u a20addr;
+
+
+ a20addr = A20ADDR(addr);
+ BX_INSTR_PHY_READ(a20addr, len);
+
+#if BX_DEBUGGER
+ // (mch) Check for physical read break points, TODO
+ // (bbd) Each breakpoint should have an associated CPU#, TODO
+ for (int i = 0; i < num_read_watchpoints; i++)
+ if (read_watchpoint[i] == a20addr) {
+ BX_CPU(0)->break_point = BREAK_POINT_READ;
+ break;
+ }
+#endif
+
+ if ( (a20addr + len) <= BX_MEM_THIS len ) {
+ // all of data is within limits of physical memory
+ if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+ if (len == 4) {
+ if ((a20addr & 0x00000003) == 0) {
+ // read 4-byte data from aligned memory location
+ Bit32u data32;
+
+ data32 = * ((Bit32u *) (&vector[a20addr]));
+#ifdef BX_BIG_ENDIAN
+ data32 = (data32 << 24) | (data32 >> 24) |
+ ((data32&0x00ff0000)>>8) | ((data32&0x0000ff00)<<8);
+#endif
+ * (Bit32u *) data = data32;
+ return;
+ }
+ else {
+ Bit32u data32;
+
+ data32 = * ((Bit8u *) (&vector[A20ADDR(addr+3)])); data32 <<= 8;
+ data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+2)])); data32 <<= 8;
+ data32 |= * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data32 <<= 8;
+ data32 |= * ((Bit8u *) (&vector[a20addr]));
+
+ * (Bit32u *) data = data32;
+ return;
+ }
+ }
+ if (len == 2) {
+ if ((a20addr & 0x00000001) == 0) {
+ // read 2-byte data from aligned memory location
+ Bit16u data16;
+
+ data16 = * ((Bit16u *) (&vector[a20addr]));
+#ifdef BX_BIG_ENDIAN
+ data16 = (data16 >> 8) | (data16 << 8);
+#endif
+
+ * (Bit16u *) data = data16;
+ return;
+ }
+ else {
+ Bit16u data16;
+
+ data16 = * ((Bit8u *) (&vector[A20ADDR(addr+1)])); data16 <<= 8;
+ data16 |= * ((Bit8u *) (&vector[a20addr]));
+
+ * (Bit16u *) data = data16;
+ return;
+ }
+ }
+ if (len == 1) {
+ Bit8u data8;
+
+ data8 = * ((Bit8u *) (&vector[a20addr]));
+ * (Bit8u *) data = data8;
+ return;
+ }
+ // len == 3 case can just fall thru to special cases handling
+ }
+
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+
+
+read_one:
+ if ( (a20addr & 0xfff80000) != 0x00080000 ) {
+ // addr *not* in range 00080000 .. 000FFFFF
+ *data_ptr = vector[a20addr];
+inc_one:
+ if (len == 1) return;
+ len--;
+ addr++;
+ a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ goto read_one;
+ }
+
+ // addr in range 00080000 .. 000FFFFF
+#if BX_PCI_SUPPORT == 0
+ if ((a20addr <= 0x0009ffff) || (a20addr >= 0x000c0000) ) {
+ // regular memory 80000 .. 9FFFF, C0000 .. F0000
+ *data_ptr = vector[a20addr];
+ goto inc_one;
+ }
+ // VGA memory A0000 .. BFFFF
+ *data_ptr = BX_VGA_MEM_READ(a20addr);
+ BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr); // obsolete
+ goto inc_one;
+#else // #if BX_PCI_SUPPORT == 0
+ if (a20addr <= 0x0009ffff) {
+ *data_ptr = vector[a20addr];
+ goto inc_one;
+ }
+ if (a20addr <= 0x000BFFFF) {
+ // VGA memory A0000 .. BFFFF
+ *data_ptr = BX_VGA_MEM_READ(a20addr);
+ BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr);
+ goto inc_one;
+ }
+
+ // a20addr in C0000 .. FFFFF
+ if (!bx_options.i440FXSupport) {
+ *data_ptr = vector[a20addr];
+ goto inc_one;
+ }
+ else {
+ switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
+ case 0x0: // Read from ShadowRAM
+ *data_ptr = vector[a20addr];
+ BX_INFO(("Reading from ShadowRAM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+ goto inc_one;
+
+ case 0x1: // Read from ROM
+ *data_ptr = bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)];
+ //BX_INFO(("Reading from ROM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+ goto inc_one;
+ default:
+ BX_PANIC(("::read_physical: default case\n"));
+ }
+ }
+ goto inc_one;
+#endif // #if BX_PCI_SUPPORT == 0
+ }
+ else {
+ // some or all of data is outside limits of physical memory
+ unsigned i;
+
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr = (Bit8u *) data;
+#else // BX_BIG_ENDIAN
+ data_ptr = (Bit8u *) data + (len - 1);
+#endif
+
+#if BX_SUPPORT_APIC
+ bx_generic_apic_c *local_apic = &cpu->local_apic;
+ bx_generic_apic_c *ioapic = bx_devices.ioapic;
+ if (local_apic->is_selected (addr, len)) {
+ local_apic->read (addr, data, len);
+ return;
+ } else if (ioapic->is_selected (addr, len)) {
+ ioapic->read (addr, data, len);
+ return;
+ }
+#endif
+ for (i = 0; i < len; i++) {
+#if BX_PCI_SUPPORT == 0
+ if (a20addr < BX_MEM_THIS len)
+ *data_ptr = vector[a20addr];
+ else
+ *data_ptr = 0xff;
+#else // BX_PCI_SUPPORT == 0
+ if (a20addr < BX_MEM_THIS len) {
+ if ((a20addr >= 0x000C0000) && (a20addr <= 0x000FFFFF)) {
+ if (!bx_options.i440FXSupport)
+ *data_ptr = vector[a20addr];
+ else {
+ switch (bx_devices.pci->rd_memType(a20addr & 0xFC000)) {
+ case 0x0: // Read from ROM
+ *data_ptr = vector[a20addr];
+ //BX_INFO(("Reading from ROM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+ break;
+
+ case 0x1: // Read from Shadow RAM
+ *data_ptr = bx_pci.s.i440fx.shadow[(a20addr - 0xc0000)];
+ BX_INFO(("Reading from ShadowRAM %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+ break;
+ default:
+ BX_PANIC(("read_physical: default case\n"));
+ } // Switch
+ }
+ }
+ else {
+ *data_ptr = vector[a20addr];
+ BX_INFO(("Reading from Norm %08x, Data %02x \n", (unsigned) a20addr, *data_ptr));
+ }
+ }
+ else
+ *data_ptr = 0xff;
+#endif // BX_PCI_SUPPORT == 0
+ addr++;
+ a20addr = A20ADDR(addr);
+#ifdef BX_LITTLE_ENDIAN
+ data_ptr++;
+#else // BX_BIG_ENDIAN
+ data_ptr--;
+#endif
+ }
+ return;
+ }
+}
+
+#endif // #if BX_PROVIDE_CPU_MEMORY
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#ifndef __MEMORY_H__
+#define __MEMORY_H__
+
+#define BX_USE_MEM_SMF 0
+
+#if BX_USE_MEM_SMF
+// if static member functions on, then there is only one memory
+# define BX_MEM_SMF static
+# define BX_MEM_THIS BX_MEM(0)->
+#else
+# define BX_MEM_SMF
+# define BX_MEM_THIS this->
+#endif
+
+
+
+class BX_MEM_C : public logfunctions {
+
+public:
+ Bit8u *vector;
+ size_t len;
+ size_t megabytes; // (len in Megabytes)
+#if BX_DEBUGGER
+ unsigned char dbg_dirty_pages[(BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096];
+ Bit32u dbg_count_dirty_pages () {
+ return (BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096;
+ }
+#endif
+
+ BX_MEM_C(void);
+ BX_MEM_C(size_t memsize);
+ ~BX_MEM_C(void);
+ BX_MEM_SMF void init_memory(int memsize);
+ BX_MEM_SMF void read_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+ BX_MEM_SMF void write_physical(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
+ BX_MEM_SMF void load_ROM(const char *path, Bit32u romaddress);
+ BX_MEM_SMF Bit32u get_memory_in_k(void);
+ BX_MEM_SMF Boolean dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf);
+ BX_MEM_SMF Boolean dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf);
+ BX_MEM_SMF Boolean dbg_crc32(
+ unsigned long (*f)(unsigned char *buf, int len),
+ Bit32u addr1, Bit32u addr2, Bit32u *crc);
+ };
+
+#if BX_SUPPORT_SID
+#else
+#if BX_PROVIDE_CPU_MEMORY==1
+#if BX_SMP_PROCESSORS==1
+extern BX_MEM_C bx_mem;
+#else
+extern BX_MEM_C *bx_mem_array[BX_ADDRESS_SPACES];
+#endif /* BX_SMP_PROCESSORS */
+#endif /* BX_PROVIDE_CPU_MEMORY==1 */
+#endif // BX_SUPPORT_SID
+
+#if BX_DEBUGGER
+# define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1;
+#else
+# define BX_DBG_DIRTY_PAGE(page)
+#endif
+
+#endif // __MEMORY_H__
--- /dev/null
+// Copyright (C) 2001 MandrakeSoft S.A.
+//
+// MandrakeSoft S.A.
+// 43, rue d'Aboukir
+// 75002 Paris - France
+// http://www.linux-mandrake.com/
+// http://www.mandrakesoft.com/
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+
+
+
+
+
+#include "bochs.h"
+#define LOG_THIS BX_MEM(0)->
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+ Bit32u
+BX_MEM_C::get_memory_in_k(void)
+{
+ BX_INFO(("%uKB\n", (unsigned)(BX_MEM_THIS megabytes*1024)));
+
+ return(BX_MEM_THIS megabytes * 1024);
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+ // BX_MEM_C constructor
+BX_MEM_C::BX_MEM_C(void)
+{
+ char mem[32];
+ sprintf(mem, "[MEM%d]", BX_SIM_ID);
+ setprefix(mem);
+ settype(MEMLOG);
+
+ vector = NULL;
+ len = 0;
+ megabytes = 0;
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+
+#if BX_PROVIDE_CPU_MEMORY
+ // BX_MEM_C constructor
+BX_MEM_C::BX_MEM_C(size_t memsize)
+{
+ vector = new Bit8u[memsize];
+ len = memsize;
+ megabytes = len / (1024*1024);
+ BX_INFO(("Init(%uB == %.2f)\n",memsize, megabytes));
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+// BX_MEM_C destructor
+BX_MEM_C::~BX_MEM_C(void)
+{
+ if (this-> vector != NULL) {
+ delete this->vector;
+ }
+ else {
+ BX_DEBUG(("(%u) memory not freed as it wasn't allocated!\n", BX_SIM_ID));
+ }
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+ void
+BX_MEM_C::init_memory(int memsize)
+{
+ // you can pass 0 if memory has been allocated already through
+ // the constructor, or the desired size of memory if it hasn't
+
+ if (BX_MEM_THIS vector == NULL) {
+ // memory not already allocated, do now...
+ BX_MEM_THIS vector = new Bit8u[memsize];
+ BX_MEM_THIS len = memsize;
+ BX_MEM_THIS megabytes = memsize / (1024*1024);
+ BX_INFO(("Init(%uB == %.2fMB).\n", memsize, (float)(BX_MEM_THIS megabytes) ));
+ }
+ // initialize all memory to 0x00
+ memset(BX_MEM_THIS vector, 0x00, BX_MEM_THIS len);
+
+ // initialize ROM area (0xc0000 .. 0xfffff) to 0xff
+ memset(BX_MEM_THIS vector + 0xc0000, 0xff, 0x40000);
+
+#if BX_DEBUGGER
+ // initialize dirty pages table
+ memset(dbg_dirty_pages, 0, sizeof(dbg_dirty_pages));
+
+ if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
+ BX_INFO(("Error: memory larger than dirty page table can handle\n"));
+ BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS\n"));
+ }
+#endif
+
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if BX_PROVIDE_CPU_MEMORY
+ void
+BX_MEM_C::load_ROM(const char *path, Bit32u romaddress)
+{
+ struct stat stat_buf;
+ int fd, ret;
+ unsigned long size, offset;
+
+ // read in ROM BIOS image file
+ fd = open(path, O_RDONLY
+#ifdef O_BINARY
+ | O_BINARY
+#endif
+ );
+ if (fd < 0) {
+ BX_INFO(( "ROM: couldn't open ROM image file '%s'.\n", path));
+ exit(1);
+ }
+ ret = fstat(fd, &stat_buf);
+ if (ret) {
+ BX_INFO(( "ROM: couldn't stat ROM image file '%s'.\n", path));
+ exit(1);
+ }
+
+ size = stat_buf.st_size;
+
+ if ( (romaddress + size) > BX_MEM_THIS len ) {
+ BX_INFO(( "ROM: ROM address range > physical memsize!\n"));
+ exit(1);
+ }
+
+ offset = 0;
+ while (size > 0) {
+#if BX_PCI_SUPPORT
+ if (bx_options.i440FXSupport)
+ ret = read(fd, (bx_ptr_t) &bx_devices.pci->s.i440fx.shadow[romaddress - 0xC0000 + offset],
+ size);
+ else
+ ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
+#else
+ ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
+#endif
+ if (ret <= 0) {
+ BX_PANIC(( "ROM: read failed on BIOS image\n"));
+ }
+ size -= ret;
+ offset += ret;
+ }
+ close(fd);
+#if BX_PCI_SUPPORT
+ if (bx_options.i440FXSupport)
+ BX_INFO(("rom in i440FX RAM 0x%06x/%u ('%s')\n",
+ (unsigned) romaddress,
+ (unsigned) stat_buf.st_size,
+ path
+ ));
+ else
+ BX_INFO(("rom at 0x%06x/%u ('%s')\n",
+ (unsigned) romaddress,
+ (unsigned) stat_buf.st_size,
+ path
+ ));
+#else // #if BX_PCI_SUPPORT
+ BX_INFO(("rom at 0x%06x/%u ('%s')\n",
+ (unsigned) romaddress,
+ (unsigned) stat_buf.st_size,
+ path
+ ));
+#endif // #if BX_PCI_SUPPORT
+}
+#endif // #if BX_PROVIDE_CPU_MEMORY
+
+
+#if ( BX_DEBUGGER || BX_DISASM )
+ Boolean
+BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
+{
+ if ( (addr + len) > this->len ) {
+ BX_INFO(("dbg_fetch_mem out of range. %p > %p\n",
+ addr+len, this->len));
+ return(0); // error, beyond limits of memory
+ }
+ for (; len>0; len--) {
+#if BX_SUPPORT_VGA
+ if ( (addr & 0xfffe0000) == 0x000a0000 ) {
+ *buf = BX_VGA_MEM_READ(addr);
+ }
+ else {
+#endif
+#if BX_PCI_SUPPORT == 0
+ *buf = vector[addr];
+#else
+ if ( bx_options.i440FXSupport &&
+ ((addr >= 0x000C0000) && (addr <= 0x000FFFFF)) ) {
+ switch (bx_devices.pci->rd_memType (addr)) {
+ case 0x0: // Fetch from ShadowRAM
+ *buf = vector[addr];
+// BX_INFO(("Fetching from ShadowRAM %06x, len %u !\n", (unsigned)addr, (unsigned)len));
+ break;
+
+ case 0x1: // Fetch from ROM
+ *buf = bx_pci.s.i440fx.shadow[(addr - 0xC0000)];
+// BX_INFO(("Fetching from ROM %06x, Data %02x \n", (unsigned)addr, *buf));
+ break;
+ default:
+ BX_PANIC(("dbg_fetch_mem: default case\n"));
+ }
+ }
+ else
+ *buf = vector[addr];
+#endif // #if BX_PCI_SUPPORT == 0
+ }
+ buf++;
+ addr++;
+ }
+ return(1);
+}
+#endif
+
+#if BX_DEBUGGER
+ Boolean
+BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
+{
+ if ( (addr + len) > this->len ) {
+ return(0); // error, beyond limits of memory
+ }
+ for (; len>0; len--) {
+#if BX_SUPPORT_VGA
+ if ( (addr & 0xfffe0000) == 0x000a0000 ) {
+ BX_VGA_MEM_WRITE(addr, *buf);
+ }
+ else
+#endif
+ vector[addr] = *buf;
+ buf++;
+ addr++;
+ }
+ return(1);
+}
+#endif
+
+ Boolean
+BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
+ Bit32u addr1, Bit32u addr2, Bit32u *crc)
+{
+ unsigned len;
+
+ *crc = 0;
+ if (addr1 > addr2)
+ return(0);
+
+ if (addr2 >= this->len) {
+ return(0); // error, specified address past last phy mem addr
+ }
+
+ len = 1 + addr2 - addr1;
+ *crc = f(vector + addr1, len);
+
+ return(1);
+}
--- /dev/null
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`configure.in'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`configure.in'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`configure.in'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id$
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
in basic_cpu now.
* compCGEN.cxx: Corresponding change.
+2001-08-22 graydon hoare <graydon@redhat.com>
+
+ * Makefile.am: Add missing dis-buf.c
+ * Makefile.in: Regenerate.
+
+2001-08-16 graydon hoare <graydon@redhat.com>
+
+ * Makefile.am: gcc -> $(CC) fix.
+ * Makefile.in: Regenerate.
+
+2001-08-15 graydon hoare <graydon@redhat.com>
+
+ * Makefile.am: Add support for building and
+ linking invididual objects from opcodes.
+ * Makefile.in: Regenerate.
+
2001-08-03 matthew green <mrg@redhat.com>
* cgen-cpu.h (~cgen_bi_endian_cpu): Add throw() specifier.
AM_MAKEFLAGS= "TOP_CXXFLAGS=$(TOP_CXXFLAGS)"
MAKEOVERRIDES=
-OPCODES = ../../../opcodes/libopcodes.la
LIBIBERTY = -L../../../libiberty -liberty
TRACEDIS = tracedis.c
libcgencpu_la_SOURCES = compCGEN.cxx $(TRACEDIS)
libcgencpu_la_LDFLAGS = -module -no-undefined
-libcgencpu_la_LIBADD = @cpu_libs@ $(OPCODES) $(INTLLIBS) $(LIBIBERTY)
-libcgencpu_la_DEPENDENCIES = @cpu_libs@
+libcgencpu_la_LIBADD = @cpu_libs@ $(INTLLIBS) $(LIBIBERTY) cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+libcgencpu_la_DEPENDENCIES = @cpu_libs@ cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+ -I../../../opcodes \
+ -I../../../bfd \
+ -I../../../intl \
+ -I$(srcdir)/../../../opcodes \
+ -I$(srcdir)/../../../include \
+ -I$(srcdir)/../../../bfd \
+ -I$(srcdir)/../../../intl \
+ -D_GNU_SOURCE
+
+cgen-asm.lo: ../../../opcodes/cgen-asm.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-dis.lo: ../../../opcodes/cgen-dis.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-opc.lo: ../../../opcodes/cgen-opc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+dis-buf.lo: ../../../opcodes/dis-buf.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
DEJAGNUTESTS = cpumonkey.exp dhrystone.exp
check-local: all
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
INTLLIBS = @INTLLIBS@
AM_MAKEFLAGS = "TOP_CXXFLAGS=$(TOP_CXXFLAGS)"
MAKEOVERRIDES =
-OPCODES = ../../../opcodes/libopcodes.la
LIBIBERTY = -L../../../libiberty -liberty
TRACEDIS = tracedis.c
libcgencpu_la_SOURCES = compCGEN.cxx $(TRACEDIS)
libcgencpu_la_LDFLAGS = -module -no-undefined
-libcgencpu_la_LIBADD = @cpu_libs@ $(OPCODES) $(INTLLIBS) $(LIBIBERTY)
-libcgencpu_la_DEPENDENCIES = @cpu_libs@
+libcgencpu_la_LIBADD = @cpu_libs@ $(INTLLIBS) $(LIBIBERTY) cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+libcgencpu_la_DEPENDENCIES = @cpu_libs@ cgen-asm.lo cgen-dis.lo cgen-opc.lo dis-buf.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+ -I../../../opcodes \
+ -I../../../bfd \
+ -I../../../intl \
+ -I$(srcdir)/../../../opcodes \
+ -I$(srcdir)/../../../include \
+ -I$(srcdir)/../../../bfd \
+ -I$(srcdir)/../../../intl \
+ -D_GNU_SOURCE
+
DEJAGNUTESTS = cpumonkey.exp dhrystone.exp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+cgen-asm.lo: ../../../opcodes/cgen-asm.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-dis.lo: ../../../opcodes/cgen-dis.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+cgen-opc.lo: ../../../opcodes/cgen-opc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+dis-buf.lo: ../../../opcodes/dis-buf.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
check-local: all
-(cd ../testsuite ; $(MAKE) check RUNTESTFLAGS="$(RUNTESTFLAGS) $(DEJAGNUTESTS)" )
for subdir in @cpu_subdirs@; do \
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2305: checking ARM family support" >&5
+echo "configure:2308: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2322: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2319: checking MIPS family support" >&5
+echo "configure:2336: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2333: checking M32R family support" >&5
+echo "configure:2350: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2347: checking M68K family support" >&5
+echo "configure:2364: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2361: checking PPC family support" >&5
+echo "configure:2378: checking PPC family support" >&5
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2404: checking for $ac_word" >&5
+echo "configure:2421: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_GUILE'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "links", so it can be a program name with args.
set dummy links; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2440: checking for $ac_word" >&5
+echo "configure:2457: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LINKS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "xsltproc", so it can be a program name with args.
set dummy xsltproc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2480: checking for $ac_word" >&5
+echo "configure:2497: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_XSLTPROC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sabcmd", so it can be a program name with args.
set dummy sabcmd; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2520: checking for $ac_word" >&5
+echo "configure:2537: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_SABLOTRON'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
+2001-08-16 graydon hoare <graydon@redhat.com>
+
+ * Makefile.am: gcc -> $(CC) fix.
+ * Makefile.in: Regenerate.
+
+2001-08-15 graydon hoare <graydon@redhat.com>
+
+ * m32rbf.cxx (step_insns): Fix for bi-endian
+ disassembly.
+
+2001-08-15 graydon hoare <graydon@redhat.com>
+
+ * m32rbf.cxx (step_insns): Add disassembly
+ tracing support.
+ * Makefile.am: Add support for building and
+ linking invididual objects from opcodes.
+ * Makefile.in: Regenerate.
+
2001-08-03 matthew green <mrg@redhat.com>
* m32rbf.h (dtor): Add throw() specifier.
libm32r_la_SOURCES = m32rbf.cxx \
m32r-decode.cxx m32r-sem.cxx
libm32r_la_LDFLAGS =
+libm32r_la_LIBADD = m32r-asm.lo m32r-dis.lo m32r-opc.lo m32r-ibld.lo m32r-desc.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+ -I../../../../opcodes \
+ -I../../../../bfd \
+ -I../../../../intl \
+ -I$(srcdir)/../../../../opcodes \
+ -I$(srcdir)/../../../../include \
+ -I$(srcdir)/../../../../bfd \
+ -I$(srcdir)/../../../../intl \
+ -D_GNU_SOURCE
+
+m32r-asm.lo: ../../../../opcodes/m32r-asm.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-dis.lo: ../../../../opcodes/m32r-dis.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-opc.lo: ../../../../opcodes/m32r-opc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-ibld.lo: ../../../../opcodes/m32r-ibld.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-desc.lo: ../../../../opcodes/m32r-desc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
DEJAGNUTESTS = m32rbsp.exp
check-local: all
m32r-decode.cxx m32r-sem.cxx
libm32r_la_LDFLAGS =
+libm32r_la_LIBADD = m32r-asm.lo m32r-dis.lo m32r-opc.lo m32r-ibld.lo m32r-desc.lo
+
+OPCODES_COMPILE_FLAGS = -DHAVE_CONFIG_H \
+ -I../../../../opcodes \
+ -I../../../../bfd \
+ -I../../../../intl \
+ -I$(srcdir)/../../../../opcodes \
+ -I$(srcdir)/../../../../include \
+ -I$(srcdir)/../../../../bfd \
+ -I$(srcdir)/../../../../intl \
+ -D_GNU_SOURCE
+
DEJAGNUTESTS = m32rbsp.exp
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
-libm32r_la_LIBADD =
+libm32r_la_DEPENDENCIES = m32r-asm.lo m32r-dis.lo m32r-opc.lo \
+m32r-ibld.lo m32r-desc.lo
libm32r_la_OBJECTS = m32rbf.lo m32r-decode.lo m32r-sem.lo
CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+m32r-asm.lo: ../../../../opcodes/m32r-asm.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-dis.lo: ../../../../opcodes/m32r-dis.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-opc.lo: ../../../../opcodes/m32r-opc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-ibld.lo: ../../../../opcodes/m32r-ibld.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
+
+m32r-desc.lo: ../../../../opcodes/m32r-desc.c
+ /bin/sh ./libtool --mode=compile $(CC) $(OPCODES_COMPILE_FLAGS) $(CFLAGS) -c $<
check-local: all
(cd ../../testsuite ; $(MAKE) check RUNTESTFLAGS="$(RUNTESTFLAGS) $(DEJAGNUTESTS)" )
.PHONY: cgen-all $(CGEN_ALL)
// Execute the instruction -----------------------------------
if (this->trace_result_p)
this->begin_trace (pc, sem->idesc->insn_name);
+ if (trace_disass_p)
+ this->disassemble (pc, print_insn_m32r,
+ bfd_target_elf_flavour,
+ bfd_arch_m32r,
+ (current_endianness() == endian_little ?
+ BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG),
+ "m32r");
try
{
sem->idesc->execute (this, sem);
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:3271: checking ARM family support" >&5
+echo "configure:3274: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:3288: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:3285: checking MIPS family support" >&5
+echo "configure:3302: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:3299: checking M32R family support" >&5
+echo "configure:3316: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:3313: checking M68K family support" >&5
+echo "configure:3330: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:3327: checking PPC family support" >&5
+echo "configure:3344: checking PPC family support" >&5
-subdirs="cfgroot tcl audio cgen-cpu families timers"
+subdirs="bochs cfgroot tcl audio cgen-cpu families timers"
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
-trap 'rm -fr `echo "Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+trap 'rm -fr `echo "Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
cache/Makefile
consoles/Makefile
gdb/Makefile
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
cat >> $CONFIG_STATUS <<EOF
-CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
cache/Makefile
consoles/Makefile
gdb/Makefile
esac
done
- for ac_config_dir in cfgroot tcl audio cgen-cpu families timers; do
+ for ac_config_dir in bochs cfgroot tcl audio cgen-cpu families timers; do
# Do not complain, so a configure script can configure whichever
# parts of a large source tree are present.
dnl tcl is here because it looks for tcl/tk in a too complex way for this file.
dnl audio is here because it has more host-dependent configuration
dnl cgen-cpu is here because it has target-dependent configuration
-AC_CONFIG_SUBDIRS([cfgroot tcl audio cgen-cpu families timers])
+AC_CONFIG_SUBDIRS([bochs cfgroot tcl audio cgen-cpu families timers])
dnl List all component subdirectory files not covered by AC_CONFIG_SUBDIRS
dnl that need autoconf @substitution@.
-AC_OUTPUT([Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
+AC_OUTPUT([Makefile testsuite/Makefile tconfig.h:tconfig.in siddoc
cache/Makefile
consoles/Makefile
gdb/Makefile
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = @family_subdirs@
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2218: checking ARM family support" >&5
+echo "configure:2221: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2235: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2232: checking MIPS family support" >&5
+echo "configure:2249: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2246: checking M32R family support" >&5
+echo "configure:2263: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2260: checking M68K family support" >&5
+echo "configure:2277: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2274: checking PPC family support" >&5
+echo "configure:2291: checking PPC family support" >&5
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
+2001-10-17 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * sw-debug-gdb.xml: New file.
+ * sw-debug-gdb.txt: New file.
+ * Makefile.am: Add docs support.
+ * Makefile.in: Regenerated.
+
2001-10-16 Dave Brolley <brolley@redhat.com>
* gdb.h (target_schedulers_enabled): New vector member of class gdb.
libgdb_la_LDFLAGS = -module -no-undefined
+pkgdata_DATA = sw-debug-gdb.txt
+
+html_stylesheet=$(srcdir)/../component_html.xsl
+include $(srcdir)/../../config/Makefile.docs
# PARTICULAR PURPOSE.
+# Makefile.docs -*- Makefile -*-
+# Copyright (C) 2001 Red Hat.
+# This file is part of SID and is licensed under the GPL.
+# See the file COPYING.SID for conditions for redistribution.
+#
+# ... to be included in document-building Makefile.am's
+#
+
+
SHELL = @SHELL@
srcdir = @srcdir@
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
libgdb_la_LDFLAGS = -module -no-undefined
+
+pkgdata_DATA = sw-debug-gdb.txt
+
+html_stylesheet = $(srcdir)/../component_html.xsl
+
+SUFFIXES = .xml .txt .html
mkinstalldirs = $(SHELL) $(top_srcdir)/../config/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DATA = $(pkgdata_DATA)
+
DIST_COMMON = ChangeLog Makefile.am Makefile.in
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/gdb.P .deps/gdbserv-input.P .deps/gdbserv-output.P \
+.deps/gdbserv-state.P .deps/gdbserv-utils.P
SOURCES = $(libgdb_la_SOURCES)
OBJECTS = $(libgdb_la_OBJECTS)
all: all-redirect
.SUFFIXES:
-.SUFFIXES: .S .c .cxx .lo .o .s
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus gdb/Makefile
+.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign gdb/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.cxx.lo:
$(LTCXXCOMPILE) -c $<
+install-pkgdataDATA: $(pkgdata_DATA)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
+ @list='$(pkgdata_DATA)'; for p in $$list; do \
+ if test -f $(srcdir)/$$p; then \
+ echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p"; \
+ $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(pkgdatadir)/$$p; \
+ else if test -f $$p; then \
+ echo " $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p"; \
+ $(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
+ fi; fi; \
+ done
+
+uninstall-pkgdataDATA:
+ @$(NORMAL_UNINSTALL)
+ list='$(pkgdata_DATA)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(pkgdatadir)/$$p; \
+ done
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
subdir = gdb
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign gdb/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
-install-data-am:
+install-data-am: install-pkgdataDATA
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
-uninstall-am: uninstall-pkglibLTLIBRARIES
+uninstall-am: uninstall-pkglibLTLIBRARIES uninstall-pkgdataDATA
uninstall: uninstall-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile $(LTLIBRARIES) $(DATA)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
- $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+ $(mkinstalldirs) $(DESTDIR)$(pkglibdir) $(DESTDIR)$(pkgdatadir)
mostlyclean-generic:
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
uninstall-pkglibLTLIBRARIES install-pkglibLTLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
-clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
-
+clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
+install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@ xsltproc --output $@ $(html_stylesheet) $<
+
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_FALSE@@HAVE_SABLOTRON_TRUE@.xml.html:
+@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_FALSE@@HAVE_SABLOTRON_TRUE@ sabcmd $(html_stylesheet) $< $@
+
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@.html.txt:
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@ links -dump $< > $@
+@MAINTAINER_MODE_TRUE@@HAVE_LINKS_TRUE@ cp $@ $(srcdir)/$@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
--- /dev/null
+ sw-debug-gdb (libgdb.la :: gdb_component_library)
+
+Synopsis:
+
+ The gdb component is an implementation of the GDB stub.
+
+ ----------------------------------------------------------------------
+
+Functionality:
+
+ Modelling:
+
+ The gdb component communicates with other components through its pins, and
+ also through four relations: a cpu uni-relation, a gloss uni-relation, a
+ target-schedulers multi-relation and a host-schedulers multi-relation.
+
+ Note that in sid, "turning the target power on or off" means that the gdb
+ component drives its yield pin, sets the target schedulers' enabled?
+ attributes through the target-schedulers relation and sets the host
+ schedulers' yield-host-time? attributes through the host-schedulers
+ relation. See sid-sched for an explanation of these pins.
+
+ Also note that the term "hw-breakpoint" used in a sid context could mean
+ the same thing as the term "software breakpoint" in a gdb context. This is
+ because breakpoints in sid are sometimes implemented as triggerpoints set
+ on the pc register.
+
+ +-------------------------------------------------+
+ | Behaviors |
+ |-------------------------------------------------|
+ | initialization | When init is driven, target |
+ | | power is turned off. |
+ | | Basically, this means the |
+ | | target will wait for further |
+ | | input from gdb. |
+ |------------------+------------------------------|
+ | execution | When the gdb component wants |
+ | | the target system to yield, |
+ | | it drives the yield pin. |
+ | | Likewise, it will drive the |
+ | | restart pin to restart the |
+ | | target system. The restart |
+ | | pin is typically connected |
+ | | to a hw-reset |
+ | | hw-glue-sequence component |
+ | | that has connections to any |
+ | | of the target components |
+ | | that need to be reset. |
+ | | |
+ | | When the start-target pin is |
+ | | driven, the target power |
+ | | will be turned on. The |
+ | | start-target pin should be |
+ | | driven by a sid-side |
+ | | component that wants the |
+ | | target cpu to start again. |
+ | | Use this pin with caution; |
+ | | driving it could upset an |
+ | | attached external debugger. |
+ | | |
+ | | The stop-target pin should |
+ | | be driven from a sid-side |
+ | | component that wants to stop |
+ | | the target cpu. This pin |
+ | | will be ignored if there are |
+ | | signals pending. |
+ | | |
+ | | When gdb itself or the gdb |
+ | | component (see the |
+ | | explanation of the |
+ | | enable-Z-packet? attribute) |
+ | | sets a software breakpoint, |
+ | | it puts the cpu's |
+ | | instruction cache out of |
+ | | sync with the actual |
+ | | contents of memory. So the |
+ | | gdb component will drive the |
+ | | flush-icache pin when it |
+ | | wants the cpu to invalidate |
+ | | its instruction cache. |
+ | | |
+ | | As long as gdb is connected |
+ | | to the gdb component, the |
+ | | connected? attribute will be |
+ | | true. |
+ |------------------+------------------------------|
+ | system call | When gdb detaches from the |
+ | emulation | gdb component, the component |
+ | | drives the process-signal |
+ | | pin. |
+ | | |
+ | | The gloss-process-signal pin |
+ | | is typically driven by a |
+ | | gloss component. It tells |
+ | | the gdb component that the |
+ | | gloss component has |
+ | | processed an exit system |
+ | | call. |
+ | | |
+ | | The gdb component's trap pin |
+ | | is usually connected to the |
+ | | gloss component's |
+ | | trap-code-chain pin. The |
+ | | gloss component sends any |
+ | | trap code that it cannot |
+ | | handle down the trap code |
+ | | chain (via the |
+ | | trap-code-chain pin), and |
+ | | any debugging-related trap |
+ | | will be handled by the gdb |
+ | | component. If the gdb |
+ | | component knows how to |
+ | | handle the trap code, it |
+ | | will handle it and then |
+ | | drive the trap pin with the |
+ | | cpu_trap_handled value. See |
+ | | sw-gloss-arm_angel and |
+ | | hw-cpu-arm7t for more |
+ | | information on trap and |
+ | | trap-code pins. |
+ |------------------+------------------------------|
+ | pin i/o | The remote-rx and remote-tx |
+ | | pins are the pins that the |
+ | | gdb component uses to |
+ | | receive data from and |
+ | | transmit data to gdb. They |
+ | | are typically connected to a |
+ | | sid-io-socket's rx and tx |
+ | | pins respectively. gdb |
+ | | connects to this |
+ | | sid-io-socket component via |
+ | | TCP, and can then be used |
+ | | just as if it were debugging |
+ | | a normal remote target. |
+ | | |
+ | | The target-tx pin is used to |
+ | | transmit characters coming |
+ | | from the target's standard |
+ | | out back to gdb. These |
+ | | characters are transmitted |
+ | | using an "O" packet. |
+ |------------------+------------------------------|
+ | deinitialization | When the deinit pin is |
+ | | driven, the gdb component |
+ | | disconnects from gdb. |
+ |------------------+------------------------------|
+ | setting | When set to true, the |
+ | | trace-gdbsid? and |
+ | | trace-gdbserv? attributes |
+ | | turn on trace messages for |
+ | | the gdb component member |
+ | | functions and the stub |
+ | | functions respectively. |
+ | | Trace messages are printed |
+ | | to stderr. |
+ | | |
+ | | When the exit-on-detach? |
+ | | attribute is true, the gdb |
+ | | component drives its |
+ | | process-signal pin when gdb |
+ | | detaches from the target. |
+ | | |
+ | | When the enable-Z-packet? |
+ | | attribute is true, the gdb |
+ | | component recognizes Z |
+ | | packets that it receives |
+ | | from gdb, and sets |
+ | | breakpoints according to |
+ | | their contents. If the |
+ | | enable-Z-packet? attribute |
+ | | is false, then gdb sets |
+ | | breakpoints directly using |
+ | | the read memory (m) and |
+ | | write memory (M) packets. |
+ | | |
+ | | The Z-packet-pc-mask |
+ | | attribute is used when |
+ | | passing Harvard-encoded PC |
+ | | addresses to the gdb |
+ | | component via a Z packet. |
+ | | |
+ | | When the operating-mode? |
+ | | attribute is true, the gdb |
+ | | component doesn't handle any |
+ | | cpu traps except for single |
+ | | stepping. |
+ +-------------------------------------------------+
+
+ +-------------------------------------------------+
+ | SID Conventions |
+ |-------------------------------------------------|
+ | functional | supported | - |
+ |--------------------+--------------------+-------|
+ | save/restore | not supported | - |
+ |--------------------+--------------------+-------|
+ | triggerpoints | supported | - |
+ +-------------------------------------------------+
+
+ ----------------------------------------------------------------------
+
+Environment:
+
+ Related Components
+
+ The gdb component connects to many other sid components:
+ * target memory to inspect and set values there
+ * the cpu to set triggerpoints, and to view register values
+ * a gloss component that sends it trap codes
+ * hw-glue-sequences so that it is initialized and deinitialized at the
+ proper times
+ * schedulers to change control between the target and the host
+ * a sid-io-socket component to interface with gdb via TCP
+
+ Host System
+
+ The gdb component prints error and tracing messages to stderr.
+
+ ----------------------------------------------------------------------
+
+Component Reference:
+
+ Component: sw-debug-gdb
+
+ +-----------------------------------------------------------+
+ | pins |
+ |-----------------------------------------------------------|
+ | name |direction|legalvalues| behaviors |
+ |--------------------+---------+-----------+----------------|
+ |init |in |any |initialization |
+ |--------------------+---------+-----------+----------------|
+ |remote-rx |in |any |pin i/o |
+ |--------------------+---------+-----------+----------------|
+ |remote-tx |out |any |pin i/o |
+ |--------------------+---------+-----------+----------------|
+ |target-tx |in |any |pin i/o |
+ |--------------------+---------+-----------+----------------|
+ |process-signal |out |enum values|system call |
+ | | | |emulation |
+ |--------------------+---------+-----------+----------------|
+ |gloss-process-signal|in |enum values|system call |
+ | | | |emulation |
+ |--------------------+---------+-----------+----------------|
+ |trap |inout |enum values|system call |
+ | | | |emulation |
+ |--------------------+---------+-----------+----------------|
+ |trap-code |in |various |system call |
+ | | |values |emulation |
+ |--------------------+---------+-----------+----------------|
+ |yield |out |any |execution |
+ |--------------------+---------+-----------+----------------|
+ |restart |out |any |execution |
+ |--------------------+---------+-----------+----------------|
+ |flush-icache |out |any |execution |
+ |--------------------+---------+-----------+----------------|
+ |stop-target |in |any |execution |
+ |--------------------+---------+-----------+----------------|
+ |start-target |in |any |execution |
+ |--------------------+---------+-----------+----------------|
+ |deinit |in |any |deinitialization|
+ +-----------------------------------------------------------+
+
+ +------------------------------------------------------+
+ | attributes |
+ |------------------------------------------------------|
+ | name |category| legal |default|behaviors||
+ | | | values | value | ||
+ |----------------+--------+---------+-------+---------||
+ |trace-gdbserv? |- |boolean |false |setting ||
+ |----------------+--------+---------+-------+---------||
+ |trace-gdbsid? |- |boolean |false |setting ||
+ |----------------+--------+---------+-------+---------||
+ |exit-on-detach? |- |boolean |false |setting ||
+ |----------------+--------+---------+-------+---------||
+ |enable-Z-packet?|- |boolean |true |setting ||
+ |----------------+--------+---------+-------+---------||
+ |Z-packet-pc-mask|- |number |0 |setting ||
+ |----------------+--------+---------+-------+---------||
+ |operating-mode? |- |boolean |true |setting ||
+ |----------------+--------+---------+-------+---------||
+ |connected? |- |boolean, |false |execution||
+ | | |read-only| | ||
+ +------------------------------------------------------+
+
+ ----------------------------------------------------------------------
+
+References:
+
+ Debugging with GDB
--- /dev/null
+<?xml version="1.0" ?>
+<!DOCTYPE defcomplib
+ PUBLIC "-//Red Hat//DTD Component Library//EN"
+ "http://sources.redhat.com/sid/component.dtd">
+<defcomplib lib="libgdb.la" dlsym="gdb_component_library">
+ <defcomponent name="sw-debug-gdb">
+ <!-- pins -->
+ <defpin name="init" direction="in" legalvalues="any" behaviors="initialization"/>
+ <defpin name="remote-rx" direction="in" legalvalues="any" behaviors="pin i/o"/>
+ <defpin name="remote-tx" direction="out" legalvalues="any" behaviors="pin i/o"/>
+ <defpin name="target-tx" direction="in" legalvalues="any" behaviors="pin i/o"/>
+ <defpin name="process-signal" direction="out" legalvalues="enum values" behaviors="system call emulation"/>
+ <defpin name="gloss-process-signal" direction="in" legalvalues="enum values" behaviors="system call emulation"/>
+ <defpin name="trap" direction="inout" legalvalues="enum values" behaviors="system call emulation"/>
+ <defpin name="trap-code" direction="in" legalvalues="various values" behaviors="system call emulation"/>
+ <defpin name="yield" direction="out" legalvalues="any" behaviors="execution"/>
+ <defpin name="restart" direction="out" legalvalues="any" behaviors="execution"/>
+ <defpin name="flush-icache" direction="out" legalvalues="any" behaviors="execution"/>
+ <defpin name="stop-target" direction="in" legalvalues="any" behaviors="execution"/>
+ <defpin name="start-target" direction="in" legalvalues="any" behaviors="execution"/>
+ <defpin name="deinit" direction="in" legalvalues="any" behaviors="deinitialization"/>
+ <!-- attributes -->
+ <defattribute name="trace-gdbserv?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+ <defattribute name="trace-gdbsid?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+ <defattribute name="exit-on-detach?" legalvalues="boolean" defaultvalue="false" behaviors="setting"/>
+ <defattribute name="enable-Z-packet?" legalvalues="boolean" defaultvalue="true" behaviors="setting"/>
+ <defattribute name="Z-packet-pc-mask" legalvalues="number" defaultvalue="0" behaviors="setting"/>
+ <defattribute name="operating-mode?" legalvalues="boolean" defaultvalue="true" behaviors="setting"/>
+ <defattribute name="connected?" legalvalues="boolean, read-only" defaultvalue="false" behaviors="execution"/>
+ </defcomponent>
+ <synop>
+ <p>
+ The gdb component is an implementation of the <a type="url"
+ href="http://sources.redhat.com/gdb/onlinedocs/gdb_15.html#SEC129">GDB
+ stub</a>.
+ </p>
+ </synop>
+ <func>
+ <modelling>
+ <p>
+ The gdb component communicates with other components
+ through its pins, and also through four relations: a cpu
+ uni-relation, a gloss uni-relation, a target-schedulers
+ multi-relation and a host-schedulers multi-relation.
+ </p>
+ <p>
+ Note that in sid, "turning the target power on or off" means
+ that the gdb component drives its <pin> yield</pin> pin, sets
+ the target schedulers' enabled? attributes through the
+ target-schedulers relation and sets the host schedulers'
+ yield-host-time? attributes through the host-schedulers
+ relation. See <complib>sid-sched</complib> for an explanation
+ of these pins.
+ </p>
+ <p>
+ Also note that the term "hw-breakpoint" used in a sid context
+ could mean the same thing as the term "software breakpoint" in
+ a gdb context. This is because breakpoints in sid are
+ sometimes implemented as triggerpoints set on the pc register.
+ </p>
+ </modelling>
+ <behavior name="initialization">
+ <p>
+ When <pin> init</pin> is driven, target power is turned
+ off. Basically, this means the target will wait for further
+ input from gdb.
+ </p>
+ </behavior>
+ <behavior name="execution">
+ <p>
+ When the gdb component wants the target system to yield, it
+ drives the <pin> yield</pin> pin. Likewise, it will drive the
+ <pin> restart</pin> pin to restart the target system. The
+ restart pin is typically connected to a hw-reset <complib>
+ hw-glue-sequence</complib> component that has connections to
+ any of the target components that need to be reset.
+ </p>
+ <p>
+ When the <pin> start-target</pin> pin is driven, the target
+ power will be turned on. The <pin> start-target</pin> pin
+ should be driven by a sid-side component that wants the target
+ cpu to start again. Use this pin with caution; driving it
+ could upset an attached external debugger.
+ </p>
+ <p>
+ The <pin> stop-target</pin> pin should be driven from a
+ sid-side component that wants to stop the target cpu. This pin
+ will be ignored if there are signals pending.
+ </p>
+ <p>
+ When gdb itself or the gdb component (see the explanation of
+ the <attribute> enable-Z-packet?</attribute> attribute) sets a
+ software breakpoint, it puts the cpu's instruction cache out
+ of sync with the actual contents of memory. So the gdb
+ component will drive the <pin> flush-icache</pin> pin when it
+ wants the cpu to invalidate its instruction cache.
+ </p>
+ <p>
+ As long as gdb is connected to the gdb component, the
+ <attribute> connected?</attribute> attribute will be true.
+ </p>
+ </behavior>
+ <behavior name="system call emulation">
+ <p>
+ When gdb detaches from the gdb component, the component drives
+ the <pin> process-signal</pin> pin.
+ </p>
+ <p>
+ The <pin> gloss-process-signal</pin> pin is typically driven
+ by a <complib> gloss</complib> component. It tells the gdb
+ component that the gloss component has processed an exit
+ system call.
+ </p>
+ <p>
+ The gdb component's <pin> trap</pin> pin is usually connected
+ to the gloss component's trap-code-chain pin. The gloss
+ component sends any trap code that it cannot handle down the
+ trap code chain (via the trap-code-chain pin), and any
+ debugging-related trap will be handled by the gdb
+ component. If the gdb component knows how to handle the trap
+ code, it will handle it and then drive the trap pin with the
+ cpu_trap_handled value. See <complib>
+ sw-gloss-arm_angel</complib> and <complib>
+ hw-cpu-arm7t</complib> for more information on trap and
+ trap-code pins.
+ </p>
+ </behavior>
+ <behavior name="pin i/o">
+ <p>
+ The <pin> remote-rx</pin> and <pin> remote-tx</pin> pins are
+ the pins that the gdb component uses to receive data from and
+ transmit data to gdb. They are typically connected to a
+ <complib> sid-io-socket</complib>'s rx and tx pins
+ respectively. gdb connects to this sid-io-socket component via
+ TCP, and can then be used just as if it were debugging a
+ normal remote target.
+ </p>
+ <p>
+ The <pin> target-tx</pin> pin is used to transmit characters
+ coming from the target's standard out back to gdb. These
+ characters are transmitted using an "O" packet.
+ </p>
+ </behavior>
+ <behavior name="deinitialization">
+ <p>
+ When the <pin> deinit</pin> pin is driven, the gdb component
+ disconnects from gdb.
+ </p>
+ </behavior>
+ <behavior name="setting">
+ <p>
+ When set to true, the <attribute> trace-gdbsid?</attribute>
+ and <attribute> trace-gdbserv?</attribute> attributes turn on
+ trace messages for the gdb component member functions and the
+ stub functions respectively. Trace messages are printed to
+ stderr.
+ </p>
+ <p>
+ When the <attribute> exit-on-detach?</attribute> attribute is
+ true, the gdb component drives its <pin> process-signal</pin>
+ pin when gdb detaches from the target.
+ </p>
+ <p>
+ When the <attribute> enable-Z-packet?</attribute> attribute is
+ true, the gdb component recognizes Z packets that it receives
+ from gdb, and sets breakpoints according to their contents. If
+ the <attribute> enable-Z-packet?</attribute> attribute is
+ false, then gdb sets breakpoints directly using the read
+ memory (m) and write memory (M) packets.
+ </p>
+ <p>
+ The <attribute> Z-packet-pc-mask</attribute> attribute is used
+ when passing Harvard-encoded PC addresses to the gdb component
+ via a Z packet.
+ </p>
+ <p>
+ When the <attribute> operating-mode?</attribute> attribute is
+ true, the gdb component doesn't handle any cpu traps except
+ for single stepping.
+ </p>
+ </behavior>
+ <convention name="functional" supported="true">
+ </convention>
+ <convention name="save/restore" supported="false">
+ </convention>
+ <convention name="triggerpoints" supported="true">
+ This component supports triggerpoints on the PC register.
+ </convention>
+ </func>
+ <env>
+ <title>
+ Related Components </title>
+ <p>
+ The gdb component connects to many other sid components:
+ <ul>
+ <li>
+ target memory to inspect and set values there </li>
+ <li>
+ the cpu to set triggerpoints, and to view register values </li>
+ <li>
+ a gloss component that sends it trap codes </li>
+ <li>
+ hw-glue-sequences so that it is initialized and deinitialized
+ at the proper times </li>
+ <li>
+ schedulers to change control between the target and the host </li>
+ <li>
+ a sid-io-socket component to interface with gdb via TCP </li>
+ </ul>
+ </p>
+ <title>
+ Host System </title>
+ <p>
+ The gdb component prints error and tracing
+ messages to stderr.
+ </p>
+ </env>
+ <refs>
+ <a type="url" href="http://sources.redhat.com/gdb/onlinedocs/gdb.html">Debugging with GDB</a>
+ </refs>
+</defcomplib>
(gloss32::set_halfword): Likewise.
(gloss32::do_sys_fstat): Likewise.
+2001-08-31 Ben Elliston <bje@redhat.com>
+
+ * sw-gloss-arm_angel.txt: Regenerate.
+
+2001-08-30 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * gloss.cxx: Add syscall-numbering-scheme setting.
+ * libcygmon.h: New file. It contains cygmon syscall numbers.
+ * sw-gloss-arm_angel.xml: Add syscall-numbering-scheme documentation.
+
2001-08-12 Richard Henderson <rth@redhat.com>
* gloss.cxx (gloss32::read): Fix argument type mismatch for min.
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/angel.P .deps/compGloss.P .deps/gloss.P \
+.deps/hostops.P .deps/m32r.P .deps/mips.P .deps/newlib.P
SOURCES = $(libgloss_la_SOURCES)
OBJECTS = $(libgloss_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus gloss/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign gloss/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = gloss
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign gloss/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
#include <errno.h>
#include "gloss.h"
#include "libgloss.h"
+#include "libcygmon.h"
// ??? For now. grep for newlib below.
#include "newlib.h"
#ifdef HAVE_TIMES
cpu (0),
cpu_memory_bus (0),
command_line("<unknown>"),
+ syscall_numbering_scheme("libgloss"),
max_fds(32),
verbose_p(false)
{
add_uni_relation("cpu", &this->cpu);
add_attribute("command-line", &this->command_line, "setting");
+ add_attribute("syscall-numbering-scheme", &this->syscall_numbering_scheme, "setting");
add_attribute("verbose?", &this->verbose_p, "setting");
-
+
add_attribute("max-fds", &this->max_fds, "setting");
host_ops = 0;
fd_table = 0;
\f
-// default syscall conversion routine
+// syscall conversion routine
int32
gloss32::target_to_host_syscall (int32 target_syscall)
{
- return target_syscall;
+ if(syscall_numbering_scheme == "cygmon")
+ {
+ switch(target_syscall)
+ {
+ case cygmon::SYS_exit:
+ return libgloss::SYS_exit;
+ break;
+ case cygmon::SYS_open:
+ return libgloss::SYS_open;
+ break;
+ case cygmon::SYS_close:
+ return libgloss::SYS_close;
+ break;
+ case cygmon::SYS_read:
+ return libgloss::SYS_read;
+ break;
+ case cygmon::SYS_write:
+ return libgloss::SYS_write;
+ break;
+ case cygmon::SYS_kill:
+ return libgloss::SYS_kill;
+ break;
+ case cygmon::SYS_time:
+ return libgloss::SYS_time;
+ break;
+ case cygmon::SYS_gettimeofday:
+ return libgloss::SYS_gettimeofday;
+ break;
+ default:
+ return libgloss::SYS_unsupported;
+ break;
+ };
+ }
+ else if (syscall_numbering_scheme == "libgloss")
+ {
+ return target_syscall;
+ }
+ else
+ {
+ cerr << "gloss: unsupported syscall numbering scheme. Assuming default (libgloss)" << endl;
+ syscall_numbering_scheme = "libgloss";
+ return target_syscall;
+ };
}
// System call support.
bool tmpnam (string& filename, int& errcode);
bool isatty (int fd, bool& result, int& errcode);
+ string syscall_numbering_scheme;
+
// true -> send various debugging messages to cerr.
// ??? Would be nice to be able to specify a file.
bool verbose_p;
--- /dev/null
+// libcygmon.h - Interface details for Cygnus' cygmon. -*- C++ -*-
+
+// Copyright (C) 1999, 2000 Red Hat.
+// This file is part of SID and is licensed under the GPL.
+// See the file COPYING.SID for conditions for redistribution.
+
+// System call numbers must be synchronised with:
+// libgloss/i386/cygmon-syscall.h
+
+#ifndef CYGMON_H
+#define CYGMON_H
+
+class cygmon
+{
+public:
+
+ enum cygmon_syscall
+ {
+ SYS_exit = 1,
+ SYS_open = 5,
+ SYS_close = 6,
+ SYS_read = 3,
+ SYS_write = 4,
+ SYS_kill = 37,
+ SYS_time = 13,
+ SYS_gettimeofday = 156
+ };
+};
+
+#endif // CYGMON_H
SYS_utime = 17,
SYS_time = 18,
SYS_gettimeofday = 19,
- SYS_times = 20
+ SYS_times = 20,
+ SYS_unsupported = 99 // arbitrary syscall number, unsupported by default gloss component
};
};
| | tracing messages will be |
| | printed to stderr during a |
| | system call emulation. |
+ | | |
+ | | The syscall-numbering-scheme |
+ | | setting causes the gloss |
+ | | component to use the system |
+ | | call numbering scheme |
+ | | specified. The gloss component |
+ | | may then properly interpret |
+ | | non-standard syscall numbers |
+ | | that come from target-program |
+ | | libgloss routines. Currently, |
+ | | the only available |
+ | | non-standard numbering scheme |
+ | | is cygmon. |
|----------------+--------------------------------|
| initialization | When the reset pin is driven, |
| | all open files are closed and |
|debug-rx |in |0-255 |stdio |
+---------------------------------------------------+
- +-------------------------------------------------------------+
- | attributes |
- |-------------------------------------------------------------|
- | name |category| legal | default value | behaviors ||
- | | |values | | ||
- |------------+--------+-------+---------------+--------------||
- |verbose? |setting |boolean|false |system call ||
- | | | | |emulation ||
- |------------+--------+-------+---------------+--------------||
- |heap-base |setting |number |0x80000 |initialization||
- |------------+--------+-------+---------------+--------------||
- |heap-limit |setting |number |1024 |initialization||
- |------------+--------+-------+---------------+--------------||
- |stack-base |setting |number |0x200000 |initialization||
- |------------+--------+-------+---------------+--------------||
- |stack-limit |setting |number |0x200000 |initialization||
- |------------+--------+-------+---------------+--------------||
- |command-line|setting |any |'' |initialization||
- |------------+--------+-------+---------------+--------------||
- |max-fds |setting |number |32 |initialization||
- |------------+--------+-------+---------------+--------------||
- |'tk tty' |gui |- |'hw-visual-tty'|component gui ||
- +-------------------------------------------------------------+
+ +-------------------------------------------------------------------------+
+ | attributes |
+ |-------------------------------------------------------------------------|
+ | name |category| legal | default value | behaviors ||
+ | | |values | | ||
+ |------------------------+--------+-------+---------------+--------------||
+ |verbose? |setting |boolean|false |system call ||
+ | | | | |emulation ||
+ |------------------------+--------+-------+---------------+--------------||
+ |syscall-numbering-scheme|setting |string |libgloss |system call ||
+ | | | | |emulation ||
+ |------------------------+--------+-------+---------------+--------------||
+ |heap-base |setting |number |0x80000 |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |heap-limit |setting |number |1024 |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |stack-base |setting |number |0x200000 |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |stack-limit |setting |number |0x200000 |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |command-line |setting |any |'' |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |max-fds |setting |number |32 |initialization||
+ |------------------------+--------+-------+---------------+--------------||
+ |'tk tty' |gui |- |'hw-visual-tty'|component gui ||
+ +-------------------------------------------------------------------------+
+-------------------------------------------------+
| accessors |
<!-- attributes -->
<defattribute name="verbose?" category="setting" legalvalues="boolean" defaultvalue="false" behaviors="system call emulation" />
+ <defattribute name="syscall-numbering-scheme" category="setting" legalvalues="string" defaultvalue="libgloss" behaviors="system call emulation" />
<defattribute name="heap-base" category="setting" legalvalues="number" defaultvalue="0x80000" behaviors="initialization" />
<defattribute name="heap-limit" category="setting" legalvalues="number" defaultvalue="1024" behaviors="initialization" />
<defattribute name="stack-base" category="setting" legalvalues="number" defaultvalue="0x200000" behaviors="initialization" />
output pin is driven with an exit code similar to that used by
UNIX <tt>wait(2)</tt>. Such conditions include memory faults,
invalid instructions, etc.
-
</p>
<p> See the documentation of <complib>hw-cpu-arm7t</complib> for
the list of supported trap & trap-code values.
true value, detailed tracing messages will be printed to
stderr during a system call emulation.
</p>
+ <p> The <attribute>syscall-numbering-scheme</attribute> setting causes the gloss component to use the
+ system call numbering scheme specified. The gloss component may then properly interpret non-standard syscall
+ numbers that come from target-program libgloss routines. Currently, the only available non-standard
+ numbering scheme is cygmon.
+ </p>
+
</behavior>
<behavior name="initialization">
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/compIDE.P
SOURCES = $(libide_la_SOURCES)
OBJECTS = $(libide_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus ide/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign ide/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = ide
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign ide/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/arm.P .deps/cma222.P .deps/components.P
SOURCES = $(libinterrupt_la_SOURCES)
OBJECTS = $(libinterrupt_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus interrupt/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign interrupt/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = interrupt
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign interrupt/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/HD44780U.P .deps/T6963C.P .deps/lcd-char-display.P \
+.deps/rom-5X10.P .deps/rom-europe.P .deps/rom-japan.P \
+.deps/rom-t6963c.P .deps/rom.P
SOURCES = $(libhd44780u_la_SOURCES) $(libt6963c_la_SOURCES) $(liblcd_char_display_la_SOURCES)
OBJECTS = $(libhd44780u_la_OBJECTS) $(libt6963c_la_OBJECTS) $(liblcd_char_display_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus lcd/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign lcd/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
subdir = lcd
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign lcd/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| exit 1; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
-install-info-am:
-install-info: install-info-recursive
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-recursive
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check-local check check-am installcheck-am installcheck \
-install-info-am install-info install-exec-am install-exec \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
* Makefile.am (all-local): Tolerate $srcdir==$builddir.
2001-03-23 John Healy <jhealy@redhat.com>
-
+
* Makefile.in: Regenerated.
2001-01-15 Frank Ch. Eigler <fche@redhat.com>
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/compLoader.P .deps/elfload.P
SOURCES = $(libloader_la_SOURCES)
OBJECTS = $(libloader_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus loader/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign loader/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = loader
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign loader/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
-installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi check \
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/compMapper.P
SOURCES = $(libmapper_la_SOURCES)
OBJECTS = $(libmapper_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus mapper/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign mapper/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
subdir = mapper
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mapper/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| exit 1; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
-install-info-am:
-install-info: install-info-recursive
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-recursive
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check-local check check-am installcheck-am installcheck \
-install-info-am install-info install-exec-am install-exec \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check-local check \
+check-am installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
+2001-08-03 matthew green <mrg@redhat.com>
+
+ * busif.cxx (dtor): Add throw() specifier.
+
2001-03-23 John Healy <jhealy@redhat.com>
* Makefile.in: Regenerated.
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/busif.P
SOURCES = $(libbusif_la_SOURCES)
OBJECTS = $(libbusif_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .lo .o .s
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus mapper/testsuite/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign mapper/testsuite/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
maintainer-clean-noinstLTLIBRARIES:
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = mapper/testsuite
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mapper/testsuite/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am:
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/am29.P .deps/at29.P .deps/components.P .deps/flash.P \
+.deps/generic.P .deps/ramrom.P
SOURCES = $(libmemory_la_SOURCES)
OBJECTS = $(libmemory_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus memory/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign memory/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = memory
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign memory/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/armRemap.P
SOURCES = $(libmmu_la_SOURCES)
OBJECTS = $(libmmu_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus mmu/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign mmu/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = mmu
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign mmu/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/ps2.P
SOURCES = $(libparport_la_SOURCES)
OBJECTS = $(libparport_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus parport/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign parport/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = parport
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign parport/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/gprof.P
SOURCES = $(libprof_la_SOURCES)
OBJECTS = $(libprof_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus profiling/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign profiling/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = profiling
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign profiling/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/components.P .deps/ds1x42.P .deps/sidrtc.P
SOURCES = $(librtc_la_SOURCES)
OBJECTS = $(librtc_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus rtc/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign rtc/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = rtc
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign rtc/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/compSched.P
SOURCES = $(libsched_la_SOURCES)
OBJECTS = $(libsched_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus sched/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign sched/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = sched
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign sched/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-local
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool uninstall-pkgdataDATA \
install-pkgdataDATA tags mostlyclean-tags distclean-tags clean-tags \
-maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
+maintainer-clean-tags distdir mostlyclean-depend distclean-depend \
+clean-depend maintainer-clean-depend info-am info dvi-am dvi \
+check-local check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
// Enumerate available sid component families.
#define SIDTARGET_ARM @sidtarget_arm@
+#define SIDTARGET_X86 @sidtarget_x86@
#define SIDTARGET_MIPS @sidtarget_mips@
#define SIDTARGET_M32R @sidtarget_m32r@
#define SIDTARGET_M68K @sidtarget_m68k@
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign dejagnu
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus testsuite/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
subdir = testsuite
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign testsuite/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
check-DEJAGNU: site.exp
srcdir=`cd $(srcdir) && pwd`; export srcdir; \
EXPECT=$(EXPECT); export EXPECT; \
- if [ -f $(top_builddir)/../expect/expect ]; then \
- TCL_LIBRARY=`cd $(top_srcdir)/../tcl/library && pwd`; \
- export TCL_LIBRARY; \
- fi; \
runtest=$(RUNTEST); \
if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
$$runtest $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
info: info-am
dvi-am:
dvi: dvi-am
-check-am:
+check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am:
install-exec: install-exec-am
maintainer-clean: maintainer-clean-am
.PHONY: tags distdir check-DEJAGNU info-am info dvi-am dvi check \
-check-am installcheck-am installcheck install-info-am install-info \
-install-exec-am install-exec install-data-am install-data install-am \
-install uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+check-am installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = @cpu_subdirs@ .
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2265: checking ARM family support" >&5
+echo "configure:2268: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2282: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2279: checking MIPS family support" >&5
+echo "configure:2296: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2293: checking M32R family support" >&5
+echo "configure:2310: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2307: checking M68K family support" >&5
+echo "configure:2324: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2321: checking PPC family support" >&5
+echo "configure:2338: checking PPC family support" >&5
# Extract the first word of "links", so it can be a program name with args.
set dummy links; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2360: checking for $ac_word" >&5
+echo "configure:2377: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LINKS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "xsltproc", so it can be a program name with args.
set dummy xsltproc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2400: checking for $ac_word" >&5
+echo "configure:2417: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_XSLTPROC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "sabcmd", so it can be a program name with args.
set dummy sabcmd; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2440: checking for $ac_word" >&5
+echo "configure:2457: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_SABLOTRON'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/Uart.P
SOURCES = $(libuart_la_SOURCES)
OBJECTS = $(libuart_la_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .html .lo .o .s .txt .xml
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../config/Makefile.docs
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus uart/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign uart/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
subdir = uart
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign uart/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| exit 1; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
-check-am:
+check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
-install-info-am:
-install-info: install-info-recursive
install-exec-am: install-pkglibLTLIBRARIES
install-exec: install-exec-recursive
maintainer-clean-generic:
mostlyclean-am: mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-pkglibLTLIBRARIES clean-compile clean-libtool \
- clean-tags clean-generic mostlyclean-am
+ clean-tags clean-depend clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-pkglibLTLIBRARIES distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-pkglibLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
-distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs-am installdirs mostlyclean-generic distclean-generic \
-clean-generic maintainer-clean-generic clean mostlyclean distclean \
-maintainer-clean
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
@MAINTAINER_MODE_TRUE@@HAVE_XSLTPROC_TRUE@.xml.html:
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
socket_libs = @socket_libs@
AUTOMAKE_OPTIONS = foreign
TAR = gtar
GZIP_ENV = --best
+DEP_FILES = .deps/Devices.P .deps/driver.P
SOURCES = $(uart_driver_SOURCES)
OBJECTS = $(uart_driver_OBJECTS)
.SUFFIXES:
.SUFFIXES: .S .c .cxx .lo .o .s
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --cygnus uart/testsuite/Makefile
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign uart/testsuite/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
maintainer-clean-checkPROGRAMS:
-.c.o:
- $(COMPILE) -c $<
-
.s.o:
$(COMPILE) -c $<
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
subdir = uart/testsuite
distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign uart/testsuite/Makefile
@for file in $(DISTFILES); do \
- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+
+%.o: %.cxx
+ @echo '$(CXXCOMPILE) -c $<'; \
+ $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.cxx
+ @echo '$(LTCXXCOMPILE) -c $<'; \
+ $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
check-TESTS: $(TESTS)
@failed=0; all=0; \
srcdir=$(srcdir); export srcdir; \
info: info-am
dvi-am:
dvi: dvi-am
-check-am: $(check_PROGRAMS)
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
installcheck-am:
installcheck: installcheck-am
-install-info-am:
-install-info: install-info-am
install-exec-am:
install-exec: install-exec-am
maintainer-clean-generic:
mostlyclean-am: mostlyclean-checkPROGRAMS mostlyclean-compile \
- mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-checkPROGRAMS clean-compile clean-libtool clean-tags \
- clean-generic mostlyclean-am
+ clean-depend clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-checkPROGRAMS distclean-compile \
- distclean-libtool distclean-tags distclean-generic \
- clean-am
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-checkPROGRAMS \
maintainer-clean-compile maintainer-clean-libtool \
- maintainer-clean-tags maintainer-clean-generic \
- distclean-am
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
distclean-compile clean-compile maintainer-clean-compile \
mostlyclean-libtool distclean-libtool clean-libtool \
maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
-clean-tags maintainer-clean-tags distdir check-TESTS info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-info-am \
-install-info install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend check-TESTS \
+info-am info dvi-am dvi check check-am installcheck-am installcheck \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
* libstdc++.m4: Reject shared libstdc++ possibility if g++ replies with
no path to "--print-file-name=libstdc++.a".
+2001-09-14 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * sidtargets.m4: Add x86 support.
+
2001-07-11 Frank Ch. Eigler <fche@redhat.com>
* Makefile.docs: Support xsltproc; prefer it to sabcmd.
# pull out "--enable-targets"/"--target" settings
global sidtarget
set sidtarget(arm) @sidtarget_arm@
+set sidtarget(x86) @sidtarget_x86@
set sidtarget(mips) @sidtarget_mips@
set sidtarget(m32r) @sidtarget_m32r@
set sidtarget(m68k) @sidtarget_m68k@
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:1438: checking ARM family support" >&5
+echo "configure:1441: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:1455: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:1452: checking MIPS family support" >&5
+echo "configure:1469: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:1466: checking M32R family support" >&5
+echo "configure:1483: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:1480: checking M68K family support" >&5
+echo "configure:1497: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:1494: checking PPC family support" >&5
+echo "configure:1511: checking PPC family support" >&5
echo $ac_n "checking whether can build shared SID component libraries""... $ac_c" 1>&6
-echo "configure:1510: checking whether can build shared SID component libraries" >&5
+echo "configure:1527: checking whether can build shared SID component libraries" >&5
if eval "test \"`echo '$''{'ac_cv_libstdcxx_shared'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo "configure: warning: Cannot test for libstdc++ without g++" 1>&2
else
echo $ac_n "checking for libstdc++ {static/shared}""... $ac_c" 1>&6
-echo "configure:1523: checking for libstdc++ {static/shared}" >&5
+echo "configure:1540: checking for libstdc++ {static/shared}" >&5
stlibname=libstdc++.a
case ${host} in
+
subdirs="include component main bsp samples demos"
trap '' 1 2 15
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
AC_SUBST(enable_shared)
AC_SUBST(target)
+
AC_CONFIG_SUBDIRS(include component main bsp samples demos)
AC_OUTPUT(Makefile config/info.tcl)
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
+2001-11-15 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * sid-guide/book-sid.sgml: Add example to Using GDB
+ section.
+
2001-10-16 Frank Ch. Eigler <fche@redhat.com>
* *-guide/images/*.png: New files, replacing ...
has a bus named "data-bus" through which it expects to
receive read/write requests. The scenario is depicted blow.
</PARA>
-<GRAPHIC FILEREF="images/accessor-bus.png" SCALE="55"></GRAPHIC>
+<GRAPHIC FILEREF="images/accessor-bus.png"></GRAPHIC>
<PARA> Recall that the accessor is the <EMPHASIS>sending</EMPHASIS>
end of the connection we wish to make, and that the bus is
the <EMPHASIS>receiving</EMPHASIS> end. Some people find the
debug the simulation exactly as if it were a "real" target
environment.
</PARA>
-<PARA>Configuring the GDB stub and socket components is somewhat
- lengthy and verbose, but is performed automatically by the
- <FILENAME>configrun-sid</FILENAME> command when
- invoked with the
- <FILENAME>---gdb=<REPLACEABLE>PORT</REPLACEABLE></FILENAME>
- option. For complete details of the connection process, see
+<EXAMPLE>
+<TITLE>Debugging a Program Running in SID</TITLE>
+<SCREEN>
+% <USERINPUT>i386-elf-sid --gdb=2345&</USERINPUT>
+[1] 25135
+% <USERINPUT>i386-elf-gdb -nw hello</USERINPUT>
+GNU gdb 2001-10-12-cvs (MI_OUT)
+Copyright 2001 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty" for details.
+This GDB was configured as "--host=i686-pc-linux-gnu --target=i386-elf"...
+(gdb) <USERINPUT>target remote :2345</USERINPUT>
+Remote debugging using :2345
+0x0000fff0 in ?? ()
+(gdb) <USERINPUT>load</USERINPUT>
+Loading section .text, size 0x5994 lma 0x100000
+Loading section .data, size 0x78c lma 0x1059a0
+Loading section .rodata, size 0x2c9 lma 0x106140
+Start address 0x100000, load size 25577
+Transfer rate: 102308 bits/sec, 97 bytes/write.
+(gdb) <USERINPUT>continue</USERINPUT>
+Continuing.
+Hello, World
+
+Program exited normally.
+(gdb)
+</SCREEN>
+</EXAMPLE>
+<PARA>Configuring the GDB stub and I/O socket components is
+ somewhat lengthy and verbose, but is performed automatically by
+ the <FILENAME>configrun-sid</FILENAME> command when invoked with
+ the <FILENAME>--gdb=<REPLACEABLE>PORT</REPLACEABLE></FILENAME>
+ option, as in the above example. For a detailed description of
+ the GDB stub component's pins and attributes, see
<FILENAME>siddoc sw-debug-gdb</FILENAME>.
</PARA>
</SECT2>
(basic_cpu ctor): Initialize them.
(cg_profile): New function.
+2001-10-12 Thomas Fitzsimmons <fitzsim@redhat.com>
+
+ * sidcpuutil.h (sidutil): Clarified expedited_regno_list comment.
+
2001-10-04 Frank Ch. Eigler <fche@redhat.com>
* sidcpuutil.h (basic_cpu ctor): Initialize those tracing flags.
this->triggerpoint_manager.add_watchable_value ("gdb-register-pc", pc);
this->add_attribute_ro_value ("gdb-num-registers", count, "debugger");
- // The "expedited" register list string is the list of
+ // The "expedited" register list string is the semi-colon-delimited list of
// register numbers that should be sent to gdb immediately
// every time sid stops, rather than let gdb ask for it
// subsequently. Usually, the PC, frame and stack pointer,
// and status register should be included in the list. It
// makes gdb step operations much faster.
+ // The register numbering scheme is that decided by gdb.
this->add_attribute_ro_value ("gdb-exp-registers", expedited_regno_list, "debugger");
for (sid::host_int_4 i=0; i<count; i++)
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
2001-10-05 Frank Ch. Eigler <fche@redhat.com>
- * mainDynamic.cxx (version): New function. Use SID_VERSION from
- new version.h file.
- (main): Support "-v" option to print this information.
- * Makefile.am (sid_DEPENDENCIES): List version.h.
- * configure, Makefile.in: Regenerated.
+ * mainDynamic.cxx (version): New function. Use SID_VERSION from
+ new version.h file.
+ (main): Support "-v" option to print this information.
+ * Makefile.am (sid_DEPENDENCIES): List version.h.
+ * configure, Makefile.in: Regenerated.
+
+2001-09-18 Frank Ch. Eigler <fche@redhat.com>
+
+ * Makefile.am (NEARBY_LIBS, NEARBY_DEPS_LIBS): Add bochs/libx86.la.
+ * Makefile.in: Regenerated.
2001-07-24 Frank Ch. Eigler <fche@redhat.com>
-dlpreopen ../../component/cache/libcache.la \
-dlpreopen ../../component/cfgroot/libconfig.la \
-dlpreopen ../../component/cgen-cpu/libcgencpu.la \
+ -dlpreopen ../../component/bochs/libx86.la \
-dlpreopen ../../component/consoles/libconsoles.la \
$(ALLFAMLIBS2) \
-dlpreopen ../../component/gdb/libgdb.la \
../../component/cache/libcache.la \
../../component/cfgroot/libconfig.la \
../../component/cgen-cpu/libcgencpu.la \
+ ../../component/bochs/libx86.la \
../../component/consoles/libconsoles.la \
$(ALLFAMLIBS) \
../../component/gdb/libgdb.la \
sidtarget_m68k = @sidtarget_m68k@
sidtarget_mips = @sidtarget_mips@
sidtarget_ppc = @sidtarget_ppc@
+sidtarget_x86 = @sidtarget_x86@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I $(srcdir)/../../config
@SID_STATIC_TRUE@ -dlpreopen ../../component/cache/libcache.la \
@SID_STATIC_TRUE@ -dlpreopen ../../component/cfgroot/libconfig.la \
@SID_STATIC_TRUE@ -dlpreopen ../../component/cgen-cpu/libcgencpu.la \
+@SID_STATIC_TRUE@ -dlpreopen ../../component/bochs/libx86.la \
@SID_STATIC_TRUE@ -dlpreopen ../../component/consoles/libconsoles.la \
@SID_STATIC_TRUE@ $(ALLFAMLIBS2) \
@SID_STATIC_TRUE@ -dlpreopen ../../component/gdb/libgdb.la \
@SID_STATIC_TRUE@ ../../component/cache/libcache.la \
@SID_STATIC_TRUE@ ../../component/cfgroot/libconfig.la \
@SID_STATIC_TRUE@ ../../component/cgen-cpu/libcgencpu.la \
+@SID_STATIC_TRUE@ ../../component/bochs/libx86.la \
@SID_STATIC_TRUE@ ../../component/consoles/libconsoles.la \
@SID_STATIC_TRUE@ $(ALLFAMLIBS) \
@SID_STATIC_TRUE@ ../../component/gdb/libgdb.la \
AC_MSG_WARN(Assuming --enable-targets=all)
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
dnl Enumerate known chip families
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
dnl Ensure at least one of these variables is non-zero.
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
AM_CONDITIONAL(SIDTARGET_ARM,[test "x$sidtarget_arm" = x1])
AC_MSG_RESULT($sidtarget_arm)
+AC_MSG_CHECKING(X86 family support)
+AC_SUBST(sidtarget_x86)
+AM_CONDITIONAL(SIDTARGET_X86,[test "x$sidtarget_x86" = x1])
+AC_MSG_RESULT($sidtarget_x86)
+
AC_MSG_CHECKING(MIPS family support)
AC_SUBST(sidtarget_mips)
AM_CONDITIONAL(SIDTARGET_MIPS,[test "x$sidtarget_mips" = x1])
echo "configure: warning: Assuming --enable-targets=all" 1>&2
all_targets=""
sidtarget_default=1
-else
+else
all_targets="$target"
sidtarget_default=0
fi
sidtarget_arm=$sidtarget_default
+sidtarget_x86=$sidtarget_default
sidtarget_mips=$sidtarget_default
sidtarget_m32r=$sidtarget_default
sidtarget_m68k=$sidtarget_default
case "$targ" in
arm*) sidtarget_arm=1 ;;
thumb*) sidtarget_arm=1 ;;
+ i386*) sidtarget_x86=1 ;;
mips*) sidtarget_mips=1 ;;
m32r*) sidtarget_m32r=1 ;;
m68k*) sidtarget_m68k=1 ;;
case 1 in
${sidtarget_arm}) ;;
+ ${sidtarget_x86}) ;;
${sidtarget_mips}) ;;
${sidtarget_m32r}) ;;
${sidtarget_m68k}) ;;
echo $ac_n "checking ARM family support""... $ac_c" 1>&6
-echo "configure:2234: checking ARM family support" >&5
+echo "configure:2180: checking ARM family support" >&5
fi
echo "$ac_t""$sidtarget_arm" 1>&6
+echo $ac_n "checking X86 family support""... $ac_c" 1>&6
+echo "configure:2194: checking X86 family support" >&5
+
+
+
+if test "x$sidtarget_x86" = x1; then
+ SIDTARGET_X86_TRUE=
+ SIDTARGET_X86_FALSE='#'
+else
+ SIDTARGET_X86_TRUE='#'
+ SIDTARGET_X86_FALSE=
+fi
+echo "$ac_t""$sidtarget_x86" 1>&6
+
echo $ac_n "checking MIPS family support""... $ac_c" 1>&6
-echo "configure:2264: checking MIPS family support" >&5
+echo "configure:2208: checking MIPS family support" >&5
echo "$ac_t""$sidtarget_mips" 1>&6
echo $ac_n "checking M32R family support""... $ac_c" 1>&6
-echo "configure:2278: checking M32R family support" >&5
+echo "configure:2222: checking M32R family support" >&5
echo "$ac_t""$sidtarget_m32r" 1>&6
echo $ac_n "checking M68K family support""... $ac_c" 1>&6
-echo "configure:2292: checking M68K family support" >&5
+echo "configure:2236: checking M68K family support" >&5
echo "$ac_t""$sidtarget_m68k" 1>&6
echo $ac_n "checking PPC family support""... $ac_c" 1>&6
-echo "configure:2322: checking PPC family support" >&5
+echo "configure:2250: checking PPC family support" >&5
s%@sidtarget_arm@%$sidtarget_arm%g
s%@SIDTARGET_ARM_TRUE@%$SIDTARGET_ARM_TRUE%g
s%@SIDTARGET_ARM_FALSE@%$SIDTARGET_ARM_FALSE%g
+s%@sidtarget_x86@%$sidtarget_x86%g
+s%@SIDTARGET_X86_TRUE@%$SIDTARGET_X86_TRUE%g
+s%@SIDTARGET_X86_FALSE@%$SIDTARGET_X86_FALSE%g
s%@sidtarget_mips@%$sidtarget_mips%g
s%@SIDTARGET_MIPS_TRUE@%$SIDTARGET_MIPS_TRUE%g
s%@SIDTARGET_MIPS_FALSE@%$SIDTARGET_MIPS_FALSE%g
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
+AR = @AR@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
EXEEXT = @EXEEXT@
+LD = @LD@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+NM = @NM@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
fi])
-# serial 40 AC_PROG_LIBTOOL
+# serial 41 AC_PROG_LIBTOOL
AC_DEFUN(AC_PROG_LIBTOOL,
[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
AC_CACHE_SAVE
# Actually configure libtool. ac_aux_dir is where install-sh is found.
-CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
|| AC_MSG_ERROR([libtool configure failed])
# Reload cache, that may have been modified by ltconfig
AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-AC_REQUIRE([AC_PROG_RANLIB])dnl
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_PROG_LD])dnl
AC_REQUIRE([AC_PROG_NM])dnl
AC_REQUIRE([AC_PROG_LN_S])dnl
dnl
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
# Check for any special flags to pass to ltconfig.
libtool_flags="--cache-file=$cache_file"
test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+AC_ARG_WITH(pic,
+ [ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+ pic_mode="$withval", pic_mode=default)
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case "$host" in
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([DllMain (0, 0, 0);],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);],
+ [lt_cv_need_dllmain=yes],[lt_cv_need_dllmain=no])])
+
+ case $host in
+ *-*-cygwin*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ *-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ esac
;;
-])
+ ])
esac
])
if test "$ac_cv_prog_gcc" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
- ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
case "$ac_prog" in
# Accept absolute paths.
changequote(,)dnl
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
AC_PROG_LD_GNU
])
fi])
NM="$ac_cv_path_NM"
AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
])
# AC_CHECK_LIBM - check for math library
--with-gnu-ld assume the C compiler uses GNU ld [default=no]"
ac_help="$ac_help
--disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
# Initialize some variables set by options.
# The variables have the same names as the options, with
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:580: checking for a BSD compatible install" >&5
+echo "configure:582: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:633: checking whether build environment is sane" >&5
+echo "configure:635: checking whether build environment is sane" >&5
# Just in case
sleep 1
echo timestamp > conftestfile
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:690: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:692: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
missing_dir=`cd $ac_aux_dir && pwd`
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:736: checking for working aclocal" >&5
+echo "configure:738: checking for working aclocal" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
fi
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:749: checking for working autoconf" >&5
+echo "configure:751: checking for working autoconf" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
fi
echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:762: checking for working automake" >&5
+echo "configure:764: checking for working automake" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
fi
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:775: checking for working autoheader" >&5
+echo "configure:777: checking for working autoheader" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
fi
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:788: checking for working makeinfo" >&5
+echo "configure:790: checking for working makeinfo" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:806: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:808: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:905: checking host system type" >&5
+echo "configure:907: checking host system type" >&5
host_alias=$host
case "$host_alias" in
echo "$ac_t""$host" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:926: checking build system type" >&5
+echo "configure:928: checking build system type" >&5
build_alias=$build
case "$build_alias" in
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$build" 1>&6
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:946: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$RANLIB"; then
- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
-fi
-fi
-RANLIB="$ac_cv_prog_RANLIB"
-if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:976: checking for $ac_word" >&5
+echo "configure:948: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1006: checking for $ac_word" >&5
+echo "configure:978: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1057: checking for $ac_word" >&5
+echo "configure:1029: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1089: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1061: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
cat > conftest.$ac_ext << EOF
-#line 1100 "configure"
+#line 1072 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1131: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1103: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1136: checking whether we are using GNU C" >&5
+echo "configure:1108: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1117: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1164: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1136: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$ac_cv_prog_gcc" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:1207: checking for ld used by GCC" >&5
- ac_prog=`($CC -print-prog-name=ld) 2>&5`
+echo "configure:1179: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
case "$ac_prog" in
# Accept absolute paths.
[\\/]* | [A-Za-z]:[\\/]*)
esac
elif test "$with_gnu_ld" = yes; then
echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:1231: checking for GNU ld" >&5
+echo "configure:1209: checking for GNU ld" >&5
else
echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:1234: checking for non-GNU ld" >&5
+echo "configure:1212: checking for non-GNU ld" >&5
fi
if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
echo "$ac_t""no" 1>&6
fi
test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:1269: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:1248: checking if the linker ($LD) is GNU ld" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:1285: checking for BSD-compatible nm" >&5
+echo "configure:1264: checking for BSD-compatible nm" >&5
if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
NM="$ac_cv_path_NM"
echo "$ac_t""$NM" 1>&6
+
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1321: checking whether ln -s works" >&5
+echo "configure:1301: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
+# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1331: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
+fi
+fi
+AR="$ac_cv_prog_AR"
+if test -n "$AR"; then
+ echo "$ac_t""$AR" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1363: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1395: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+
# Check for any special flags to pass to ltconfig.
libtool_flags="--cache-file=$cache_file"
test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
# Some flags need to be propagated to the compiler or linker for good
# libtool support.
case "$host" in
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 1371 "configure"' > conftest.$ac_ext
- if { (eval echo configure:1372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ echo '#line 1462 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
case "`/usr/bin/file conftest.o`" in
*32-bit*)
LD="${LD-ld} -32"
SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -belf"
echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:1393: checking whether the C compiler needs -belf" >&5
+echo "configure:1484: checking whether the C compiler needs -belf" >&5
if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1398 "configure"
+#line 1489 "configure"
#include "confdefs.h"
int main() {
; return 0; }
EOF
-if { (eval echo configure:1405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
lt_cv_cc_needs_belf=yes
else
# Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
set dummy ${ac_tool_prefix}dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1428: checking for $ac_word" >&5
+echo "configure:1519: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "dlltool", so it can be a program name with args.
set dummy dlltool; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1460: checking for $ac_word" >&5
+echo "configure:1551: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
set dummy ${ac_tool_prefix}as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1495: checking for $ac_word" >&5
+echo "configure:1586: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "as", so it can be a program name with args.
set dummy as; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1527: checking for $ac_word" >&5
+echo "configure:1618: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
set dummy ${ac_tool_prefix}objdump; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1562: checking for $ac_word" >&5
+echo "configure:1653: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# Extract the first word of "objdump", so it can be a program name with args.
set dummy objdump; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1594: checking for $ac_word" >&5
+echo "configure:1685: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
fi
- ;;
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ echo $ac_n "checking if libtool should supply DllMain function""... $ac_c" 1>&6
+echo "configure:1721: checking if libtool should supply DllMain function" >&5
+if eval "test \"`echo '$''{'lt_cv_need_dllmain'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1726 "configure"
+#include "confdefs.h"
+DllMain (0, 0, 0);
+int main() {
+extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+; return 0; }
+EOF
+if { (eval echo configure:1733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_need_dllmain=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_need_dllmain=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_need_dllmain" 1>&6
+
+ case $host in
+ *-*-cygwin*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ *-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ echo $ac_n "checking how to link DLLs""... $ac_c" 1>&6
+echo "configure:1758: checking how to link DLLs" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_dll_switch'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1763 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_dll_switch=-mdll
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_dll_switch=-dll
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_dll_switch" 1>&6
+ CFLAGS="$SAVE_CFLAGS" ;;
+ esac
+ ;;
+
esac
# Actually configure libtool. ac_aux_dir is where install-sh is found.
-CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+AR="$AR" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
-$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
# Reload cache, that may have been modified by ltconfig
echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:1711: checking for Cygwin environment" >&5
+echo "configure:1870: checking for Cygwin environment" >&5
if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1716 "configure"
+#line 1875 "configure"
#include "confdefs.h"
int main() {
return __CYGWIN__;
; return 0; }
EOF
-if { (eval echo configure:1727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1886: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_cygwin=yes
else
CYGWIN=
test "$ac_cv_cygwin" = yes && CYGWIN=yes
echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:1744: checking for mingw32 environment" >&5
+echo "configure:1903: checking for mingw32 environment" >&5
if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1749 "configure"
+#line 1908 "configure"
#include "confdefs.h"
int main() {
return __MINGW32__;
; return 0; }
EOF
-if { (eval echo configure:1756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_mingw32=yes
else
echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1775: checking for executable suffix" >&5
+echo "configure:1934: checking for executable suffix" >&5
if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
rm -f conftest*
echo 'int main () { return 0; }' > conftest.$ac_ext
ac_cv_exeext=
- if { (eval echo configure:1785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ if { (eval echo configure:1944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
for file in conftest.*; do
case $file in
*.c | *.o | *.obj | *.ilk | *.pdb) ;;
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1810: checking for $ac_word" >&5
+echo "configure:1969: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1842: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+echo "configure:2001: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
ac_ext=C
# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
cat > conftest.$ac_ext << EOF
-#line 1853 "configure"
+#line 2012 "configure"
#include "confdefs.h"
int main(){return(0);}
EOF
-if { (eval echo configure:1858: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cxx_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
{ echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1884: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2043: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
cross_compiling=$ac_cv_prog_cxx_cross
echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
-echo "configure:1889: checking whether we are using GNU C++" >&5
+echo "configure:2048: checking whether we are using GNU C++" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
yes;
#endif
EOF
-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1898: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:2057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gxx=yes
else
ac_cv_prog_gxx=no
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS=
echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
-echo "configure:1917: checking whether ${CXX-g++} accepts -g" >&5
+echo "configure:2076: checking whether ${CXX-g++} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
-echo "configure:1949: checking how to run the C++ preprocessor" >&5
+echo "configure:2108: checking how to run the C++ preprocessor" >&5
if test -z "$CXXCPP"; then
if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
cross_compiling=$ac_cv_prog_cxx_cross
CXXCPP="${CXX-g++} -E"
cat > conftest.$ac_ext <<EOF
-#line 1962 "configure"
+#line 2121 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1967: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2126: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
echo "$ac_t""$CXXCPP" 1>&6
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1992: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:2151: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
-s%@RANLIB@%$RANLIB%g
s%@CC@%$CC%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
s%@LN_S@%$LN_S%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
s%@DLLTOOL@%$DLLTOOL%g
s%@AS@%$AS%g
s%@OBJDUMP@%$OBJDUMP%g
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.