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:
parent
5ca59b4d4f
commit
f05d453b6c
173
bochs/configure
vendored
173
bochs/configure
vendored
@ -623,7 +623,7 @@ else
|
|||||||
fi
|
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"
|
VERSION="1.4.cvs"
|
||||||
@ -3658,6 +3658,7 @@ if test "${enable_x86_64+set}" = set; then
|
|||||||
echo "$ac_t""yes" 1>&6
|
echo "$ac_t""yes" 1>&6
|
||||||
CPUDIR=cpu64
|
CPUDIR=cpu64
|
||||||
LIBCPU32_A=""
|
LIBCPU32_A=""
|
||||||
|
OBJS64_CPU='$(OBJS64_CPU)'
|
||||||
cat >> confdefs.h <<\EOF
|
cat >> confdefs.h <<\EOF
|
||||||
#define BX_SUPPORT_X86_64 1
|
#define BX_SUPPORT_X86_64 1
|
||||||
EOF
|
EOF
|
||||||
@ -3667,6 +3668,7 @@ EOF
|
|||||||
echo "$ac_t""no" 1>&6
|
echo "$ac_t""no" 1>&6
|
||||||
CPUDIR=cpu
|
CPUDIR=cpu
|
||||||
LIBCPU32_A=libcpu.a
|
LIBCPU32_A=libcpu.a
|
||||||
|
OBJS64_CPU=''
|
||||||
cat >> confdefs.h <<\EOF
|
cat >> confdefs.h <<\EOF
|
||||||
#define BX_SUPPORT_X86_64 0
|
#define BX_SUPPORT_X86_64 0
|
||||||
EOF
|
EOF
|
||||||
@ -3678,6 +3680,7 @@ else
|
|||||||
echo "$ac_t""no" 1>&6
|
echo "$ac_t""no" 1>&6
|
||||||
CPUDIR=cpu
|
CPUDIR=cpu
|
||||||
LIBCPU32_A=libcpu.a
|
LIBCPU32_A=libcpu.a
|
||||||
|
OBJS64_CPU=''
|
||||||
cat >> confdefs.h <<\EOF
|
cat >> confdefs.h <<\EOF
|
||||||
#define BX_SUPPORT_X86_64 0
|
#define BX_SUPPORT_X86_64 0
|
||||||
EOF
|
EOF
|
||||||
@ -3689,8 +3692,9 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for cpu level""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-cpu-level or --disable-cpu-level was given.
|
||||||
if test "${enable_cpu_level+set}" = set; then
|
if test "${enable_cpu_level+set}" = set; then
|
||||||
enableval="$enable_cpu_level"
|
enableval="$enable_cpu_level"
|
||||||
@ -3784,7 +3788,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for dynamic translation support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-dynamic or --disable-dynamic was given.
|
||||||
if test "${enable_dynamic+set}" = set; then
|
if test "${enable_dynamic+set}" = set; then
|
||||||
enableval="$enable_dynamic"
|
enableval="$enable_dynamic"
|
||||||
@ -3857,7 +3861,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for fetchdecode-cache support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-fetchdecode-cache or --disable-fetchdecode-cache was given.
|
||||||
if test "${enable_fetchdecode_cache+set}" = set; then
|
if test "${enable_fetchdecode_cache+set}" = set; then
|
||||||
enableval="$enable_fetchdecode_cache"
|
enableval="$enable_fetchdecode_cache"
|
||||||
@ -3887,7 +3891,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for APIC support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-apic or --disable-apic was given.
|
||||||
if test "${enable_apic+set}" = set; then
|
if test "${enable_apic+set}" = set; then
|
||||||
enableval="$enable_apic"
|
enableval="$enable_apic"
|
||||||
@ -3942,7 +3946,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for split hard disk image support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-split-hd or --disable-split-hd was given.
|
||||||
if test "${enable_split_hd+set}" = set; then
|
if test "${enable_split_hd+set}" = set; then
|
||||||
enableval="$enable_split_hd"
|
enableval="$enable_split_hd"
|
||||||
@ -3973,7 +3977,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for NE2000 support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-ne2000 or --disable-ne2000 was given.
|
||||||
if test "${enable_ne2000+set}" = set; then
|
if test "${enable_ne2000+set}" = set; then
|
||||||
enableval="$enable_ne2000"
|
enableval="$enable_ne2000"
|
||||||
@ -3986,17 +3990,17 @@ EOF
|
|||||||
NE2K_OBJS='ne2k.o eth.o eth_null.o'
|
NE2K_OBJS='ne2k.o eth.o eth_null.o'
|
||||||
ac_safe=`echo "net/bpf.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "net/bpf.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for net/bpf.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 3995 "configure"
|
#line 3999 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <net/bpf.h>
|
#include <net/bpf.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -4019,17 +4023,17 @@ fi
|
|||||||
|
|
||||||
ac_safe=`echo "netpacket/packet.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "netpacket/packet.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for netpacket/packet.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4028 "configure"
|
#line 4032 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <netpacket/packet.h>
|
#include <netpacket/packet.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -4052,17 +4056,17 @@ fi
|
|||||||
|
|
||||||
ac_safe=`echo "linux/netlink.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "linux/netlink.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for linux/netlink.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4061 "configure"
|
#line 4065 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -4091,17 +4095,17 @@ fi
|
|||||||
|
|
||||||
ac_safe=`echo "linux/if_tun.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "linux/if_tun.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for linux/if_tun.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4100 "configure"
|
#line 4104 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <linux/if_tun.h>
|
#include <linux/if_tun.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -4160,7 +4164,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for i440FX PCI support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-pci or --disable-pci was given.
|
||||||
if test "${enable_pci+set}" = set; then
|
if test "${enable_pci+set}" = set; then
|
||||||
enableval="$enable_pci"
|
enableval="$enable_pci"
|
||||||
@ -4195,7 +4199,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for 4Meg pages support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-4meg-pages or --disable-4meg-pages was given.
|
||||||
if test "${enable_4meg_pages+set}" = set; then
|
if test "${enable_4meg_pages+set}" = set; then
|
||||||
enableval="$enable_4meg_pages"
|
enableval="$enable_4meg_pages"
|
||||||
@ -4226,7 +4230,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for guest to host TLB support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-guest2host-tlb or --disable-guest2host-tlb was given.
|
||||||
if test "${enable_guest2host_tlb+set}" = set; then
|
if test "${enable_guest2host_tlb+set}" = set; then
|
||||||
enableval="$enable_guest2host_tlb"
|
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 $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.
|
# Check whether --enable-repeat-speedups or --disable-repeat-speedups was given.
|
||||||
if test "${enable_repeat_speedups+set}" = set; then
|
if test "${enable_repeat_speedups+set}" = set; then
|
||||||
enableval="$enable_repeat_speedups"
|
enableval="$enable_repeat_speedups"
|
||||||
@ -4288,7 +4292,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for Global pages support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-global-pages or --disable-global-pages was given.
|
||||||
if test "${enable_global_pages+set}" = set; then
|
if test "${enable_global_pages+set}" = set; then
|
||||||
enableval="$enable_global_pages"
|
enableval="$enable_global_pages"
|
||||||
@ -4320,7 +4324,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for port e9 hack""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-port-e9-hack or --disable-port-e9-hack was given.
|
||||||
if test "${enable_port_e9_hack+set}" = set; then
|
if test "${enable_port_e9_hack+set}" = set; then
|
||||||
enableval="$enable_port_e9_hack"
|
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 $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.
|
# Check whether --enable-cpp or --disable-cpp was given.
|
||||||
if test "${enable_cpp+set}" = set; then
|
if test "${enable_cpp+set}" = set; then
|
||||||
enableval="$enable_cpp"
|
enableval="$enable_cpp"
|
||||||
@ -4394,7 +4398,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for Bochs internal debugger support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-debugger or --disable-debugger was given.
|
||||||
if test "${enable_debugger+set}" = set; then
|
if test "${enable_debugger+set}" = set; then
|
||||||
enableval="$enable_debugger"
|
enableval="$enable_debugger"
|
||||||
@ -4432,7 +4436,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for external debugger""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-external-debugger or --disable-external-debugger was given.
|
||||||
if test "${enable_external_debugger+set}" = set; then
|
if test "${enable_external_debugger+set}" = set; then
|
||||||
enableval="$enable_external_debugger"
|
enableval="$enable_external_debugger"
|
||||||
@ -4456,7 +4460,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for disassembler support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-disasm or --disable-disasm was given.
|
||||||
if test "${enable_disasm+set}" = set; then
|
if test "${enable_disasm+set}" = set; then
|
||||||
enableval="$enable_disasm"
|
enableval="$enable_disasm"
|
||||||
@ -4507,14 +4511,14 @@ rl_without_curses_ok=no
|
|||||||
rl_with_curses_ok=no
|
rl_with_curses_ok=no
|
||||||
|
|
||||||
echo $ac_n "checking if readline works without -lcurses""... $ac_c" 1>&6
|
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
|
OLD_LIBS=$LIBS
|
||||||
LIBS="$LIBS -lreadline"
|
LIBS="$LIBS -lreadline"
|
||||||
if test "$cross_compiling" = yes; then
|
if test "$cross_compiling" = yes; then
|
||||||
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
|
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4518 "configure"
|
#line 4522 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -4522,7 +4526,7 @@ else
|
|||||||
int main() { rl_initialize(); exit(0); }
|
int main() { rl_initialize(); exit(0); }
|
||||||
|
|
||||||
EOF
|
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
|
then
|
||||||
echo "$ac_t""yes" 1>&6
|
echo "$ac_t""yes" 1>&6
|
||||||
rl_without_curses_ok=yes
|
rl_without_curses_ok=yes
|
||||||
@ -4537,13 +4541,13 @@ rm -fr conftest*
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking if readline works with -lcurses""... $ac_c" 1>&6
|
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"
|
LIBS="$LIBS -lcurses"
|
||||||
if test "$cross_compiling" = yes; then
|
if test "$cross_compiling" = yes; then
|
||||||
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
|
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4547 "configure"
|
#line 4551 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -4551,7 +4555,7 @@ else
|
|||||||
int main() { rl_initialize(); exit(0); }
|
int main() { rl_initialize(); exit(0); }
|
||||||
|
|
||||||
EOF
|
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
|
then
|
||||||
echo "$ac_t""yes" 1>&6
|
echo "$ac_t""yes" 1>&6
|
||||||
rl_with_curses_ok=yes
|
rl_with_curses_ok=yes
|
||||||
@ -4568,7 +4572,7 @@ fi
|
|||||||
LIBS=$OLD_LIBS
|
LIBS=$OLD_LIBS
|
||||||
|
|
||||||
echo $ac_n "checking whether user wants readline""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-readline or --disable-readline was given.
|
||||||
if test "${enable_readline+set}" = set; then
|
if test "${enable_readline+set}" = set; then
|
||||||
enableval="$enable_readline"
|
enableval="$enable_readline"
|
||||||
@ -4590,7 +4594,7 @@ fi
|
|||||||
|
|
||||||
use_readline=0
|
use_readline=0
|
||||||
echo $ac_n "checking whether to use readline""... $ac_c" 1>&6
|
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 "$want_readline" = yes; then
|
||||||
if test "$bx_debugger" = 1; then
|
if test "$bx_debugger" = 1; then
|
||||||
if test "$rl_without_curses_ok" = yes; then
|
if test "$rl_without_curses_ok" = yes; then
|
||||||
@ -4623,17 +4627,17 @@ fi
|
|||||||
|
|
||||||
ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "readline/history.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for readline/history.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 4632 "configure"
|
#line 4636 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -4660,7 +4664,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for loader support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-loader or --disable-loader was given.
|
||||||
if test "${enable_loader+set}" = set; then
|
if test "${enable_loader+set}" = set; then
|
||||||
enableval="$enable_loader"
|
enableval="$enable_loader"
|
||||||
@ -4698,7 +4702,7 @@ fi
|
|||||||
INSTRUMENT_DIR='instrument/stubs'
|
INSTRUMENT_DIR='instrument/stubs'
|
||||||
|
|
||||||
echo $ac_n "checking for instrumentation support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-instrumentation or --disable-instrumentation was given.
|
||||||
if test "${enable_instrumentation+set}" = set; then
|
if test "${enable_instrumentation+set}" = set; then
|
||||||
enableval="$enable_instrumentation"
|
enableval="$enable_instrumentation"
|
||||||
@ -4833,7 +4837,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for VGA emulation""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-vga or --disable-vga was given.
|
||||||
if test "${enable_vga+set}" = set; then
|
if test "${enable_vga+set}" = set; then
|
||||||
enableval="$enable_vga"
|
enableval="$enable_vga"
|
||||||
@ -4867,7 +4871,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for VESA BIOS extensions""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-vbe or --disable-vbe was given.
|
||||||
if test "${enable_vbe+set}" = set; then
|
if test "${enable_vbe+set}" = set; then
|
||||||
enableval="$enable_vbe"
|
enableval="$enable_vbe"
|
||||||
@ -4897,7 +4901,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for MMX support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-mmx or --disable-mmx was given.
|
||||||
if test "${enable_mmx+set}" = set; then
|
if test "${enable_mmx+set}" = set; then
|
||||||
enableval="$enable_mmx"
|
enableval="$enable_mmx"
|
||||||
@ -4928,7 +4932,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for FPU emulation""... $ac_c" 1>&6
|
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_VAR=''
|
||||||
FPU_GLUE_OBJ=''
|
FPU_GLUE_OBJ=''
|
||||||
# Check whether --enable-fpu or --disable-fpu was given.
|
# 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 $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.
|
# Check whether --enable-x86-debugger or --disable-x86-debugger was given.
|
||||||
if test "${enable_x86_debugger+set}" = set; then
|
if test "${enable_x86_debugger+set}" = set; then
|
||||||
enableval="$enable_x86_debugger"
|
enableval="$enable_x86_debugger"
|
||||||
@ -5010,17 +5014,17 @@ fi
|
|||||||
|
|
||||||
ac_safe=`echo "IOKit/storage/IOCDMedia.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "IOKit/storage/IOCDMedia.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for IOKit/storage/IOCDMedia.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5019 "configure"
|
#line 5023 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <IOKit/storage/IOCDMedia.h>
|
#include <IOKit/storage/IOCDMedia.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -5044,7 +5048,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for CDROM support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-cdrom or --disable-cdrom was given.
|
||||||
if test "${enable_cdrom+set}" = set; then
|
if test "${enable_cdrom+set}" = set; then
|
||||||
enableval="$enable_cdrom"
|
enableval="$enable_cdrom"
|
||||||
@ -5104,7 +5108,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for Sound Blaster 16 support""... $ac_c" 1>&6
|
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.
|
# Check whether --enable-sb16 or --disable-sb16 was given.
|
||||||
if test "${enable_sb16+set}" = set; then
|
if test "${enable_sb16+set}" = set; then
|
||||||
enableval="$enable_sb16"
|
enableval="$enable_sb16"
|
||||||
@ -5178,7 +5182,7 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
echo $ac_n "checking for I/O Interface to the debugger""... $ac_c" 1>&6
|
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=''
|
IODEBUG_OBJS=''
|
||||||
# Check whether --enable-iodebug or --disable-iodebug was given.
|
# Check whether --enable-iodebug or --disable-iodebug was given.
|
||||||
if test "${enable_iodebug+set}" = set; then
|
if test "${enable_iodebug+set}" = set; then
|
||||||
@ -5341,10 +5345,10 @@ INSTALL_TARGET=install_unix
|
|||||||
INSTALL_LIST_FOR_PLATFORM=
|
INSTALL_LIST_FOR_PLATFORM=
|
||||||
|
|
||||||
echo $ac_n "checking for default gui on this platform""... $ac_c" 1>&6
|
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_t""$DEFAULT_GUI" 1>&6
|
||||||
echo $ac_n "checking for gui library to use""... $ac_c" 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
|
# the $with_* variable tells the gui library to use, but does NOT necessarily
|
||||||
# indicate the platform. Settings that depend on the platform should be
|
# indicate the platform. Settings that depend on the platform should be
|
||||||
@ -5554,7 +5558,7 @@ esac
|
|||||||
|
|
||||||
if test "$use_curses" = yes; then
|
if test "$use_curses" = yes; then
|
||||||
echo $ac_n "checking for mvaddch in -lcurses""... $ac_c" 1>&6
|
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_%'`
|
ac_lib_var=`echo curses'_'mvaddch | sed 'y%./+-%__p_%'`
|
||||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
@ -5562,7 +5566,7 @@ else
|
|||||||
ac_save_LIBS="$LIBS"
|
ac_save_LIBS="$LIBS"
|
||||||
LIBS="-lcurses $LIBS"
|
LIBS="-lcurses $LIBS"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5566 "configure"
|
#line 5570 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
@ -5573,7 +5577,7 @@ int main() {
|
|||||||
mvaddch()
|
mvaddch()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||||
else
|
else
|
||||||
@ -5594,7 +5598,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for mvaddch in -lncurses""... $ac_c" 1>&6
|
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_%'`
|
ac_lib_var=`echo ncurses'_'mvaddch | sed 'y%./+-%__p_%'`
|
||||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
@ -5602,7 +5606,7 @@ else
|
|||||||
ac_save_LIBS="$LIBS"
|
ac_save_LIBS="$LIBS"
|
||||||
LIBS="-lncurses $LIBS"
|
LIBS="-lncurses $LIBS"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5606 "configure"
|
#line 5610 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
@ -5613,7 +5617,7 @@ int main() {
|
|||||||
mvaddch()
|
mvaddch()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||||
else
|
else
|
||||||
@ -5634,7 +5638,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking for mvaddch in -ltermlib""... $ac_c" 1>&6
|
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_%'`
|
ac_lib_var=`echo termlib'_'mvaddch | sed 'y%./+-%__p_%'`
|
||||||
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
@ -5642,7 +5646,7 @@ else
|
|||||||
ac_save_LIBS="$LIBS"
|
ac_save_LIBS="$LIBS"
|
||||||
LIBS="-ltermlib $LIBS"
|
LIBS="-ltermlib $LIBS"
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5646 "configure"
|
#line 5650 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
@ -5653,7 +5657,7 @@ int main() {
|
|||||||
mvaddch()
|
mvaddch()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
eval "ac_cv_lib_$ac_lib_var=yes"
|
eval "ac_cv_lib_$ac_lib_var=yes"
|
||||||
else
|
else
|
||||||
@ -5695,17 +5699,17 @@ acx_pthread_ok=no
|
|||||||
# If it isn't, don't bother looking for the threads libraries.
|
# If it isn't, don't bother looking for the threads libraries.
|
||||||
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
|
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
|
||||||
echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5704 "configure"
|
#line 5708 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
EOF
|
EOF
|
||||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
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}\$"`
|
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||||
if test -z "$ac_err"; then
|
if test -z "$ac_err"; then
|
||||||
rm -rf conftest*
|
rm -rf conftest*
|
||||||
@ -5742,9 +5746,9 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
|
|||||||
save_LIBS="$LIBS"
|
save_LIBS="$LIBS"
|
||||||
LIBS="$PTHREAD_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 $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
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5748 "configure"
|
#line 5752 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
/* Override any gcc2 internal prototype to avoid an error. */
|
/* Override any gcc2 internal prototype to avoid an error. */
|
||||||
/* We use char because int might match the return type of a gcc2
|
/* We use char because int might match the return type of a gcc2
|
||||||
@ -5755,7 +5759,7 @@ int main() {
|
|||||||
pthread_join()
|
pthread_join()
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
acx_pthread_ok=yes
|
acx_pthread_ok=yes
|
||||||
else
|
else
|
||||||
@ -5817,18 +5821,18 @@ for flag in $acx_pthread_flags; do
|
|||||||
case $flag in
|
case $flag in
|
||||||
none)
|
none)
|
||||||
echo $ac_n "checking whether pthreads work without any flags""... $ac_c" 1>&6
|
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 $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"
|
PTHREAD_CFLAGS="$flag"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo $ac_n "checking for the pthreads library -l$flag""... $ac_c" 1>&6
|
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"
|
PTHREAD_LIBS="-l$flag"
|
||||||
;;
|
;;
|
||||||
esac
|
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.
|
# functions on Solaris that doesn't have a non-functional libc stub.
|
||||||
# We try pthread_create on general principles.
|
# We try pthread_create on general principles.
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5852 "configure"
|
#line 5856 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
int main() {
|
int main() {
|
||||||
@ -5857,7 +5861,7 @@ pthread_t th; pthread_join(th, 0);
|
|||||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0);
|
pthread_create(0,0,0,0); pthread_cleanup_pop(0);
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
acx_pthread_ok=yes
|
acx_pthread_ok=yes
|
||||||
else
|
else
|
||||||
@ -5889,16 +5893,16 @@ if test "x$acx_pthread_ok" = xyes; then
|
|||||||
# Detect AIX lossage: threads are created detached by default
|
# Detect AIX lossage: threads are created detached by default
|
||||||
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
|
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
|
||||||
echo $ac_n "checking for joinable pthread attribute""... $ac_c" 1>&6
|
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
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5895 "configure"
|
#line 5899 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
int main() {
|
int main() {
|
||||||
int attr=PTHREAD_CREATE_JOINABLE;
|
int attr=PTHREAD_CREATE_JOINABLE;
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
ok=PTHREAD_CREATE_JOINABLE
|
ok=PTHREAD_CREATE_JOINABLE
|
||||||
else
|
else
|
||||||
@ -5910,14 +5914,14 @@ fi
|
|||||||
rm -f conftest*
|
rm -f conftest*
|
||||||
if test x"$ok" = xunknown; then
|
if test x"$ok" = xunknown; then
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 5914 "configure"
|
#line 5918 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
int main() {
|
int main() {
|
||||||
int attr=PTHREAD_CREATE_UNDETACHED;
|
int attr=PTHREAD_CREATE_UNDETACHED;
|
||||||
; return 0; }
|
; return 0; }
|
||||||
EOF
|
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*
|
rm -rf conftest*
|
||||||
ok=PTHREAD_CREATE_UNDETACHED
|
ok=PTHREAD_CREATE_UNDETACHED
|
||||||
else
|
else
|
||||||
@ -5940,7 +5944,7 @@ EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo $ac_n "checking if more special flags are required for pthreads""... $ac_c" 1>&6
|
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
|
flag=no
|
||||||
case "${host_cpu}-${host_os}" in
|
case "${host_cpu}-${host_os}" in
|
||||||
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
|
*-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.
|
# Extract the first word of "cc_r", so it can be a program name with args.
|
||||||
set dummy cc_r; ac_word=$2
|
set dummy cc_r; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_prog_PTHREAD_CC'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
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.
|
# Extract the first word of "gzip", so it can be a program name with args.
|
||||||
set dummy gzip; ac_word=$2
|
set dummy gzip; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
@ -6107,7 +6111,7 @@ fi
|
|||||||
# Extract the first word of "tar", so it can be a program name with args.
|
# Extract the first word of "tar", so it can be a program name with args.
|
||||||
set dummy tar; ac_word=$2
|
set dummy tar; ac_word=$2
|
||||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
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
|
if eval "test \"`echo '$''{'ac_cv_path_TAR'+set}'`\" = set"; then
|
||||||
echo $ac_n "(cached) $ac_c" 1>&6
|
echo $ac_n "(cached) $ac_c" 1>&6
|
||||||
else
|
else
|
||||||
@ -6304,6 +6308,7 @@ s%@SLOWDOWN_OBJS@%$SLOWDOWN_OBJS%g
|
|||||||
s%@BX_USE_IDLE_HACK@%$BX_USE_IDLE_HACK%g
|
s%@BX_USE_IDLE_HACK@%$BX_USE_IDLE_HACK%g
|
||||||
s%@CPUDIR@%$CPUDIR%g
|
s%@CPUDIR@%$CPUDIR%g
|
||||||
s%@LIBCPU32_A@%$LIBCPU32_A%g
|
s%@LIBCPU32_A@%$LIBCPU32_A%g
|
||||||
|
s%@OBJS64_CPU@%$OBJS64_CPU%g
|
||||||
s%@DYNAMIC_VAR@%$DYNAMIC_VAR%g
|
s%@DYNAMIC_VAR@%$DYNAMIC_VAR%g
|
||||||
s%@AS_DYNAMIC_OBJS@%$AS_DYNAMIC_OBJS%g
|
s%@AS_DYNAMIC_OBJS@%$AS_DYNAMIC_OBJS%g
|
||||||
s%@AS_DYNAMIC_INCS@%$AS_DYNAMIC_INCS%g
|
s%@AS_DYNAMIC_INCS@%$AS_DYNAMIC_INCS%g
|
||||||
|
@ -2,7 +2,7 @@ dnl // Process this file with autoconf to produce a configure script.
|
|||||||
|
|
||||||
AC_PREREQ(2.4)
|
AC_PREREQ(2.4)
|
||||||
AC_INIT(bochs.h)
|
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)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
dnl // Put Bochs version information right here so that it gets substituted
|
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)
|
AC_MSG_RESULT(yes)
|
||||||
CPUDIR=cpu64
|
CPUDIR=cpu64
|
||||||
LIBCPU32_A=""
|
LIBCPU32_A=""
|
||||||
|
OBJS64_CPU='$(OBJS64_CPU)'
|
||||||
AC_DEFINE(BX_SUPPORT_X86_64, 1)
|
AC_DEFINE(BX_SUPPORT_X86_64, 1)
|
||||||
use_x86_64=1
|
use_x86_64=1
|
||||||
else
|
else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
CPUDIR=cpu
|
CPUDIR=cpu
|
||||||
LIBCPU32_A=libcpu.a
|
LIBCPU32_A=libcpu.a
|
||||||
|
OBJS64_CPU=''
|
||||||
AC_DEFINE(BX_SUPPORT_X86_64, 0)
|
AC_DEFINE(BX_SUPPORT_X86_64, 0)
|
||||||
fi
|
fi
|
||||||
],
|
],
|
||||||
@ -321,11 +323,13 @@ AC_ARG_ENABLE(x86-64,
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
CPUDIR=cpu
|
CPUDIR=cpu
|
||||||
LIBCPU32_A=libcpu.a
|
LIBCPU32_A=libcpu.a
|
||||||
|
OBJS64_CPU=''
|
||||||
AC_DEFINE(BX_SUPPORT_X86_64, 0)
|
AC_DEFINE(BX_SUPPORT_X86_64, 0)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
AC_SUBST(CPUDIR)
|
AC_SUBST(CPUDIR)
|
||||||
AC_SUBST(LIBCPU32_A)
|
AC_SUBST(LIBCPU32_A)
|
||||||
|
AC_SUBST(OBJS64_CPU)
|
||||||
|
|
||||||
AC_MSG_CHECKING(for cpu level)
|
AC_MSG_CHECKING(for cpu level)
|
||||||
AC_ARG_ENABLE(cpu-level,
|
AC_ARG_ENABLE(cpu-level,
|
||||||
|
@ -103,6 +103,20 @@ OBJSXX = \
|
|||||||
bcd.o \
|
bcd.o \
|
||||||
mult16.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
|
BX_INCLUDES = ../bochs.h ../config.h
|
||||||
|
|
||||||
@ -118,15 +132,17 @@ libcpu.a: $(OBJS32)
|
|||||||
@MAKELIB@ $(OBJS32)
|
@MAKELIB@ $(OBJS32)
|
||||||
$(RANLIB) libcpu.a
|
$(RANLIB) libcpu.a
|
||||||
|
|
||||||
libcpuXX.a: $(OBJSXX)
|
libcpuXX.a: $(OBJSXX) @OBJS64_CPU@
|
||||||
@RMCOMMAND@ libcpuXX.a
|
@RMCOMMAND@ libcpuXX.a
|
||||||
@MAKELIB@ $(OBJSXX)
|
@MAKELIB@ $(OBJSXX) @OBJS64_CPU@
|
||||||
$(RANLIB) libcpuXX.a
|
$(RANLIB) libcpuXX.a
|
||||||
|
|
||||||
$(OBJS32): $(BX_INCLUDES)
|
$(OBJS32): $(BX_INCLUDES)
|
||||||
|
|
||||||
$(OBJSXX): $(BX_INCLUDES)
|
$(OBJSXX): $(BX_INCLUDES)
|
||||||
|
|
||||||
|
$(OBJS64_CPU): $(BX_INCLUDES)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@RMCOMMAND@ *.o
|
@RMCOMMAND@ *.o
|
||||||
@RMCOMMAND@ *.a
|
@RMCOMMAND@ *.a
|
||||||
|
870
bochs/cpu/arith64.cc
Normal file
870
bochs/cpu/arith64.cc
Normal 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
461
bochs/cpu/ctrl_xfer64.cc
Normal 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
472
bochs/cpu/data_xfer64.cc
Normal 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
2691
bochs/cpu/fetchdecode64.cc
Normal file
File diff suppressed because it is too large
Load Diff
439
bochs/cpu/logical64.cc
Normal file
439
bochs/cpu/logical64.cc
Normal 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
491
bochs/cpu/mult64.cc
Normal 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("ient_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("ient_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
457
bochs/cpu/resolve64.cc
Normal 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
465
bochs/cpu/shift64.cc
Normal 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
338
bochs/cpu/stack64.cc
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user