Moved 64-bit only files from cpu64 to cpu and modified the Makefiles

accordingly.  These files cause no conflicts at all, since they
are not used in 32-bit compiles.
This commit is contained in:
Kevin Lawton 2002-09-13 15:53:22 +00:00
parent 5ca59b4d4f
commit f05d453b6c
12 changed files with 6796 additions and 87 deletions

173
bochs/configure vendored
View File

@ -623,7 +623,7 @@ else
fi
# From configure.in Id: configure.in,v 1.97 2002/09/12 07:16:35 bdenney Exp
# From configure.in Id: configure.in,v 1.98 2002/09/13 02:56:14 kevinlawton Exp
VERSION="1.4.cvs"
@ -3658,6 +3658,7 @@ if test "${enable_x86_64+set}" = set; then
echo "$ac_t""yes" 1>&6
CPUDIR=cpu64
LIBCPU32_A=""
OBJS64_CPU='$(OBJS64_CPU)'
cat >> confdefs.h <<\EOF
#define BX_SUPPORT_X86_64 1
EOF
@ -3667,6 +3668,7 @@ EOF
echo "$ac_t""no" 1>&6
CPUDIR=cpu
LIBCPU32_A=libcpu.a
OBJS64_CPU=''
cat >> confdefs.h <<\EOF
#define BX_SUPPORT_X86_64 0
EOF
@ -3678,6 +3680,7 @@ else
echo "$ac_t""no" 1>&6
CPUDIR=cpu
LIBCPU32_A=libcpu.a
OBJS64_CPU=''
cat >> confdefs.h <<\EOF
#define BX_SUPPORT_X86_64 0
EOF
@ -3689,8 +3692,9 @@ fi
echo $ac_n "checking for cpu level""... $ac_c" 1>&6
echo "configure:3694: checking for cpu level" >&5
echo "configure:3698: 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"
@ -3784,7 +3788,7 @@ fi
echo $ac_n "checking for dynamic translation support""... $ac_c" 1>&6
echo "configure:3788: checking for dynamic translation support" >&5
echo "configure:3792: 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"
@ -3857,7 +3861,7 @@ fi
echo $ac_n "checking for fetchdecode-cache support""... $ac_c" 1>&6
echo "configure:3861: checking for fetchdecode-cache support" >&5
echo "configure:3865: checking for fetchdecode-cache support" >&5
# Check whether --enable-fetchdecode-cache or --disable-fetchdecode-cache was given.
if test "${enable_fetchdecode_cache+set}" = set; then
enableval="$enable_fetchdecode_cache"
@ -3887,7 +3891,7 @@ fi
echo $ac_n "checking for APIC support""... $ac_c" 1>&6
echo "configure:3891: checking for APIC support" >&5
echo "configure:3895: checking for APIC support" >&5
# Check whether --enable-apic or --disable-apic was given.
if test "${enable_apic+set}" = set; then
enableval="$enable_apic"
@ -3942,7 +3946,7 @@ fi
echo $ac_n "checking for split hard disk image support""... $ac_c" 1>&6
echo "configure:3946: checking for split hard disk image support" >&5
echo "configure:3950: 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"
@ -3973,7 +3977,7 @@ fi
echo $ac_n "checking for NE2000 support""... $ac_c" 1>&6
echo "configure:3977: checking for NE2000 support" >&5
echo "configure:3981: checking for NE2000 support" >&5
# Check whether --enable-ne2000 or --disable-ne2000 was given.
if test "${enable_ne2000+set}" = set; then
enableval="$enable_ne2000"
@ -3986,17 +3990,17 @@ 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:3990: checking for net/bpf.h" >&5
echo "configure:3994: 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 3995 "configure"
#line 3999 "configure"
#include "confdefs.h"
#include <net/bpf.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4000: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4004: \"$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*
@ -4019,17 +4023,17 @@ fi
ac_safe=`echo "netpacket/packet.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for netpacket/packet.h""... $ac_c" 1>&6
echo "configure:4023: checking for netpacket/packet.h" >&5
echo "configure:4027: checking for netpacket/packet.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 4028 "configure"
#line 4032 "configure"
#include "confdefs.h"
#include <netpacket/packet.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4033: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4037: \"$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*
@ -4052,17 +4056,17 @@ fi
ac_safe=`echo "linux/netlink.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/netlink.h""... $ac_c" 1>&6
echo "configure:4056: checking for linux/netlink.h" >&5
echo "configure:4060: checking for linux/netlink.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 4061 "configure"
#line 4065 "configure"
#include "confdefs.h"
#include <linux/netlink.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4070: \"$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*
@ -4091,17 +4095,17 @@ fi
ac_safe=`echo "linux/if_tun.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/if_tun.h""... $ac_c" 1>&6
echo "configure:4095: checking for linux/if_tun.h" >&5
echo "configure:4099: checking for linux/if_tun.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 4100 "configure"
#line 4104 "configure"
#include "confdefs.h"
#include <linux/if_tun.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4105: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4109: \"$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*
@ -4160,7 +4164,7 @@ fi
echo $ac_n "checking for i440FX PCI support""... $ac_c" 1>&6
echo "configure:4164: checking for i440FX PCI support" >&5
echo "configure:4168: 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"
@ -4195,7 +4199,7 @@ fi
echo $ac_n "checking for 4Meg pages support""... $ac_c" 1>&6
echo "configure:4199: checking for 4Meg pages support" >&5
echo "configure:4203: checking for 4Meg pages support" >&5
# Check whether --enable-4meg-pages or --disable-4meg-pages was given.
if test "${enable_4meg_pages+set}" = set; then
enableval="$enable_4meg_pages"
@ -4226,7 +4230,7 @@ fi
echo $ac_n "checking for guest to host TLB support""... $ac_c" 1>&6
echo "configure:4230: checking for guest to host TLB support" >&5
echo "configure:4234: checking for guest to host TLB support" >&5
# Check whether --enable-guest2host-tlb or --disable-guest2host-tlb was given.
if test "${enable_guest2host_tlb+set}" = set; then
enableval="$enable_guest2host_tlb"
@ -4257,7 +4261,7 @@ fi
echo $ac_n "checking for repeated IO and mem copy speedups""... $ac_c" 1>&6
echo "configure:4261: checking for repeated IO and mem copy speedups" >&5
echo "configure:4265: checking for repeated IO and mem copy speedups" >&5
# Check whether --enable-repeat-speedups or --disable-repeat-speedups was given.
if test "${enable_repeat_speedups+set}" = set; then
enableval="$enable_repeat_speedups"
@ -4288,7 +4292,7 @@ fi
echo $ac_n "checking for Global pages support""... $ac_c" 1>&6
echo "configure:4292: checking for Global pages support" >&5
echo "configure:4296: checking for Global pages support" >&5
# Check whether --enable-global-pages or --disable-global-pages was given.
if test "${enable_global_pages+set}" = set; then
enableval="$enable_global_pages"
@ -4320,7 +4324,7 @@ fi
echo $ac_n "checking for port e9 hack""... $ac_c" 1>&6
echo "configure:4324: checking for port e9 hack" >&5
echo "configure:4328: 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"
@ -4351,7 +4355,7 @@ fi
echo $ac_n "checking for use of .cpp as suffix""... $ac_c" 1>&6
echo "configure:4355: checking for use of .cpp as suffix" >&5
echo "configure:4359: 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"
@ -4394,7 +4398,7 @@ fi
echo $ac_n "checking for Bochs internal debugger support""... $ac_c" 1>&6
echo "configure:4398: checking for Bochs internal debugger support" >&5
echo "configure:4402: 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"
@ -4432,7 +4436,7 @@ fi
echo $ac_n "checking for external debugger""... $ac_c" 1>&6
echo "configure:4436: checking for external debugger" >&5
echo "configure:4440: checking for external debugger" >&5
# Check whether --enable-external-debugger or --disable-external-debugger was given.
if test "${enable_external_debugger+set}" = set; then
enableval="$enable_external_debugger"
@ -4456,7 +4460,7 @@ fi
echo $ac_n "checking for disassembler support""... $ac_c" 1>&6
echo "configure:4460: checking for disassembler support" >&5
echo "configure:4464: checking for disassembler support" >&5
# Check whether --enable-disasm or --disable-disasm was given.
if test "${enable_disasm+set}" = set; then
enableval="$enable_disasm"
@ -4507,14 +4511,14 @@ rl_without_curses_ok=no
rl_with_curses_ok=no
echo $ac_n "checking if readline works without -lcurses""... $ac_c" 1>&6
echo "configure:4511: checking if readline works without -lcurses" >&5
echo "configure:4515: checking if readline works without -lcurses" >&5
OLD_LIBS=$LIBS
LIBS="$LIBS -lreadline"
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 4518 "configure"
#line 4522 "configure"
#include "confdefs.h"
#include <stdio.h>
@ -4522,7 +4526,7 @@ else
int main() { rl_initialize(); exit(0); }
EOF
if { (eval echo configure:4526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
if { (eval echo configure:4530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "$ac_t""yes" 1>&6
rl_without_curses_ok=yes
@ -4537,13 +4541,13 @@ rm -fr conftest*
fi
echo $ac_n "checking if readline works with -lcurses""... $ac_c" 1>&6
echo "configure:4541: checking if readline works with -lcurses" >&5
echo "configure:4545: checking if readline works with -lcurses" >&5
LIBS="$LIBS -lcurses"
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 4547 "configure"
#line 4551 "configure"
#include "confdefs.h"
#include <stdio.h>
@ -4551,7 +4555,7 @@ else
int main() { rl_initialize(); exit(0); }
EOF
if { (eval echo configure:4555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
if { (eval echo configure:4559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "$ac_t""yes" 1>&6
rl_with_curses_ok=yes
@ -4568,7 +4572,7 @@ fi
LIBS=$OLD_LIBS
echo $ac_n "checking whether user wants readline""... $ac_c" 1>&6
echo "configure:4572: checking whether user wants readline" >&5
echo "configure:4576: checking whether user wants readline" >&5
# Check whether --enable-readline or --disable-readline was given.
if test "${enable_readline+set}" = set; then
enableval="$enable_readline"
@ -4590,7 +4594,7 @@ fi
use_readline=0
echo $ac_n "checking whether to use readline""... $ac_c" 1>&6
echo "configure:4594: checking whether to use readline" >&5
echo "configure:4598: checking whether to use readline" >&5
if test "$want_readline" = yes; then
if test "$bx_debugger" = 1; then
if test "$rl_without_curses_ok" = yes; then
@ -4623,17 +4627,17 @@ fi
ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for readline/history.h""... $ac_c" 1>&6
echo "configure:4627: checking for readline/history.h" >&5
echo "configure:4631: 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 4632 "configure"
#line 4636 "configure"
#include "confdefs.h"
#include <readline/history.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:4637: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:4641: \"$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*
@ -4660,7 +4664,7 @@ fi
echo $ac_n "checking for loader support""... $ac_c" 1>&6
echo "configure:4664: checking for loader support" >&5
echo "configure:4668: checking for loader support" >&5
# Check whether --enable-loader or --disable-loader was given.
if test "${enable_loader+set}" = set; then
enableval="$enable_loader"
@ -4698,7 +4702,7 @@ fi
INSTRUMENT_DIR='instrument/stubs'
echo $ac_n "checking for instrumentation support""... $ac_c" 1>&6
echo "configure:4702: checking for instrumentation support" >&5
echo "configure:4706: checking for instrumentation support" >&5
# Check whether --enable-instrumentation or --disable-instrumentation was given.
if test "${enable_instrumentation+set}" = set; then
enableval="$enable_instrumentation"
@ -4833,7 +4837,7 @@ fi
echo $ac_n "checking for VGA emulation""... $ac_c" 1>&6
echo "configure:4837: checking for VGA emulation" >&5
echo "configure:4841: checking for VGA emulation" >&5
# Check whether --enable-vga or --disable-vga was given.
if test "${enable_vga+set}" = set; then
enableval="$enable_vga"
@ -4867,7 +4871,7 @@ fi
echo $ac_n "checking for VESA BIOS extensions""... $ac_c" 1>&6
echo "configure:4871: checking for VESA BIOS extensions" >&5
echo "configure:4875: checking for VESA BIOS extensions" >&5
# Check whether --enable-vbe or --disable-vbe was given.
if test "${enable_vbe+set}" = set; then
enableval="$enable_vbe"
@ -4897,7 +4901,7 @@ fi
echo $ac_n "checking for MMX support""... $ac_c" 1>&6
echo "configure:4901: checking for MMX support" >&5
echo "configure:4905: checking for MMX support" >&5
# Check whether --enable-mmx or --disable-mmx was given.
if test "${enable_mmx+set}" = set; then
enableval="$enable_mmx"
@ -4928,7 +4932,7 @@ fi
echo $ac_n "checking for FPU emulation""... $ac_c" 1>&6
echo "configure:4932: checking for FPU emulation" >&5
echo "configure:4936: checking for FPU emulation" >&5
FPU_VAR=''
FPU_GLUE_OBJ=''
# Check whether --enable-fpu or --disable-fpu was given.
@ -4973,7 +4977,7 @@ fi
echo $ac_n "checking for x86 debugger support""... $ac_c" 1>&6
echo "configure:4977: checking for x86 debugger support" >&5
echo "configure:4981: 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"
@ -5010,17 +5014,17 @@ fi
ac_safe=`echo "IOKit/storage/IOCDMedia.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for IOKit/storage/IOCDMedia.h""... $ac_c" 1>&6
echo "configure:5014: checking for IOKit/storage/IOCDMedia.h" >&5
echo "configure:5018: checking for IOKit/storage/IOCDMedia.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 5019 "configure"
#line 5023 "configure"
#include "confdefs.h"
#include <IOKit/storage/IOCDMedia.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:5024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:5028: \"$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*
@ -5044,7 +5048,7 @@ fi
echo $ac_n "checking for CDROM support""... $ac_c" 1>&6
echo "configure:5048: checking for CDROM support" >&5
echo "configure:5052: checking for CDROM support" >&5
# Check whether --enable-cdrom or --disable-cdrom was given.
if test "${enable_cdrom+set}" = set; then
enableval="$enable_cdrom"
@ -5104,7 +5108,7 @@ fi
echo $ac_n "checking for Sound Blaster 16 support""... $ac_c" 1>&6
echo "configure:5108: checking for Sound Blaster 16 support" >&5
echo "configure:5112: 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"
@ -5178,7 +5182,7 @@ fi
echo $ac_n "checking for I/O Interface to the debugger""... $ac_c" 1>&6
echo "configure:5182: checking for I/O Interface to the debugger" >&5
echo "configure:5186: checking for I/O Interface to the debugger" >&5
IODEBUG_OBJS=''
# Check whether --enable-iodebug or --disable-iodebug was given.
if test "${enable_iodebug+set}" = set; then
@ -5341,10 +5345,10 @@ INSTALL_TARGET=install_unix
INSTALL_LIST_FOR_PLATFORM=
echo $ac_n "checking for default gui on this platform""... $ac_c" 1>&6
echo "configure:5345: checking for default gui on this platform" >&5
echo "configure:5349: checking for default gui on this platform" >&5
echo "$ac_t""$DEFAULT_GUI" 1>&6
echo $ac_n "checking for gui library to use""... $ac_c" 1>&6
echo "configure:5348: checking for gui library to use" >&5
echo "configure:5352: checking for gui library to use" >&5
# the $with_* variable tells the gui library to use, but does NOT necessarily
# indicate the platform. Settings that depend on the platform should be
@ -5554,7 +5558,7 @@ esac
if test "$use_curses" = yes; then
echo $ac_n "checking for mvaddch in -lcurses""... $ac_c" 1>&6
echo "configure:5558: checking for mvaddch in -lcurses" >&5
echo "configure:5562: 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
@ -5562,7 +5566,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 5566 "configure"
#line 5570 "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
@ -5573,7 +5577,7 @@ int main() {
mvaddch()
; return 0; }
EOF
if { (eval echo configure:5577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5581: \"$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
@ -5594,7 +5598,7 @@ else
fi
echo $ac_n "checking for mvaddch in -lncurses""... $ac_c" 1>&6
echo "configure:5598: checking for mvaddch in -lncurses" >&5
echo "configure:5602: 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
@ -5602,7 +5606,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lncurses $LIBS"
cat > conftest.$ac_ext <<EOF
#line 5606 "configure"
#line 5610 "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
@ -5613,7 +5617,7 @@ int main() {
mvaddch()
; return 0; }
EOF
if { (eval echo configure:5617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5621: \"$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
@ -5634,7 +5638,7 @@ else
fi
echo $ac_n "checking for mvaddch in -ltermlib""... $ac_c" 1>&6
echo "configure:5638: checking for mvaddch in -ltermlib" >&5
echo "configure:5642: 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
@ -5642,7 +5646,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ltermlib $LIBS"
cat > conftest.$ac_ext <<EOF
#line 5646 "configure"
#line 5650 "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
@ -5653,7 +5657,7 @@ int main() {
mvaddch()
; return 0; }
EOF
if { (eval echo configure:5657: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5661: \"$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
@ -5695,17 +5699,17 @@ acx_pthread_ok=no
# If it isn't, don't bother looking for the threads libraries.
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
echo "configure:5699: checking for pthread.h" >&5
echo "configure:5703: checking for pthread.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 5704 "configure"
#line 5708 "configure"
#include "confdefs.h"
#include <pthread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:5709: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
{ (eval echo configure:5713: \"$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*
@ -5742,9 +5746,9 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
echo $ac_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS""... $ac_c" 1>&6
echo "configure:5746: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
echo "configure:5750: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
cat > conftest.$ac_ext <<EOF
#line 5748 "configure"
#line 5752 "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
@ -5755,7 +5759,7 @@ int main() {
pthread_join()
; return 0; }
EOF
if { (eval echo configure:5759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
acx_pthread_ok=yes
else
@ -5817,18 +5821,18 @@ for flag in $acx_pthread_flags; do
case $flag in
none)
echo $ac_n "checking whether pthreads work without any flags""... $ac_c" 1>&6
echo "configure:5821: checking whether pthreads work without any flags" >&5
echo "configure:5825: checking whether pthreads work without any flags" >&5
;;
-*)
echo $ac_n "checking whether pthreads work with $flag""... $ac_c" 1>&6
echo "configure:5826: checking whether pthreads work with $flag" >&5
echo "configure:5830: checking whether pthreads work with $flag" >&5
PTHREAD_CFLAGS="$flag"
;;
*)
echo $ac_n "checking for the pthreads library -l$flag""... $ac_c" 1>&6
echo "configure:5832: checking for the pthreads library -l$flag" >&5
echo "configure:5836: checking for the pthreads library -l$flag" >&5
PTHREAD_LIBS="-l$flag"
;;
esac
@ -5848,7 +5852,7 @@ echo "configure:5832: checking for the pthreads library -l$flag" >&5
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
cat > conftest.$ac_ext <<EOF
#line 5852 "configure"
#line 5856 "configure"
#include "confdefs.h"
#include <pthread.h>
int main() {
@ -5857,7 +5861,7 @@ pthread_t th; pthread_join(th, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0);
; return 0; }
EOF
if { (eval echo configure:5861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
acx_pthread_ok=yes
else
@ -5889,16 +5893,16 @@ if test "x$acx_pthread_ok" = xyes; then
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
echo $ac_n "checking for joinable pthread attribute""... $ac_c" 1>&6
echo "configure:5893: checking for joinable pthread attribute" >&5
echo "configure:5897: checking for joinable pthread attribute" >&5
cat > conftest.$ac_ext <<EOF
#line 5895 "configure"
#line 5899 "configure"
#include "confdefs.h"
#include <pthread.h>
int main() {
int attr=PTHREAD_CREATE_JOINABLE;
; return 0; }
EOF
if { (eval echo configure:5902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ok=PTHREAD_CREATE_JOINABLE
else
@ -5910,14 +5914,14 @@ fi
rm -f conftest*
if test x"$ok" = xunknown; then
cat > conftest.$ac_ext <<EOF
#line 5914 "configure"
#line 5918 "configure"
#include "confdefs.h"
#include <pthread.h>
int main() {
int attr=PTHREAD_CREATE_UNDETACHED;
; return 0; }
EOF
if { (eval echo configure:5921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
if { (eval echo configure:5925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ok=PTHREAD_CREATE_UNDETACHED
else
@ -5940,7 +5944,7 @@ EOF
fi
echo $ac_n "checking if more special flags are required for pthreads""... $ac_c" 1>&6
echo "configure:5944: checking if more special flags are required for pthreads" >&5
echo "configure:5948: checking if more special flags are required for pthreads" >&5
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
@ -5958,7 +5962,7 @@ echo "configure:5944: checking if more special flags are required for pthreads"
# Extract the first word of "cc_r", so it can be a program name with args.
set dummy cc_r; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:5962: checking for $ac_word" >&5
echo "configure:5966: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_PTHREAD_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -6072,7 +6076,7 @@ if test ! -d build/linux; then mkdir build/linux; 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:6076: checking for $ac_word" >&5
echo "configure:6080: 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
@ -6107,7 +6111,7 @@ 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:6111: checking for $ac_word" >&5
echo "configure:6115: 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
@ -6304,6 +6308,7 @@ s%@SLOWDOWN_OBJS@%$SLOWDOWN_OBJS%g
s%@BX_USE_IDLE_HACK@%$BX_USE_IDLE_HACK%g
s%@CPUDIR@%$CPUDIR%g
s%@LIBCPU32_A@%$LIBCPU32_A%g
s%@OBJS64_CPU@%$OBJS64_CPU%g
s%@DYNAMIC_VAR@%$DYNAMIC_VAR%g
s%@AS_DYNAMIC_OBJS@%$AS_DYNAMIC_OBJS%g
s%@AS_DYNAMIC_INCS@%$AS_DYNAMIC_INCS%g

View File

@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
AC_PREREQ(2.4)
AC_INIT(bochs.h)
AC_REVISION([[$Id: configure.in,v 1.98 2002-09-13 02:56:14 kevinlawton Exp $]])
AC_REVISION([[$Id: configure.in,v 1.99 2002-09-13 15:53:21 kevinlawton Exp $]])
AC_CONFIG_HEADER(config.h)
dnl // Put Bochs version information right here so that it gets substituted
@ -308,12 +308,14 @@ AC_ARG_ENABLE(x86-64,
AC_MSG_RESULT(yes)
CPUDIR=cpu64
LIBCPU32_A=""
OBJS64_CPU='$(OBJS64_CPU)'
AC_DEFINE(BX_SUPPORT_X86_64, 1)
use_x86_64=1
else
AC_MSG_RESULT(no)
CPUDIR=cpu
LIBCPU32_A=libcpu.a
OBJS64_CPU=''
AC_DEFINE(BX_SUPPORT_X86_64, 0)
fi
],
@ -321,11 +323,13 @@ AC_ARG_ENABLE(x86-64,
AC_MSG_RESULT(no)
CPUDIR=cpu
LIBCPU32_A=libcpu.a
OBJS64_CPU=''
AC_DEFINE(BX_SUPPORT_X86_64, 0)
]
)
AC_SUBST(CPUDIR)
AC_SUBST(LIBCPU32_A)
AC_SUBST(OBJS64_CPU)
AC_MSG_CHECKING(for cpu level)
AC_ARG_ENABLE(cpu-level,

View File

@ -103,6 +103,20 @@ OBJSXX = \
bcd.o \
mult16.o \
# Objects which are only used for x86-64 code, but which have been
# moved to the cpu/ directory since they cause no conflict at all
# by being here.
OBJS64_CPU = \
arith64.o \
ctrl_xfer64.o \
data_xfer64.o \
fetchdecode64.o \
logical64.o \
mult64.o \
resolve64.o \
shift64.o \
stack64.o \
BX_INCLUDES = ../bochs.h ../config.h
@ -118,15 +132,17 @@ libcpu.a: $(OBJS32)
@MAKELIB@ $(OBJS32)
$(RANLIB) libcpu.a
libcpuXX.a: $(OBJSXX)
libcpuXX.a: $(OBJSXX) @OBJS64_CPU@
@RMCOMMAND@ libcpuXX.a
@MAKELIB@ $(OBJSXX)
@MAKELIB@ $(OBJSXX) @OBJS64_CPU@
$(RANLIB) libcpuXX.a
$(OBJS32): $(BX_INCLUDES)
$(OBJSXX): $(BX_INCLUDES)
$(OBJS64_CPU): $(BX_INCLUDES)
clean:
@RMCOMMAND@ *.o
@RMCOMMAND@ *.a

870
bochs/cpu/arith64.cc Normal file
View File

@ -0,0 +1,870 @@
/////////////////////////////////////////////////////////////////////////
// $Id: arith64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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
/* I don't think these versions accessible in 64 bit mode
void
BX_CPU_C::INC_RRX(BxInstruction_t *i)
{
Bit32u rrx;
rrx = ++ BX_CPU_THIS_PTR gen_reg[i->nnn].rrx;
SET_FLAGS_OSZAP_64(0, 0, rrx, BX_INSTR_INC64);
}
void
BX_CPU_C::DEC_RRX(BxInstruction_t *i)
{
Bit32u rrx;
rrx = -- BX_CPU_THIS_PTR gen_reg[i->nnn].rrx;
SET_FLAGS_OSZAP_64(0, 0, rrx, BX_INSTR_DEC64);
}
*/
void
BX_CPU_C::ADD_EqGq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, sum_64;
/* op2_64 is a register, i->rm_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
sum_64 = op1_64 + op2_64;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, sum_64);
}
else {
write_RMW_virtual_qword(sum_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_ADD64);
}
void
BX_CPU_C::ADD_GqEq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, sum_64;
/* op1_64 is a register, i->rm_addr is an index of a register */
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
sum_64 = op1_64 + op2_64;
/* now write sum back to destination */
BX_WRITE_64BIT_REG(i->nnn, sum_64);
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_ADD64);
}
void
BX_CPU_C::ADD_RAXId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, sum_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
sum_64 = op1_64 + op2_64;
/* now write sum back to destination */
RAX = sum_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_ADD64);
}
void
BX_CPU_C::ADC_EqGq(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, sum_64;
/* op2_64 is a register, i->rm_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
sum_64 = op1_64 + op2_64 + temp_CF;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, sum_64);
}
else {
write_RMW_virtual_qword(sum_64);
}
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, sum_64, BX_INSTR_ADC64,
temp_CF);
}
void
BX_CPU_C::ADC_GqEq(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, sum_64;
/* op1_64 is a register, i->rm_addr is an index of a register */
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
sum_64 = op1_64 + op2_64 + temp_CF;
/* now write sum back to destination */
BX_WRITE_64BIT_REG(i->nnn, sum_64);
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, sum_64, BX_INSTR_ADC64,
temp_CF);
}
void
BX_CPU_C::ADC_RAXId(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, sum_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
sum_64 = op1_64 + op2_64 + temp_CF;
/* now write sum back to destination */
RAX = sum_64;
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, sum_64, BX_INSTR_ADC64,
temp_CF);
}
void
BX_CPU_C::SBB_EqGq(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
/* op2_64 is a register, i->rm_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - (op2_64 + temp_CF);
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, diff_64);
}
else {
write_RMW_virtual_qword(diff_64);
}
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, diff_64, BX_INSTR_SBB64,
temp_CF);
}
void
BX_CPU_C::SBB_GqEq(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
/* op1_64 is a register, i->rm_addr is an index of a register */
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
diff_64 = op1_64 - (op2_64 + temp_CF);
/* now write diff back to destination */
BX_WRITE_64BIT_REG(i->nnn, diff_64);
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, diff_64, BX_INSTR_SBB64,
temp_CF);
}
void
BX_CPU_C::SBB_RAXId(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
diff_64 = op1_64 - (op2_64 + temp_CF);
/* now write diff back to destination */
RAX = diff_64;
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, diff_64, BX_INSTR_SBB64,
temp_CF);
}
void
BX_CPU_C::SBB_EqId(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - (op2_64 + temp_CF);
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, diff_64);
}
else {
write_RMW_virtual_qword(diff_64);
}
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, diff_64, BX_INSTR_SBB64,
temp_CF);
}
void
BX_CPU_C::SUB_EqGq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
/* op2_64 is a register, i->rm_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - op2_64;
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, diff_64);
}
else {
write_RMW_virtual_qword(diff_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_SUB64);
}
void
BX_CPU_C::SUB_GqEq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
/* op1_64 is a register, i->rm_addr is an index of a register */
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
diff_64 = op1_64 - op2_64;
/* now write diff back to destination */
BX_WRITE_64BIT_REG(i->nnn, diff_64);
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_SUB64);
}
void
BX_CPU_C::SUB_RAXId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
diff_64 = op1_64 - op2_64;
/* now write diff back to destination */
RAX = diff_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_SUB64);
}
void
BX_CPU_C::CMP_EqGq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
/* op2_64 is a register, i->rm_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_CMP64);
}
void
BX_CPU_C::CMP_GqEq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
/* op1_64 is a register, i->rm_addr is an index of a register */
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
diff_64 = op1_64 - op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_CMP64);
}
void
BX_CPU_C::CMP_RAXId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, diff_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
diff_64 = op1_64 - op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_CMP64);
}
#ifdef ignore
void
BX_CPU_C::CWDE64(BxInstruction_t *i)
{
/* CBW: no flags are effected */
RAX = (Bit16s) AX;
}
#endif
void
BX_CPU_C::CDQE(BxInstruction_t *i)
{
/* CWDE: no flags are affected */
RAX = (Bit32s) EAX;
}
void
BX_CPU_C::CQO(BxInstruction_t *i)
{
/* CQO: no flags are affected */
if (RAX & BX_CONST64(0x8000000000000000))
RDX = BX_CONST64(0xffffffffffffffff);
else
RDX = 0;
}
#ifdef ignore_this
// not sure about these....
// 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|64
//
// On 486 >= B steps, and further processors, the
// CMPXCHG instructions were moved to opcodes:
// {OF,B0} = CMPXCHG 8
// {OF,B1} = CMPXCHG 16|64
void
BX_CPU_C::CMPXCHG_XBTS(BxInstruction_t *i)
{
BX_INFO(("CMPXCHG_XBTS:"));
UndefinedOpcode(i);
}
void
BX_CPU_C::CMPXCHG_IBTS(BxInstruction_t *i)
{
BX_INFO(("CMPXCHG_IBTS:"));
UndefinedOpcode(i);
}
#endif
void
BX_CPU_C::XADD_EqGq(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u op2_64, op1_64, sum_64;
/* 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_64 = BX_READ_64BIT_REG(i->nnn);
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
sum_64 = op1_64 + op2_64;
/* 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_64BIT_REG(i->nnn, op1_64);
BX_WRITE_64BIT_REG(i->rm, sum_64);
}
else {
write_RMW_virtual_qword(sum_64);
/* and write destination into source */
BX_WRITE_64BIT_REG(i->nnn, op1_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_XADD64);
#else
#endif
}
void
BX_CPU_C::ADD_EqId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, sum_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
sum_64 = op1_64 + op2_64;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, sum_64);
}
else {
write_RMW_virtual_qword(sum_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_ADD64);
}
void
BX_CPU_C::ADC_EqId(BxInstruction_t *i)
{
Boolean temp_CF;
temp_CF = get_CF();
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, sum_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
sum_64 = op1_64 + op2_64 + temp_CF;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, sum_64);
}
else {
write_RMW_virtual_qword(sum_64);
}
SET_FLAGS_OSZAPC_64_CF(op1_64, op2_64, sum_64, BX_INSTR_ADC64,
temp_CF);
}
void
BX_CPU_C::SUB_EqId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - op2_64;
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, diff_64);
}
else {
write_RMW_virtual_qword(diff_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_SUB64);
}
void
BX_CPU_C::CMP_EqId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, diff_64;
op2_64 = i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = op1_64 - op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, diff_64, BX_INSTR_CMP64);
}
void
BX_CPU_C::NEG_Eq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, diff_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = 0 - op1_64;
/* now write diff back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, diff_64);
}
else {
write_RMW_virtual_qword(diff_64);
}
SET_FLAGS_OSZAPC_64(op1_64, 0, diff_64, BX_INSTR_NEG64);
}
void
BX_CPU_C::INC_Eq(BxInstruction_t *i)
{
Bit64u op1_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
op1_64++;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
write_RMW_virtual_qword(op1_64);
}
SET_FLAGS_OSZAP_64(0, 0, op1_64, BX_INSTR_INC64);
}
void
BX_CPU_C::DEC_Eq(BxInstruction_t *i)
{
Bit64u op1_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
op1_64--;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op1_64);
}
else {
write_RMW_virtual_qword(op1_64);
}
SET_FLAGS_OSZAP_64(0, 0, op1_64, BX_INSTR_DEC64);
}
void
BX_CPU_C::CMPXCHG_EqGq(BxInstruction_t *i)
{
#if (BX_CPU_LEVEL >= 4) || (BX_CPU_LEVEL_HACKED >= 4)
Bit64u op2_64, op1_64, diff_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
diff_64 = RAX - op1_64;
SET_FLAGS_OSZAPC_64(RAX, op1_64, diff_64, BX_INSTR_CMP64);
if (diff_64 == 0) { // if accumulator == dest
// ZF = 1
set_ZF(1);
// dest <-- src
op2_64 = BX_READ_64BIT_REG(i->nnn);
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op2_64);
}
else {
write_RMW_virtual_qword(op2_64);
}
}
else {
// ZF = 0
set_ZF(0);
// accumulator <-- dest
RAX = op1_64;
}
#else
BX_PANIC(("CMPXCHG_EqGq:"));
#endif
}

461
bochs/cpu/ctrl_xfer64.cc Normal file
View File

@ -0,0 +1,461 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ctrl_xfer64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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::RETnear64_Iw(BxInstruction_t *i)
{
Bit16u imm16;
Bit64u temp_RSP;
Bit64u return_RIP;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
temp_RSP = RSP;
imm16 = i->Iw;
invalidate_prefetch_q();
//if ( !can_pop(8) ) {
// BX_PANIC(("retnear_iw: can't pop RIP"));
// /* ??? #SS(0) -or #GP(0) */
// }
access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_RSP + 0,
8, CPL==3, BX_READ, &return_RIP);
/* Pentium book says imm16 is number of words ??? */
//if ( !can_pop(8 + imm16) ) {
// BX_PANIC(("retnear_iw: can't release bytes from stack"));
// /* #GP(0) -or #SS(0) ??? */
// }
RIP = return_RIP;
RSP += 8 + imm16; /* ??? should it be 2*imm16 ? */
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR rip);
}
void
BX_CPU_C::RETnear64(BxInstruction_t *i)
{
Bit64u temp_RSP;
Bit64u return_RIP;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_ret;
#endif
invalidate_prefetch_q();
temp_RSP = RSP;
//if ( !can_pop(8) ) {
// BX_PANIC(("retnear: can't pop RIP"));
// /* ??? #SS(0) -or #GP(0) */
// }
access_linear(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.base + temp_RSP + 0,
8, CPL==3, BX_READ, &return_RIP);
RIP = return_RIP;
RSP += 8;
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_RET, BX_CPU_THIS_PTR rip);
}
void
BX_CPU_C::RETfar64_Iw(BxInstruction_t *i)
{
Bit64u rip, rcs_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_64(&rip);
pop_64(&rcs_raw);
RIP = rip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) rcs_raw);
RSP += 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 rip);
return;
}
void
BX_CPU_C::RETfar64(BxInstruction_t *i)
{
Bit64u rip, rcs_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_64(&rip);
pop_64(&rcs_raw); /* 64bit pop, upper 48 bits discarded */
RIP = rip;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) rcs_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 rip);
return;
}
void
BX_CPU_C::CALL_Aq(BxInstruction_t *i)
{
Bit64u new_RIP;
Bit32s disp32;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
#endif
disp32 = i->Id;
invalidate_prefetch_q();
new_RIP = RIP + disp32;
/* push 64 bit EA of next instruction */
push_64(BX_CPU_THIS_PTR rip);
RIP = new_RIP;
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR rip);
}
void
BX_CPU_C::CALL64_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_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_64(BX_CPU_THIS_PTR rip);
RIP = 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 rip);
return;
}
void
BX_CPU_C::CALL_Eq(BxInstruction_t *i)
{
Bit64u temp_RSP;
Bit64u op1_64;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
#endif
temp_RSP = RSP;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
invalidate_prefetch_q();
if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_RSP, 8) ) {
BX_PANIC(("call_ev: can't push RIP"));
}
push_64(BX_CPU_THIS_PTR rip);
RIP = op1_64;
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_CALL, BX_CPU_THIS_PTR rip);
}
void
BX_CPU_C::CALL64_Ep(BxInstruction_t *i)
{
Bit16u cs_raw;
Bit64u op1_64;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_call;
#endif
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
BX_PANIC(("CALL_Ep: op1 is a register"));
}
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
read_virtual_word(i->seg, i->rm_addr+8, &cs_raw);
invalidate_prefetch_q();
if ( protected_mode() ) {
BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_64);
goto done;
}
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
push_64(BX_CPU_THIS_PTR rip);
RIP = op1_64;
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 rip);
return;
}
void
BX_CPU_C::JMP_Jq(BxInstruction_t *i)
{
Bit64u new_RIP;
invalidate_prefetch_q();
RIP += (Bit32s) i->Id;
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_RIP);
}
void
BX_CPU_C::JCC_Jq(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) {
RIP += (Bit32s) i->Id;
BX_INSTR_CNEAR_BRANCH_TAKEN(RIP);
revalidate_prefetch_q();
}
#if BX_INSTRUMENTATION
else {
BX_INSTR_CNEAR_BRANCH_NOT_TAKEN();
}
#endif
}
#ifdef ignore
void
BX_CPU_C::JMP64_Ap(BxInstruction_t *i)
{
Bit64u disp64;
Bit16u cs_raw;
invalidate_prefetch_q();
if (i->os_32) {
disp64 = (Bit32s) i->Id;
}
else {
disp64 = (Bit16s) 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);
RIP = disp64;
done:
BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR rip);
return;
}
#endif
void
BX_CPU_C::JMP_Eq(BxInstruction_t *i)
{
Bit64u new_RIP;
Bit64u op1_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
invalidate_prefetch_q();
RIP = op1_64;
BX_INSTR_UCNEAR_BRANCH(BX_INSTR_IS_JMP, new_RIP);
}
/* Far indirect jump */
void
BX_CPU_C::JMP64_Ep(BxInstruction_t *i)
{
Bit16u cs_raw;
Bit64u op1_64;
/* 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"));
}
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
read_virtual_word(i->seg, i->rm_addr+8, &cs_raw);
invalidate_prefetch_q();
if ( protected_mode() ) {
BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_64);
goto done;
}
RIP = op1_64;
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw);
done:
#warning "KPL: should this instr macro pass 64-bit RIP?"
BX_INSTR_FAR_BRANCH(BX_INSTR_IS_JMP,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
return;
}
void
BX_CPU_C::IRET64(BxInstruction_t *i)
{
Bit32u rip, ecs_raw, eflags;
#if BX_DEBUGGER
BX_CPU_THIS_PTR show_flag |= Flag_iret;
#warning "KPL: why was this show_rip?"
BX_CPU_THIS_PTR show_eip = BX_CPU_THIS_PTR rip;
#endif
invalidate_prefetch_q();
#if BX_CPU_LEVEL >= 2
if (BX_CPU_THIS_PTR cr0.pe) {
iret_protected(i);
goto done;
}
#endif
done:
BX_INSTR_FAR_BRANCH(BX_INSTR_IS_IRET,
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, BX_CPU_THIS_PTR rip);
return;
}

472
bochs/cpu/data_xfer64.cc Normal file
View File

@ -0,0 +1,472 @@
/////////////////////////////////////////////////////////////////////////
// $Id: data_xfer64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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_RRXRAX(BxInstruction_t *i)
{
Bit64u temp64;
temp64 = RAX;
RAX = BX_CPU_THIS_PTR gen_reg[i->nnn].rrx;
BX_CPU_THIS_PTR gen_reg[i->nnn].rrx = temp64;
}
void
BX_CPU_C::MOV_RRXIq(BxInstruction_t *i)
{
BX_CPU_THIS_PTR gen_reg[i->nnn].rrx = i->Iq;
}
void
BX_CPU_C::MOV_EqGq(BxInstruction_t *i)
{
Bit64u op2_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
/* now write op2 to op1 */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op2_64);
}
else {
write_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
}
void
BX_CPU_C::MOV_GqEq(BxInstruction_t *i)
{
Bit64u op2_64;
//BX_DEBUG (("MOV_GqEq mod=%02x nnn=%d rm=%d rm_addr=%08x seg=%d",i->mod,i->nnn,i->rm,i->rm_addr,i->seg));
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
//BX_DEBUG (("call read_virtual_qword"));
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
//BX_DEBUG (("done read_virtual_qword"));
}
BX_WRITE_64BIT_REG(i->nnn, op2_64);
}
void
BX_CPU_C::LEA_GqM(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_64BIT_REG(i->nnn, i->rm_addr);
}
void
BX_CPU_C::MOV_ALOq(BxInstruction_t *i)
{
Bit8u temp_8;
bx_address addr;
addr = i->Iq;
/* read from memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
read_virtual_byte(i->seg, addr, &temp_8);
}
else {
read_virtual_byte(BX_SEG_REG_DS, addr, &temp_8);
}
/* write to register */
RAX = temp_8;
}
void
BX_CPU_C::MOV_OqAL(BxInstruction_t *i)
{
Bit8u temp_8;
bx_address addr;
addr = i->Iq;
/* read from register */
temp_8 = AL;
/* write to memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
write_virtual_byte(i->seg, addr, &temp_8);
}
else {
write_virtual_byte(BX_SEG_REG_DS, addr, &temp_8);
}
}
void
BX_CPU_C::MOV_AXOq(BxInstruction_t *i)
{
Bit16u temp_16;
bx_address addr;
addr = i->Iq;
/* read from memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
read_virtual_word(i->seg, addr, &temp_16);
}
else {
read_virtual_word(BX_SEG_REG_DS, addr, &temp_16);
}
/* write to register */
AX = temp_16;
}
void
BX_CPU_C::MOV_OqAX(BxInstruction_t *i)
{
Bit16u temp_16;
bx_address addr;
addr = i->Iq;
/* read from register */
temp_16 = AX;
/* write to memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
write_virtual_word(i->seg, addr, &temp_16);
}
else {
write_virtual_word(BX_SEG_REG_DS, addr, &temp_16);
}
}
void
BX_CPU_C::MOV_EAXOq(BxInstruction_t *i)
{
Bit32u temp_32;
bx_address addr;
addr = i->Iq;
/* read from memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
read_virtual_dword(i->seg, addr, &temp_32);
}
else {
read_virtual_dword(BX_SEG_REG_DS, addr, &temp_32);
}
/* write to register */
RAX = temp_32;
}
void
BX_CPU_C::MOV_OqEAX(BxInstruction_t *i)
{
Bit32u temp_32;
bx_address addr;
addr = i->Iq;
/* read from register */
temp_32 = EAX;
/* write to memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
write_virtual_dword(i->seg, addr, &temp_32);
}
else {
write_virtual_dword(BX_SEG_REG_DS, addr, &temp_32);
}
}
void
BX_CPU_C::MOV_RAXOq(BxInstruction_t *i)
{
Bit64u temp_64;
bx_address addr;
addr = i->Iq;
/* read from memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
read_virtual_qword(i->seg, addr, &temp_64);
}
else {
read_virtual_qword(BX_SEG_REG_DS, addr, &temp_64);
}
/* write to register */
RAX = temp_64;
}
void
BX_CPU_C::MOV_OqRAX(BxInstruction_t *i)
{
Bit64u temp_64;
bx_address addr;
addr = i->Iq;
/* read from register */
temp_64 = RAX;
/* write to memory address */
if (!BX_NULL_SEG_REG(i->seg)) {
write_virtual_qword(i->seg, addr, &temp_64);
}
else {
write_virtual_qword(BX_SEG_REG_DS, addr, &temp_64);
}
}
void
BX_CPU_C::MOV_EqId(BxInstruction_t *i)
{
Bit64u op2_64;
op2_64 = (Bit32s) i->Id;
/* now write sum back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, op2_64);
}
else {
write_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
}
void
BX_CPU_C::MOVZX_GqEb(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("MOVZX_GvEb: not supported on < 386"));
#else
Bit8u op2_8;
if (i->mod == 0xc0) {
op2_8 = BX_READ_8BIT_REG(i->rm,i->extend8bit);
}
else {
/* pointer, segment address pair */
read_virtual_byte(i->seg, i->rm_addr, &op2_8);
}
/* zero extend byte op2 into qword op1 */
BX_WRITE_64BIT_REG(i->nnn, (Bit64u) op2_8);
#endif /* BX_CPU_LEVEL < 3 */
}
void
BX_CPU_C::MOVZX_GqEw(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("MOVZX_GvEw: not supported on < 386"));
#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 qword op1 */
BX_WRITE_64BIT_REG(i->nnn, (Bit64u) op2_16);
#endif /* BX_CPU_LEVEL < 3 */
}
void
BX_CPU_C::MOVSX_GqEb(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("MOVSX_GvEb: not supported on < 386"));
#else
Bit8u op2_8;
if (i->mod == 0xc0) {
op2_8 = BX_READ_8BIT_REG(i->rm,i->extend8bit);
}
else {
/* pointer, segment address pair */
read_virtual_byte(i->seg, i->rm_addr, &op2_8);
}
/* sign extend byte op2 into qword op1 */
BX_WRITE_64BIT_REG(i->nnn, (Bit8s) op2_8);
#endif /* BX_CPU_LEVEL < 3 */
}
void
BX_CPU_C::MOVSX_GqEw(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("MOVSX_GvEw: not supported on < 386"));
#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 qword op1 */
BX_WRITE_64BIT_REG(i->nnn, (Bit16s) op2_16);
#endif /* BX_CPU_LEVEL < 3 */
}
void
BX_CPU_C::MOVSX_GqEd(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("MOVSX_GvEw: not supported on < 386"));
#else
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);
}
/* sign extend word op2 into qword op1 */
BX_WRITE_64BIT_REG(i->nnn, (Bit16s) op2_32);
#endif /* BX_CPU_LEVEL < 3 */
}
void
BX_CPU_C::XCHG_EqGq(BxInstruction_t *i)
{
Bit64u op2_64, op1_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
BX_WRITE_64BIT_REG(i->rm, op2_64);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
write_RMW_virtual_qword(op2_64);
}
BX_WRITE_64BIT_REG(i->nnn, op1_64);
}
void
BX_CPU_C::CMOV_GqEq(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;
Bit64u op2_64;
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"));
}
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
if (condition) {
BX_WRITE_64BIT_REG(i->nnn, op2_64);
}
#else
BX_PANIC(("cmov_gded called"));
#endif
}

2691
bochs/cpu/fetchdecode64.cc Normal file

File diff suppressed because it is too large Load Diff

439
bochs/cpu/logical64.cc Normal file
View File

@ -0,0 +1,439 @@
/////////////////////////////////////////////////////////////////////////
// $Id: logical64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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_EqGq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op2_64, op1_64, result_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 ^ op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_XOR64);
}
void
BX_CPU_C::XOR_GqEq(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, result_64;
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
result_64 = op1_64 ^ op2_64;
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn, result_64);
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_XOR64);
}
void
BX_CPU_C::XOR_RAXId(BxInstruction_t *i)
{
/* for 64 bit operand size mode */
Bit64u op1_64, op2_64, sum_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
sum_64 = op1_64 ^ op2_64;
/* now write sum back to destination */
RAX = sum_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_XOR64);
}
void
BX_CPU_C::XOR_EqId(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 ^ op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_XOR64);
}
void
BX_CPU_C::OR_EqId(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 | op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_OR64);
}
void
BX_CPU_C::NOT_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = ~op1_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
}
void
BX_CPU_C::OR_EqGq(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 | op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_OR64);
}
void
BX_CPU_C::OR_GqEq(BxInstruction_t *i)
{
Bit64u op1_64, op2_64, result_64;
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
result_64 = op1_64 | op2_64;
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn, result_64);
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_OR64);
}
void
BX_CPU_C::OR_RAXId(BxInstruction_t *i)
{
Bit64u op1_64, op2_64, sum_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
sum_64 = op1_64 | op2_64;
/* now write sum back to destination */
RAX = sum_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_OR64);
}
void
BX_CPU_C::AND_EqGq(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 & op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_AND64);
}
void
BX_CPU_C::AND_GqEq(BxInstruction_t *i)
{
Bit64u op1_64, op2_64, result_64;
op1_64 = BX_READ_64BIT_REG(i->nnn);
/* op2_64 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
result_64 = op1_64 & op2_64;
/* now write result back to destination */
BX_WRITE_64BIT_REG(i->nnn, result_64);
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_AND64);
}
void
BX_CPU_C::AND_RAXId(BxInstruction_t *i)
{
Bit64u op1_64, op2_64, sum_64;
op1_64 = RAX;
op2_64 = (Bit32s) i->Id;
sum_64 = op1_64 & op2_64;
/* now write sum back to destination */
RAX = sum_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, sum_64, BX_INSTR_AND64);
}
void
BX_CPU_C::AND_EqId(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 & op2_64;
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_AND64);
}
void
BX_CPU_C::TEST_EqGq(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
/* op2_64 is a register, op2_addr is an index of a register */
op2_64 = BX_READ_64BIT_REG(i->nnn);
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 & op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_TEST64);
}
void
BX_CPU_C::TEST_RAXId(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
/* op1 is RAX register */
op1_64 = RAX;
/* op2 is imm64 */
op2_64 = (Bit32s) i->Id;
result_64 = op1_64 & op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_TEST64);
}
void
BX_CPU_C::TEST_EqId(BxInstruction_t *i)
{
Bit64u op2_64, op1_64, result_64;
/* op2 is imm64 */
op2_64 = (Bit32s) i->Id;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
result_64 = op1_64 & op2_64;
SET_FLAGS_OSZAPC_64(op1_64, op2_64, result_64, BX_INSTR_TEST64);
}

491
bochs/cpu/mult64.cc Normal file
View File

@ -0,0 +1,491 @@
/////////////////////////////////////////////////////////////////////////
// $Id: mult64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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
unsigned partial_add(Bit32u *sum,Bit32u b)
{
Bit32u t = *sum;
*sum += b;
return (*sum < t);
}
void
long_mul(Bit128u *product, Bit64u op1, Bit64u op2)
{
Bit32u op_1[2],op_2[2];
Bit32u result[5];
Bit64u nn;
unsigned c;
int i,j,k;
op_1[0] = op1 & 0xffffffff;
op_1[1] = op1 >> 32;
op_2[0] = op2 & 0xffffffff;
op_2[1] = op2 >> 32;
for (i = 0; i < 4; i++) result[i] = 0;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
nn = (Bit64u) op_1[i] * (Bit64u) op_2[j];
k = i + j;
c = partial_add(&result[k++],nn & 0xffffffff);
c = partial_add(&result[k++],(nn >> 32) + c);
while (k < 4 && c != 0) {
c = partial_add(&result[k++],c);
}
}
}
product->lo = result[0] + ((Bit64u) result[1] << 32);
product->hi = result[2] + ((Bit64u) result[3] << 32);
}
void
long_neg(Bit128s *n)
{
Bit64u t;
t = n->lo;
n->lo = -n->lo;
if (t > (Bit64u)n->lo) --n->hi;
n->hi = -n->hi;
}
void
long_imul(Bit128s *product, Bit64s op1, Bit64s op2)
{
unsigned s1,s2;
//BX_DEBUG (("long_imul %08X%08X X %08X%08X->",(unsigned)(op1 >> 32),(unsigned)op1,(unsigned)(op2 >> 32),(unsigned)op2));
if (s1 = (op1 < 0)) op1 = -op1;
if (s2 = (op2 < 0)) op2 = -op2;
long_mul((Bit128u*)product,(Bit64u)op1,(Bit64u)op2);
if (s1 ^ s2) {
long_neg(product);
}
//BX_DEBUG (("%08X%08X%08X%08X",
// (unsigned)(product->hi >> 32),(unsigned)product->hi,
// (unsigned)(product->lo >> 32),(unsigned)product->lo));
}
void
long_shl(Bit128u *a)
{
Bit64u c;
c = a->lo >> 63;
a->lo <<= 1;
a->hi <<= 1;
a->hi |= c;
}
void
long_shr(Bit128u *a)
{
Bit64u c;
c = a->hi << 63;
a->hi >>= 1;
a->lo >>= 1;
a->lo |= c;
}
unsigned
long_sub(Bit128u *a,Bit128u *b)
{
Bit64u t;
int c;
t = a->lo;
a->lo -= b->lo;
c = (a->lo > t);
t = a -> hi;
a->hi -= b->hi + c;
return(a->hi > t);
}
Boolean
long_le(Bit128u *a,Bit128u *b)
{
if (a->hi == b->hi) {
return(a->lo <= b->lo);
} else {
return(a->hi <= b->hi);
}
}
void
long_div(Bit128u *quotient,Bit64u *remainder,Bit128u *dividend,Bit64u divisor)
{
/*
n := 0;
while (divisor <= dividend) do
inc(n);
divisor := divisor * 2;
end;
quotient := 0;
while n > 0 do
divisor := divisor div 2;
quotient := quotient * 2;
temp := dividend;
dividend := dividend - divisor;
if temp > dividend then
dividend := temp;
else
inc(quotient);
end;
dec(n);
end;
remainder := dividend;
*/
Bit128u d,acc,q,temp;
int n,c;
d.lo = divisor;
d.hi = 0;
acc.lo = dividend->lo;
acc.hi = dividend->hi;
q.lo = 0;
q.hi = 0;
n = 0;
//BX_DEBUG (("ldiv: n=%d d=%08X acc=%08X",n,d.lo,acc.lo));
while (long_le(&d,&acc) && n < 128) {
long_shl(&d);
n++;
}
//BX_DEBUG (("ldiv: n=%d d=%08X acc=%08X",n,d.lo,acc.lo));
while (n > 0) {
long_shr(&d);
long_shl(&q);
temp.lo = acc.lo;
temp.hi = acc.hi;
c = long_sub(&acc,&d);
if (c) {
acc.lo = temp.lo;
acc.hi = temp.hi;
} else {
q.lo++;
}
n--;
}
//BX_DEBUG (("ldiv: n=%d d=%08X acc=%08X",n,d.lo,acc.lo));
*remainder = acc.lo;
quotient->lo = q.lo;
quotient->hi = q.hi;
}
void
long_idiv(Bit128s *quotient,Bit64s *remainder,Bit128s *dividend,Bit64s divisor)
{
unsigned s1,s2;
Bit128s temp;
temp = *dividend;
if (s1 = (temp.hi < 0)) {
long_neg(&temp);
}
if (s2 = (divisor < 0)) divisor = -divisor;
long_div((Bit128u*)quotient,(Bit64u*)remainder,(Bit128u*)&temp,divisor);
if (s1 ^ s2) {
long_neg(quotient);
}
if (s2) {
*remainder = -*remainder;
}
}
void
BX_CPU_C::MUL_RAXEq(BxInstruction_t *i)
{
Bit64u op1_64, op2_64;
Bit128u product_128;
Boolean temp_flag;
op1_64 = RAX;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
//product_128 = ((Bit128u) op1_64) * ((Bit128u) op2_64);
long_mul(&product_128,op1_64,op2_64);
//product_64l = (Bit64u) (product_128 & 0xFFFFFFFFFFFFFFFF);
//product_64h = (Bit64u) (product_128 >> 64);
/* now write product back to destination */
RAX = product_128.lo;
RDX = product_128.hi;
/* set eflags:
* MUL affects the following flags: C,O
*/
temp_flag = (product_128.hi != 0);
SET_FLAGS_OxxxxC(temp_flag, temp_flag);
}
void
BX_CPU_C::IMUL_RAXEq(BxInstruction_t *i)
{
Bit64s op1_64, op2_64;
Bit128s product_128;
//Bit64u product_64h, product_64l;
op1_64 = RAX;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, (Bit64u *) &op2_64);
}
//product_128 = ((Bit128s) op1_64) * ((Bit128s) op2_64);
long_imul(&product_128,op1_64,op2_64);
//product_64l = (Bit64u) (product_128 & 0xFFFFFFFFFFFFFFFF);
//product_64h = (Bit64u) (product_128 >> 64);
/* now write product back to destination */
RAX = product_128.lo;
RDX = product_128.hi;
/* set eflags:
* IMUL affects the following flags: C,O
* IMUL r/m16: condition for clearing CF & OF:
* RDX:RAX = sign-extend of RAX
*/
if ( (RDX==BX_CONST64(0xffffffffffffffff)) && (RAX & BX_CONST64(0x8000000000000000)) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else if ( (RDX==BX_CONST64(0x0000000000000000)) && (RAX < BX_CONST64(0x8000000000000000)) ) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
}
void
BX_CPU_C::DIV_RAXEq(BxInstruction_t *i)
{
Bit64u op2_64, remainder_64, quotient_64l;
Bit128u op1_128, quotient_128;
op1_128.lo = RAX;
op1_128.hi = RDX;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op2_64);
}
if (op2_64 == 0) {
exception(BX_DE_EXCEPTION, 0, 0);
}
//quotient_128 = op1_128 / op2_64;
//remainder_64 = (Bit64u) (op1_128 % op2_64);
//quotient_64l = (Bit64u) (quotient_128 & 0xFFFFFFFFFFFFFFFF);
long_div(&quotient_128,&remainder_64,&op1_128,op2_64);
quotient_64l = quotient_128.lo;
//if (quotient_128 != quotient_64l) {
if (quotient_128.hi != 0) {
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 */
RAX = quotient_64l;
RDX = remainder_64;
}
void
BX_CPU_C::IDIV_RAXEq(BxInstruction_t *i)
{
Bit64s op2_64, remainder_64, quotient_64l;
Bit128s op1_128, quotient_128;
op1_128.lo = RAX;
op1_128.hi = RDX;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, (Bit64u *) &op2_64);
}
if (op2_64 == 0) {
exception(BX_DE_EXCEPTION, 0, 0);
}
//quotient_128 = op1_128 / op2_64;
//remainder_64 = (Bit64s) (op1_128 % op2_64);
//quotient_64l = (Bit64s) (quotient_128 & 0xFFFFFFFFFFFFFFFF);
long_idiv(&quotient_128,&remainder_64,&op1_128,op2_64);
quotient_64l = quotient_128.lo;
//if (quotient_128 != quotient_64l) {
if (quotient_128.hi != 0) {
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 */
RAX = quotient_64l;
RDX = remainder_64;
}
void
BX_CPU_C::IMUL_GqEqId(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("IMUL_GdEdId() unsupported on 8086!"));
#else
Bit64s op2_64, op3_64, product_64;
Bit128s product_128;
op3_64 = (Bit32s) i->Id;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, (Bit64u *) &op2_64);
}
product_64 = op2_64 * op3_64;
//product_128 = ((Bit128s) op2_64) * ((Bit128s) op3_64);
long_imul(&product_128,op2_64,op3_64);
/* now write product back to destination */
BX_WRITE_64BIT_REG(i->nnn, product_64);
/* 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_128.lo == product_64) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
#endif
}
void
BX_CPU_C::IMUL_GqEq(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("IMUL_GvEv() unsupported on 8086!"));
#else
Bit64s op1_64, op2_64, product_64;
Bit128s product_128;
/* op2 is a register or memory reference */
if (i->mod == 0xc0) {
op2_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, (Bit64u *) &op2_64);
}
op1_64 = BX_READ_64BIT_REG(i->nnn);
product_64 = op1_64 * op2_64;
//product_128 = ((Bit128s) op1_64) * ((Bit128s) op2_64);
long_imul(&product_128,op1_64,op2_64);
/* now write product back to destination */
BX_WRITE_64BIT_REG(i->nnn, product_64);
/* 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_128.lo == product_64) {
SET_FLAGS_OxxxxC(0, 0);
}
else {
SET_FLAGS_OxxxxC(1, 1);
}
#endif
}

457
bochs/cpu/resolve64.cc Normal file
View File

@ -0,0 +1,457 @@
/////////////////////////////////////////////////////////////////////////
// $Id: resolve64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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::Resolve64Mod0Rm0(BxInstruction_t *i)
{
i->rm_addr = RAX;
}
void
BX_CPU_C::Resolve64Mod0Rm1(BxInstruction_t *i)
{
i->rm_addr = RCX;
}
void
BX_CPU_C::Resolve64Mod0Rm2(BxInstruction_t *i)
{
i->rm_addr = RDX;
}
void
BX_CPU_C::Resolve64Mod0Rm3(BxInstruction_t *i)
{
i->rm_addr = RBX;
}
void
BX_CPU_C::Resolve64Mod0Rm5(BxInstruction_t *i)
{
// eip hasn't been bumped yet when this is called. must choose the saved value.
i->rm_addr = BX_CPU_THIS_PTR prev_eip + i->ilen + (Bit32s)i->displ32u;
}
void
BX_CPU_C::Resolve64Mod0Rm6(BxInstruction_t *i)
{
i->rm_addr = RSI;
}
void
BX_CPU_C::Resolve64Mod0Rm7(BxInstruction_t *i)
{
i->rm_addr = RDI;
}
void
BX_CPU_C::Resolve64Mod0Rm8(BxInstruction_t *i)
{
i->rm_addr = R8;
}
void
BX_CPU_C::Resolve64Mod0Rm9(BxInstruction_t *i)
{
i->rm_addr = R9;
}
void
BX_CPU_C::Resolve64Mod0Rm10(BxInstruction_t *i)
{
i->rm_addr = R10;
}
void
BX_CPU_C::Resolve64Mod0Rm11(BxInstruction_t *i)
{
i->rm_addr = R11;
}
void
BX_CPU_C::Resolve64Mod0Rm12(BxInstruction_t *i)
{
i->rm_addr = R12;
}
void
BX_CPU_C::Resolve64Mod0Rm13(BxInstruction_t *i)
{
i->rm_addr = R13;
}
void
BX_CPU_C::Resolve64Mod0Rm14(BxInstruction_t *i)
{
i->rm_addr = R14;
}
void
BX_CPU_C::Resolve64Mod0Rm15(BxInstruction_t *i)
{
i->rm_addr = R15;
}
void
BX_CPU_C::Resolve64Mod1or2Rm0(BxInstruction_t *i)
{
i->rm_addr = RAX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm1(BxInstruction_t *i)
{
i->rm_addr = RCX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm2(BxInstruction_t *i)
{
i->rm_addr = RDX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm3(BxInstruction_t *i)
{
i->rm_addr = RBX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm5(BxInstruction_t *i)
{
i->rm_addr = RBP + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm6(BxInstruction_t *i)
{
i->rm_addr = RSI + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm7(BxInstruction_t *i)
{
i->rm_addr = RDI + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm8(BxInstruction_t *i)
{
i->rm_addr = R8 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm9(BxInstruction_t *i)
{
i->rm_addr = R9 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm10(BxInstruction_t *i)
{
i->rm_addr = R10 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm11(BxInstruction_t *i)
{
i->rm_addr = R11 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm12(BxInstruction_t *i)
{
i->rm_addr = R12 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm13(BxInstruction_t *i)
{
i->rm_addr = R13 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm14(BxInstruction_t *i)
{
i->rm_addr = R14 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Rm15(BxInstruction_t *i)
{
i->rm_addr = R15 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod0Base0(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RAX + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RAX;
}
void
BX_CPU_C::Resolve64Mod0Base1(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RCX + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RCX;
}
void
BX_CPU_C::Resolve64Mod0Base2(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RDX + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RDX;
}
void
BX_CPU_C::Resolve64Mod0Base3(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RBX + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RBX;
}
void
BX_CPU_C::Resolve64Mod0Base4(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RSP + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RSP;
}
void
BX_CPU_C::Resolve64Mod0Base5(BxInstruction_t *i)
{
if (i->index != 4) {
i->rm_addr = (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
}
else
i->rm_addr = (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod0Base6(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RSI + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RSI;
}
void
BX_CPU_C::Resolve64Mod0Base7(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RDI + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = RDI;
}
void
BX_CPU_C::Resolve64Mod0Base8(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R8 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R8;
}
void
BX_CPU_C::Resolve64Mod0Base9(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R9 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R9;
}
void
BX_CPU_C::Resolve64Mod0Base10(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R10 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R10;
}
void
BX_CPU_C::Resolve64Mod0Base11(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R11 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R11;
}
void
BX_CPU_C::Resolve64Mod0Base12(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R12 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R12;
}
void
BX_CPU_C::Resolve64Mod0Base13(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R13 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R13;
}
void
BX_CPU_C::Resolve64Mod0Base14(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R14 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R14;
}
void
BX_CPU_C::Resolve64Mod0Base15(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R15 + (BX_READ_64BIT_REG(i->index) << i->scale);
else
i->rm_addr = R15;
}
void
BX_CPU_C::Resolve64Mod1or2Base0(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RAX + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RAX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base1(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RCX + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RCX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base2(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RDX + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RDX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base3(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RBX + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RBX + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base4(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RSP + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RSP + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base5(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RBP + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RBP + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base6(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RSI + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RSI + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base7(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = RDI + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = RDI + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base8(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R8 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R8 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base9(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R9 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R9 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base10(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R10 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R10 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base11(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R11 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R11 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base12(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R12 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R12 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base13(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R13 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R13 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base14(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R14 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R14 + (Bit32s) i->displ32u;
}
void
BX_CPU_C::Resolve64Mod1or2Base15(BxInstruction_t *i)
{
if (i->index != 4)
i->rm_addr = R15 + (BX_READ_64BIT_REG(i->index) << i->scale) + (Bit32s) i->displ32u;
else
i->rm_addr = R15 + (Bit32s) i->displ32u;
}

465
bochs/cpu/shift64.cc Normal file
View File

@ -0,0 +1,465 @@
/////////////////////////////////////////////////////////////////////////
// $Id: shift64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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_EqGq(BxInstruction_t *i)
{
Bit64u op1_64, op2_64, result_64;
unsigned count;
/* op1:op2 << count. result stored in op1 */
if (i->b1 == 0x1a4)
count = i->Ib & 0x3f;
else // 0x1a5
count = CL & 0x3f;
if (!count) return; /* NOP */
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
op2_64 = BX_READ_64BIT_REG(i->nnn);
result_64 = (op1_64 << count) | (op2_64 >> (64 - count));
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* SHLD count affects the following flags: S,Z,P,C,O
*/
set_CF((op1_64 >> (64 - count)) & 0x01);
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
set_ZF(result_64 == 0);
set_PF_base(result_64);
set_SF(result_64 >> 63);
}
void
BX_CPU_C::SHRD_EqGq(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 3
BX_PANIC(("shrd_evgvib: not supported on < 386"));
#else
Bit64u op1_64, op2_64, result_64;
unsigned count;
if (i->b1 == 0x1ac)
count = i->Ib & 0x3f;
else // 0x1ad
count = CL & 0x3f;
if (!count) return; /* NOP */
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
op2_64 = BX_READ_64BIT_REG(i->nnn);
result_64 = (op2_64 << (64 - count)) | (op1_64 >> count);
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* SHRD count affects the following flags: S,Z,P,C,O
*/
set_CF((op1_64 >> (count - 1)) & 0x01);
set_ZF(result_64 == 0);
set_SF(result_64 >> 63);
/* for shift of 1, OF set if sign change occurred. */
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
set_PF_base(result_64);
#endif /* BX_CPU_LEVEL >= 3 */
}
void
BX_CPU_C::ROL_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (count) {
result_64 = (op1_64 << count) | (op1_64 >> (64 - count));
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* ROL count affects the following flags: C
*/
set_CF(result_64 & 0x01);
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
}
}
void
BX_CPU_C::ROR_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64, result_b63;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (count) {
result_64 = (op1_64 >> count) | (op1_64 << (64 - count));
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* ROR count affects the following flags: C
*/
result_b63 = result_64 & BX_CONST64(0x8000000000000000);
set_CF(result_b63 != 0);
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
}
}
void
BX_CPU_C::RCL_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (!count) return;
if (count==1) {
result_64 = (op1_64 << 1) | get_CF();
}
else {
result_64 = (op1_64 << count) |
(get_CF() << (count - 1)) |
(op1_64 >> (65 - count));
}
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* RCL count affects the following flags: C
*/
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
set_CF((op1_64 >> (64 - count)) & 0x01);
}
void
BX_CPU_C::RCR_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (!count) return;
if (count==1) {
result_64 = (op1_64 >> 1) | (((Bit64u) get_CF()) << 63);
}
else {
result_64 = (op1_64 >> count) |
(get_CF() << (64 - count)) |
(op1_64 << (65 - count));
}
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* RCR count affects the following flags: C
*/
set_CF((op1_64 >> (count - 1)) & 0x01);
if (count == 1)
set_OF(((op1_64 ^ result_64) & BX_CONST64(0x8000000000000000)) > 0);
}
void
BX_CPU_C::SHL_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (!count) return;
result_64 = (op1_64 << count);
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHL64);
}
void
BX_CPU_C::SHR_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (!count) return;
result_64 = (op1_64 >> count);
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
SET_FLAGS_OSZAPC_64(op1_64, count, result_64, BX_INSTR_SHR64);
}
void
BX_CPU_C::SAR_Eq(BxInstruction_t *i)
{
Bit64u op1_64, result_64;
unsigned count;
if (i->b1 == 0xc1)
count = i->Ib & 0x3f;
else if (i->b1 == 0xd1)
count = 1;
else // (i->b1 == 0xd3)
count = CL & 0x3f;
/* op1 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_RMW_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
if (!count) return;
/* count < 64, since only lower 5 bits used */
if (op1_64 & BX_CONST64(0x8000000000000000)) {
result_64 = (op1_64 >> count) | (BX_CONST64(0xffffffffffffffff) << (64 - count));
}
else {
result_64 = (op1_64 >> count);
}
/* now write result back to destination */
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, result_64);
}
else {
write_RMW_virtual_qword(result_64);
}
/* set eflags:
* SAR count affects the following flags: S,Z,P,C
*/
set_CF((op1_64 >> (count - 1)) & 0x01);
set_ZF(result_64 == 0);
set_SF(result_64 >> 63);
if (count == 1)
set_OF(0);
set_PF_base(result_64);
}

338
bochs/cpu/stack64.cc Normal file
View File

@ -0,0 +1,338 @@
/////////////////////////////////////////////////////////////////////////
// $Id: stack64.cc,v 1.1 2002-09-13 15:53:22 kevinlawton Exp $
/////////////////////////////////////////////////////////////////////////
//
// 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_Eq(BxInstruction_t *i)
{
Bit64u val64;
pop_64(&val64);
if (i->mod == 0xc0) {
BX_WRITE_64BIT_REG(i->rm, val64);
}
else {
// Note: there is one little weirdism here. When 64bit addressing
// is used, it is possible to use RSP in the modrm addressing.
// If used, the value of RSP after the pop is used to calculate
// the address.
if (i->as_64 && (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_qword(i->seg, i->rm_addr, &val64);
}
}
void
BX_CPU_C::PUSH_RRX(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR gen_reg[i->nnn].rrx);
}
void
BX_CPU_C::POP_RRX(BxInstruction_t *i)
{
Bit64u rrx;
pop_64(&rrx);
BX_CPU_THIS_PTR gen_reg[i->nnn].rrx = rrx;
}
void
BX_CPU_C::PUSH64_CS(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
}
void
BX_CPU_C::PUSH64_DS(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value);
}
void
BX_CPU_C::PUSH64_ES(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value);
}
void
BX_CPU_C::PUSH64_FS(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value);
}
void
BX_CPU_C::PUSH64_GS(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value);
}
void
BX_CPU_C::PUSH64_SS(BxInstruction_t *i)
{
push_64(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
}
void
BX_CPU_C::POP64_DS(BxInstruction_t *i)
{
Bit64u ds;
pop_64(&ds);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS], (Bit16u) ds);
}
void
BX_CPU_C::POP64_ES(BxInstruction_t *i)
{
Bit64u es;
pop_64(&es);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES], (Bit16u) es);
}
void
BX_CPU_C::POP64_FS(BxInstruction_t *i)
{
Bit64u fs;
pop_64(&fs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], (Bit16u) fs);
}
void
BX_CPU_C::POP64_GS(BxInstruction_t *i)
{
Bit64u gs;
pop_64(&gs);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], (Bit16u) gs);
}
void
BX_CPU_C::POP64_SS(BxInstruction_t *i)
{
Bit64u ss;
pop_64(&ss);
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS], (Bit16u) 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::PUSHAD64(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("PUSHAD: not supported on an 8086"));
#else
Bit64u temp_RSP;
Bit64u rsp;
temp_RSP = RSP;
if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_RSP, 64) ) {
BX_PANIC(("PUSHAD(): stack doesn't have enough room!"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
rsp = RSP;
/* ??? optimize this by using virtual write, all checks passed */
push_64(RAX);
push_64(RCX);
push_64(RDX);
push_64(RBX);
push_64(rsp);
push_64(RBP);
push_64(RSI);
push_64(RDI);
#endif
}
void
BX_CPU_C::POPAD64(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("POPAD not supported on an 8086"));
#else /* 286+ */
Bit64u rdi, rsi, rbp, rtmp, rbx, rdx, rcx, rax;
if ( !can_pop(64) ) {
BX_PANIC(("pop_ad: not enough bytes on stack"));
exception(BX_SS_EXCEPTION, 0, 0);
return;
}
/* ??? optimize this */
pop_64(&rdi);
pop_64(&rsi);
pop_64(&rbp);
pop_64(&rtmp); /* value for ESP discarded */
pop_64(&rbx);
pop_64(&rdx);
pop_64(&rcx);
pop_64(&rax);
RDI = rdi;
RSI = rsi;
RBP = rbp;
RBX = rbx;
RDX = rdx;
RCX = rcx;
RAX = rax;
#endif
}
void
BX_CPU_C::PUSH64_Id(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("PUSH_Id: not supported on 8086!"));
#else
Bit64u imm64;
imm64 = (Bit32s) i->Id;
push_64(imm64);
#endif
}
void
BX_CPU_C::PUSH_Eq(BxInstruction_t *i)
{
Bit64u op1_64;
/* op1_64 is a register or memory reference */
if (i->mod == 0xc0) {
op1_64 = BX_READ_64BIT_REG(i->rm);
}
else {
/* pointer, segment address pair */
read_virtual_qword(i->seg, i->rm_addr, &op1_64);
}
push_64(op1_64);
}
void
BX_CPU_C::ENTER64_IwIb(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("ENTER_IwIb: not supported by 8086!"));
#else
Bit64u frame_ptr64;
Bit16u frame_ptr16;
Bit8u level;
static Bit8u first_time = 1;
level = i->Ib2;
invalidate_prefetch_q();
level %= 32;
/* ??? */
if (first_time && level>0) {
BX_ERROR(("enter() with level > 0. The emulation of this instruction may not be complete. This warning will be printed only once per bochs run."));
first_time = 0;
}
//if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b && i->os_64==0) {
// BX_INFO(("enter(): stacksize!=opsize: I'm unsure of the code for this"));
// BX_PANIC((" The Intel manuals are a mess on this one!"));
// }
{
Bit64u bytes_to_push, temp_RSP;
if (level == 0) {
bytes_to_push = 8 + i->Iw;
}
else { /* level > 0 */
bytes_to_push = 8 + (level-1)*8 + 8 + i->Iw;
}
temp_RSP = RSP;
if ( !can_push(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache, temp_RSP, bytes_to_push) ) {
BX_PANIC(("ENTER: not enough room on stack!"));
exception(BX_SS_EXCEPTION, 0, 0);
}
}
push_64(RBP);
frame_ptr64 = RSP;
if (level > 0) {
/* do level-1 times */
while (--level) {
Bit64u temp64;
RBP -= 4;
read_virtual_qword(BX_SEG_REG_SS, RBP, &temp64);
ESP -= 4;
write_virtual_qword(BX_SEG_REG_SS, RSP, &temp64);
} /* while (--level) */
/* push(frame pointer) */
RSP -= 4;
write_virtual_qword(BX_SEG_REG_SS, RSP, &frame_ptr64);
} /* if (level > 0) ... */
RBP = frame_ptr64;
RSP = RSP - i->Iw;
#endif
}
void
BX_CPU_C::LEAVE64(BxInstruction_t *i)
{
#if BX_CPU_LEVEL < 2
BX_PANIC(("LEAVE: not supported by 8086!"));
#else
// delete frame
RSP = RBP;
// restore frame pointer
{
Bit64u temp64;
pop_64(&temp64);
RBP = temp64;
}
#endif
}