First stage of dynamic recompiler rewrite.

Basic IR generation calls C implementation of all instructions.
Backend generation implemented for x86, x86-64, ARM and ARM64.
This commit is contained in:
SarahW 2018-06-17 20:26:15 +01:00
commit 03fe25d818
46 changed files with 4134 additions and 17767 deletions

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -133,7 +133,7 @@ am__recursive_targets = \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir dist dist-all distcheck
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
@ -308,7 +308,6 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -342,8 +341,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -461,7 +460,10 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@ -526,7 +528,7 @@ distdir: $(DISTFILES)
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
@ -552,7 +554,7 @@ dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
@ -570,7 +572,7 @@ dist dist-all:
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
@ -580,7 +582,7 @@ distcheck: dist
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac

380
configure vendored
View file

@ -590,6 +590,8 @@ LTLIBOBJS
LIBOBJS
OS_MACOSX_FALSE
OS_MACOSX_TRUE
OS_OTHER_FALSE
OS_OTHER_TRUE
OS_WINDOWS_FALSE
OS_WINDOWS_TRUE
OS_LINUX_FALSE
@ -622,6 +624,10 @@ USE_NETWORKING_FALSE
USE_NETWORKING_TRUE
USE_WX_FALSE
USE_WX_TRUE
CPU_ARM64_FALSE
CPU_ARM64_TRUE
CPU_ARM_FALSE
CPU_ARM_TRUE
CPU_X86_64_FALSE
CPU_X86_64_TRUE
CPU_I386_FALSE
@ -641,7 +647,6 @@ am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
am__quote
am__include
DEPDIR
OBJEXT
@ -705,7 +710,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -724,7 +728,8 @@ PACKAGE_VERSION
PACKAGE_TARNAME
PACKAGE_NAME
PATH_SEPARATOR
SHELL'
SHELL
am__quote'
ac_subst_files=''
ac_user_opts='
enable_option_checking
@ -798,7 +803,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1051,15 +1055,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1197,7 +1192,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1350,7 +1345,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -2130,7 +2124,7 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
am__api_version='1.15'
am__api_version='1.16'
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@ -2646,8 +2640,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# For better backward compatibility. To be removed once Automake 1.9.x
# dies out for good. For more background, see:
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
mkdir_p='$(MKDIR_P)'
# We need awk for the "check" target (and possibly the TAP driver). The
@ -2698,7 +2692,7 @@ END
Aborting the configuration process, to ensure you take notice of the issue.
You can download and install GNU coreutils to get an 'rm' implementation
that behaves properly: <http://www.gnu.org/software/coreutils/>.
that behaves properly: <https://www.gnu.org/software/coreutils/>.
If you want to complete the configuration process using your problematic
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@ -3560,45 +3554,45 @@ DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
am_make=${MAKE-make}
cat > confinc << 'END'
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
cat > confinc.mk << 'END'
am__doit:
@echo this is the am__doit target
@echo this is the am__doit target >confinc.out
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
$as_echo_n "checking for style of include used by $am_make... " >&6; }
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from 'make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
# BSD make does it like this.
echo '.include "confinc.mk" # ignored' > confmf.BSD
# Other make implementations (GNU, Solaris 10, AIX) do it like this.
echo 'include confinc.mk # ignored' > confmf.GNU
_am_result=no
for s in GNU BSD; do
{ echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
(${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
case $?:`cat confinc.out 2>/dev/null` in #(
'0:this is the am__doit target') :
case $s in #(
BSD) :
am__include='.include' am__quote='"' ;; #(
*) :
am__include='include' am__quote='' ;;
esac ;; #(
*) :
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
$as_echo "$_am_result" >&6; }
rm -f confinc confmf
esac
if test "$am__include" != "#"; then
_am_result="yes ($s style)"
break
fi
done
rm -f confinc.* confmf.*
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
$as_echo "${_am_result}" >&6; }
# Check whether --enable-dependency-tracking was given.
if test "${enable_dependency_tracking+set}" = set; then :
@ -4220,10 +4214,20 @@ $as_echo "${host_cpu}" >&6; }
x86_64)
CPU=x86_64
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5
$as_echo "${host_cpu}" >&6; }
;;
armv7l)
CPU=arm
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5
$as_echo "${host_cpu}" >&6; }
;;
aarch64)
CPU=arm64
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${host_cpu}" >&5
$as_echo "${host_cpu}" >&6; }
;;
*)
as_fn_error $? "Unsupported CPU." "$LINENO" 5
as_fn_error $? "Unsupported CPU. ${host_cpu}" "$LINENO" 5
;;
esac
@ -4243,9 +4247,25 @@ else
CPU_X86_64_FALSE=
fi
if test "$CPU" = "arm"; then
CPU_ARM_TRUE=
CPU_ARM_FALSE='#'
else
CPU_ARM_TRUE='#'
CPU_ARM_FALSE=
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
$as_echo_n "checking for off64_t... " >&6; }
if test "$CPU" = "arm64"; then
CPU_ARM64_TRUE=
CPU_ARM64_FALSE='#'
else
CPU_ARM64_TRUE='#'
CPU_ARM64_FALSE=
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t $CPU" >&5
$as_echo_n "checking for off64_t $CPU... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@ -4265,6 +4285,11 @@ else
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
case "$host" in
*-*-freebsd*) # has off64_t but no fopen64/etc.
has_lfs="no"
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_lfs" >&5
$as_echo "$has_lfs" >&6; }
@ -4464,8 +4489,8 @@ fi
if test "x$sdl_prefix$sdl_exec_prefix" = x ; then
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5
$as_echo_n "checking for SDL... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5
$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; }
if test -n "$SDL_CFLAGS"; then
pkg_cv_SDL_CFLAGS="$SDL_CFLAGS"
@ -4505,7 +4530,7 @@ fi
if test $pkg_failed = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
@ -4523,7 +4548,7 @@ fi
sdl_pc=no
elif test $pkg_failed = untried; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
sdl_pc=no
else
@ -5213,6 +5238,7 @@ fi
build_macosx="no"
build_linux="no"
build_win="no"
build_other="no"
case "$host" in
*-*-darwin*)
@ -5317,7 +5343,7 @@ fi
SET_MAKE='MAKE=mingw32-make'
;;
*)
*-*-linux*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5
$as_echo_n "checking for glGetError in -lGL... " >&6; }
if ${ac_cv_lib_GL_glGetError+:} false; then :
@ -5418,6 +5444,107 @@ fi
build_linux="yes"
;;
*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glGetError in -lGL" >&5
$as_echo_n "checking for glGetError in -lGL... " >&6; }
if ${ac_cv_lib_GL_glGetError+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lGL $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char glGetError ();
int
main ()
{
return glGetError ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_GL_glGetError=yes
else
ac_cv_lib_GL_glGetError=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GL_glGetError" >&5
$as_echo "$ac_cv_lib_GL_glGetError" >&6; }
if test "x$ac_cv_lib_GL_glGetError" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBGL 1
_ACEOF
LIBS="-lGL $LIBS"
else
\
echo "You need to install the OpenGL library."
exit -1
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alGetError in -lopenal" >&5
$as_echo_n "checking for alGetError in -lopenal... " >&6; }
if ${ac_cv_lib_openal_alGetError+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lopenal $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char alGetError ();
int
main ()
{
return alGetError ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_openal_alGetError=yes
else
ac_cv_lib_openal_alGetError=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openal_alGetError" >&5
$as_echo "$ac_cv_lib_openal_alGetError" >&6; }
if test "x$ac_cv_lib_openal_alGetError" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBOPENAL 1
_ACEOF
LIBS="-lopenal $LIBS"
else
\
echo "You need to install the OpenAL library."
exit -1
fi
build_other="yes"
;;
esac
LIBS="$LIBS $WX_LIBS $SDL_LIBS"
@ -5438,6 +5565,14 @@ else
OS_WINDOWS_FALSE=
fi
if test "$build_other" = "yes"; then
OS_OTHER_TRUE=
OS_OTHER_FALSE='#'
else
OS_OTHER_TRUE='#'
OS_OTHER_FALSE=
fi
if test "$build_macosx" = "yes"; then
OS_MACOSX_TRUE=
OS_MACOSX_FALSE='#'
@ -5634,6 +5769,14 @@ if test -z "${CPU_X86_64_TRUE}" && test -z "${CPU_X86_64_FALSE}"; then
as_fn_error $? "conditional \"CPU_X86_64\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${CPU_ARM_TRUE}" && test -z "${CPU_ARM_FALSE}"; then
as_fn_error $? "conditional \"CPU_ARM\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${CPU_ARM64_TRUE}" && test -z "${CPU_ARM64_FALSE}"; then
as_fn_error $? "conditional \"CPU_ARM64\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${USE_WX_TRUE}" && test -z "${USE_WX_FALSE}"; then
as_fn_error $? "conditional \"USE_WX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@ -5658,6 +5801,10 @@ if test -z "${OS_WINDOWS_TRUE}" && test -z "${OS_WINDOWS_FALSE}"; then
as_fn_error $? "conditional \"OS_WINDOWS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${OS_OTHER_TRUE}" && test -z "${OS_OTHER_FALSE}"; then
as_fn_error $? "conditional \"OS_OTHER\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${OS_MACOSX_TRUE}" && test -z "${OS_MACOSX_FALSE}"; then
as_fn_error $? "conditional \"OS_MACOSX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@ -6224,7 +6371,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
# INIT-COMMANDS
#
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
_ACEOF
@ -6670,29 +6817,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
# Older Autoconf quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
*\'*) eval set x "$CONFIG_FILES" ;;
*) set x $CONFIG_FILES ;;
esac
# TODO: see whether this extra hack can be removed once we start
# requiring Autoconf 2.70 or later.
case $CONFIG_FILES in #(
*\'*) :
eval set x "$CONFIG_FILES" ;; #(
*) :
set x $CONFIG_FILES ;; #(
*) :
;;
esac
shift
for mf
# Used to flag and report bootstrapping failures.
am_rc=0
for am_mf
do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named 'Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile which includes
# dependency-tracking related rules and includes.
# Grep'ing the whole file directly is not great: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`$as_dirname -- "$mf" ||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$mf" : 'X\(//\)[^/]' \| \
X"$mf" : 'X\(//\)$' \| \
X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$mf" |
sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
|| continue
am_dirpart=`$as_dirname -- "$am_mf" ||
$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$am_mf" : 'X\(//\)[^/]' \| \
X"$am_mf" : 'X\(//\)$' \| \
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$am_mf" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
@ -6710,53 +6863,48 @@ $as_echo X"$mf" |
q
}
s/.*/./; q'`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running 'make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "$am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`$as_dirname -- "$file" ||
$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$file" : 'X\(//\)[^/]' \| \
X"$file" : 'X\(//\)$' \| \
X"$file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
am_filepart=`$as_basename -- "$am_mf" ||
$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
X"$am_mf" : 'X\(//\)$' \| \
X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$am_mf" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
as_dir=$dirpart/$fdir; as_fn_mkdir_p
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
{ echo "$as_me:$LINENO: cd "$am_dirpart" \
&& sed -e '/# am--include-marker/d' "$am_filepart" \
| $MAKE -f - am--depfiles" >&5
(cd "$am_dirpart" \
&& sed -e '/# am--include-marker/d' "$am_filepart" \
| $MAKE -f - am--depfiles) >&5 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } || am_rc=$?
done
if test $am_rc -ne 0; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).
See \`config.log' for more details" "$LINENO" 5; }
fi
{ am_dirpart=; unset am_dirpart;}
{ am_filepart=; unset am_filepart;}
{ am_mf=; unset am_mf;}
{ am_rc=; unset am_rc;}
rm -f conftest-deps.mk
}
;;

View file

@ -64,15 +64,25 @@ case "${host_cpu}" in
CPU=x86_64
AC_MSG_RESULT(${host_cpu})
;;
armv7l)
CPU=arm
AC_MSG_RESULT(${host_cpu})
;;
aarch64)
CPU=arm64
AC_MSG_RESULT(${host_cpu})
;;
*)
AC_MSG_ERROR([Unsupported CPU.])
AC_MSG_ERROR([Unsupported CPU. ${host_cpu}])
;;
esac
AM_CONDITIONAL(CPU_I386, test "$CPU" = "i386")
AM_CONDITIONAL(CPU_X86_64, test "$CPU" = "x86_64")
AM_CONDITIONAL(CPU_ARM, test "$CPU" = "arm")
AM_CONDITIONAL(CPU_ARM64, test "$CPU" = "arm64")
AC_MSG_CHECKING([for off64_t])
AC_MSG_CHECKING([for off64_t $CPU])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],[[off64_t n=0;]])],[has_lfs="yes"],[has_lfs="no"])
case "$host" in
*-*-freebsd*) # has off64_t but no fopen64/etc.

View file

@ -8,6 +8,7 @@
#include "x87.h"
#include "mem.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "cpu.h"
#include "fdc.h"
#include "nmi.h"

View file

@ -23,6 +23,64 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (cpu_rm == 4)
{
uint8_t sib = rmdat >> 8;
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
cpu_state.pc++;
break;
case 1:
cpu_state.pc++;
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
// cpu_state.pc++;
break;
case 2:
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
cpu_state.pc += 5;
break;
}
/*SIB byte present*/
if ((sib & 7) == 5 && !cpu_mod)
cpu_state.eaaddr = getlong();
else if ((sib & 6) == 4 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (((sib >> 3) & 7) != 4)
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
}
else
{
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
if (cpu_mod)
{
if (cpu_rm == 5 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (cpu_mod == 1)
{
cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
cpu_state.pc++;
}
else
{
cpu_state.eaaddr += getlong();
}
}
else if (cpu_rm == 5)
{
cpu_state.eaaddr = getlong();
}
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
@ -38,6 +96,33 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (!cpu_mod && cpu_rm == 6)
{
cpu_state.eaaddr = getword();
}
else
{
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = 0;
break;
case 1:
cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
break;
case 2:
cpu_state.eaaddr = getword();
break;
}
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
cpu_state.eaaddr &= 0xFFFF;
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
@ -48,8 +133,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
}
}
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat);
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; }
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32)
@ -57,7 +142,8 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
#define PREFETCH_FLUSH()
#define OP_TABLE(name) dynarec_ops_ ## name
#define CLOCK_CYCLES(c)
/*Temporary*/
#define CLOCK_CYCLES(c) cycles -= (c)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#include "386_ops.h"

View file

@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc
# PCem
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \
cmd640.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
cmd640.c codegen.c codegen_backend.c codegen_ir.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \
hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \
joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \
@ -70,12 +70,20 @@ pcem_SOURCES += wx-sdl2-midi.c
endif
if CPU_I386
pcem_SOURCES += codegen_x86.c
pcem_SOURCES += codegen_backend_x86.c codegen_backend_x86_uops.c
pcem_CFLAGS += -msse2
endif
if CPU_X86_64
pcem_SOURCES += codegen_x86-64.c
pcem_SOURCES += codegen_backend_x86-64.c codegen_backend_x86-64_uops.c
endif
if CPU_ARM
pcem_SOURCES += codegen_backend_arm.c codegen_backend_arm_uops.c
endif
if CPU_ARM64
pcem_SOURCES += codegen_backend_arm64.c codegen_backend_arm64_uops.c
endif
if USE_NETWORKING

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,13 @@
#include "x86_ops.h"
#include "mem.h"
#include "codegen.h"
#include "x86.h"
#include "codegen_backend.h"
#include "codegen_ir.h"
codeblock_t *codeblock;
codeblock_t **codeblock_hash;
void (*codegen_timing_start)();
void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
@ -19,3 +26,39 @@ void codegen_timing_set(codegen_timing_t *timing)
}
int codegen_in_recompile;
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc)
{
codeblock_t *block = &codeblock[block_current];
ir_data_t *ir = codegen_get_ir_data();
uint32_t op_pc = new_pc;
OpFn *op_table = x86_dynarec_opcodes;
int opcode_shift = 0;
int opcode_mask = 0x3ff;
uint32_t op_32 = use32;
//pclog("%04x:%08x : %02x\n", CS, new_pc, opcode);
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
uop_STORE_PTR_IMM(ir, &cpu_state.pc, op_pc);
uop_STORE_PTR_IMM(ir, &cpu_state.oldpc, old_pc);
uop_STORE_PTR_IMM(ir, &cpu_state.op32, op_32);
uop_STORE_PTR_IMM(ir, &cpu_state.ea_seg, (uintptr_t)&_ds);
uop_STORE_PTR_IMM_8(ir, &cpu_state.ssegs, 0);
uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat);
uop_CALL_INSTRUCTION_FUNC(ir, op);
//codegen_block_ins++;
block->ins++;
if (block->ins >= 50)
CPU_BLOCK_END();
// addbyte(0xE8); /*CALL*/
// addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4])));
codegen_endpc = (cs + cpu_state.pc) + 8;
}

View file

@ -4,14 +4,6 @@
#include "mem.h"
#include "x86_ops.h"
#ifdef __amd64__
#include "codegen_x86-64.h"
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include "codegen_x86.h"
#else
#error Dynamic recompiler not implemented on your platform
#endif
/*Handling self-modifying code (of which there is a lot on x86) :
PCem tracks a 'dirty mask' for each physical page, in which each bit
@ -37,6 +29,9 @@
same page).
*/
/*Hack until better memory management written*/
#define BLOCK_DATA_SIZE 0x10000
typedef struct codeblock_t
{
uint64_t page_mask, page_mask2;
@ -66,7 +61,7 @@ typedef struct codeblock_t
uint32_t status;
uint32_t flags;
uint8_t data[2048];
uint8_t data[BLOCK_DATA_SIZE];
} codeblock_t;
/*Code block uses FPU*/
@ -311,45 +306,6 @@ extern int block_pos;
#define CPU_BLOCK_END() cpu_block_end = 1
static inline void addbyte(uint8_t val)
{
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addword(uint16_t val)
{
*(uint16_t *)(void *)&codeblock[block_current].data[block_pos] = val;
block_pos += 2;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addlong(uint32_t val)
{
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addquad(uint64_t val)
{
*(uint64_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 8;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
extern uint32_t recomp_page;

416
src/codegen_backend.c Normal file
View file

@ -0,0 +1,416 @@
#include <stdlib.h>
#include "ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_ir.h"
int codegen_flat_ds, codegen_flat_ss;
int mmx_ebx_ecx_loaded;
int codegen_flags_changed = 0;
int codegen_fpu_entered = 0;
int codegen_mmx_entered = 0;
int codegen_fpu_loaded_iq[8];
x86seg *op_ea_seg;
int op_ssegs;
uint32_t op_old_pc;
uint32_t recomp_page = -1;
int block_current = 0;
static int block_num;
int block_pos;
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
int cpu_recomp_reuse, cpu_recomp_reuse_latched;
int cpu_recomp_removed, cpu_recomp_removed_latched;
uint32_t codegen_endpc;
int codegen_block_cycles;
static int codegen_block_ins;
static int codegen_block_full_ins;
static uint32_t last_op32;
static x86seg *last_ea_seg;
static int last_ssegs;
void codegen_init()
{
codegen_backend_init();
}
void codegen_reset()
{
int c;
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
mem_reset_page_blocks();
for (c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
}
void dump_block()
{
/* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");*/
}
static void add_to_block_list(codeblock_t *block)
{
codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3];
if (!block->page_mask)
fatal("add_to_block_list - mask = 0\n");
if (block_prev)
{
block->next = block_prev;
block_prev->prev = block;
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
}
else
{
block->next = NULL;
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
}
if (block->next)
{
if (block->next->pc == BLOCK_PC_INVALID)
fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos);
}
if (block->page_mask2)
{
block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3];
if (block_prev)
{
block->next_2 = block_prev;
block_prev->prev_2 = block;
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
}
else
{
block->next_2 = NULL;
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
}
}
}
static void remove_from_block_list(codeblock_t *block, uint32_t pc)
{
if (!block->page_mask)
return;
if (block->prev)
{
block->prev->next = block->next;
if (block->next)
block->next->prev = block->prev;
}
else
{
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next;
if (block->next)
block->next->prev = NULL;
else
mem_flush_write_page(block->phys, 0);
}
if (!block->page_mask2)
{
if (block->prev_2 || block->next_2)
fatal("Invalid block_2\n");
return;
}
if (block->prev_2)
{
block->prev_2->next_2 = block->next_2;
if (block->next_2)
block->next_2->prev_2 = block->prev_2;
}
else
{
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2)
block->next_2->prev_2 = NULL;
else
mem_flush_write_page(block->phys_2, 0);
}
}
static void delete_block(codeblock_t *block)
{
uint32_t old_pc = block->pc;
if (block == codeblock_hash[HASH(block->phys)])
codeblock_hash[HASH(block->phys)] = NULL;
if (block->pc == BLOCK_PC_INVALID)
fatal("Deleting deleted block\n");
block->pc = BLOCK_PC_INVALID;
codeblock_tree_delete(block);
remove_from_block_list(block, old_pc);
}
void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{
struct codeblock_t *block = page->block[(phys_addr >> 10) & 3];
while (block)
{
if (mask & block->page_mask)
{
delete_block(block);
cpu_recomp_evicted++;
}
if (block == block->next)
fatal("Broken 1\n");
block = block->next;
}
block = page->block_2[(phys_addr >> 10) & 3];
while (block)
{
if (mask & block->page_mask2)
{
delete_block(block);
cpu_recomp_evicted++;
}
if (block == block->next_2)
fatal("Broken 2\n");
block = block->next_2;
}
}
void codegen_block_init(uint32_t phys_addr)
{
codeblock_t *block;
page_t *page = &pages[phys_addr >> 12];
if (!page->block[(phys_addr >> 10) & 3])
mem_flush_write_page(phys_addr, cs+cpu_state.pc);
block_current = (block_current + 1) & BLOCK_MASK;
block = &codeblock[block_current];
// if (block->pc == 0xb00b4ff5)
// pclog("Init target block\n");
if (block->pc != BLOCK_PC_INVALID)
{
// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc);
delete_block(block);
cpu_recomp_reuse++;
}
block_num = HASH(phys_addr);
codeblock_hash[block_num] = &codeblock[block_current];
block->ins = 0;
block->pc = cs + cpu_state.pc;
block->_cs = cs;
block->pnt = block_current;
block->phys = phys_addr;
block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
block->dirty_mask2 = NULL;
block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL;
block->page_mask = 0;
block->flags = CODEBLOCK_STATIC_TOP;
block->status = cpu_cur_status;
block->was_recompiled = 0;
recomp_page = block->phys & ~0xfff;
codeblock_tree_add(block);
}
static ir_data_t *ir_data;
ir_data_t *codegen_get_ir_data()
{
return ir_data;
}
void codegen_block_start_recompile(codeblock_t *block)
{
page_t *page = &pages[block->phys >> 12];
if (!page->block[(block->phys >> 10) & 3])
mem_flush_write_page(block->phys, cs+cpu_state.pc);
block_num = HASH(block->phys);
block_current = block->pnt;
if (block->pc != cs + cpu_state.pc || block->was_recompiled)
fatal("Recompile to used block!\n");
block->status = cpu_cur_status;
cpu_block_end = 0;
// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num);
last_op32 = -1;
last_ea_seg = NULL;
last_ssegs = -1;
codegen_block_cycles = 0;
codegen_timing_block_start();
codegen_block_ins = 0;
codegen_block_full_ins = 0;
recomp_page = block->phys & ~0xfff;
codegen_flags_changed = 0;
codegen_fpu_entered = 0;
codegen_mmx_entered = 0;
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
block->TOP = cpu_state.TOP;
block->was_recompiled = 1;
codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS);
codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS);
ir_data = codegen_ir_init();
}
void codegen_block_remove()
{
codeblock_t *block = &codeblock[block_current];
delete_block(block);
cpu_recomp_removed++;
recomp_page = -1;
}
void codegen_block_generate_end_mask()
{
codeblock_t *block = &codeblock[block_current];
uint32_t start_pc;
uint32_t end_pc;
block->endpc = codegen_endpc;
block->page_mask = 0;
start_pc = (block->pc & 0x3ff) & ~15;
if ((block->pc ^ block->endpc) & ~0x3ff)
end_pc = 0x3ff & ~15;
else
end_pc = (block->endpc & 0x3ff) & ~15;
if (end_pc < start_pc)
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT;
// pclog("block_end: %08x %08x\n", start_pc, end_pc);
for (; start_pc <= end_pc; start_pc++)
{
block->page_mask |= ((uint64_t)1 << start_pc);
// pclog(" %08x %llx\n", start_pc, block->page_mask);
}
pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1;
block->page_mask2 = 0;
block->next_2 = block->prev_2 = NULL;
if ((block->pc ^ block->endpc) & ~0x3ff)
{
block->phys_2 = get_phys_noabrt(block->endpc);
if (block->phys_2 != -1)
{
page_t *page_2 = &pages[block->phys_2 >> 12];
start_pc = 0;
end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT;
for (; start_pc <= end_pc; start_pc++)
block->page_mask2 |= ((uint64_t)1 << start_pc);
page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2;
if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3])
mem_flush_write_page(block->phys_2, block->endpc);
if (!block->page_mask2)
fatal("!page_mask2\n");
if (block->next_2)
{
// pclog(" next_2->pc=%08x\n", block->next_2->pc);
if (block->next_2->pc == BLOCK_PC_INVALID)
fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)block->next_2);
}
block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
}
}
// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask);
recomp_page = -1;
}
void codegen_block_end()
{
codeblock_t *block = &codeblock[block_current];
codegen_block_generate_end_mask();
add_to_block_list(block);
}
void codegen_block_end_recompile(codeblock_t *block)
{
codegen_timing_block_end();
remove_from_block_list(block, block->pc);
block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL;
codegen_block_generate_end_mask();
add_to_block_list(block);
// pclog("End block %i\n", block_num);
if (!(block->flags & CODEBLOCK_HAS_FPU))
block->flags &= ~CODEBLOCK_STATIC_TOP;
codegen_ir_compile(ir_data, block);
}
void codegen_flush()
{
return;
}

65
src/codegen_backend.h Normal file
View file

@ -0,0 +1,65 @@
//#ifdef __amd64__
//#include "codegen_x86-64.h"
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include "codegen_backend_x86.h"
#elif defined __amd64__
#include "codegen_backend_x86-64.h"
#elif defined __ARM_EABI__
#include "codegen_backend_arm.h"
#elif defined __aarch64__
#include "codegen_backend_arm64.h"
#else
#error Dynamic recompiler not implemented on your platform
#endif
void codegen_backend_init();
void codegen_backend_prologue(codeblock_t *block);
void codegen_backend_epilogue(codeblock_t *block);
static inline void addbyte(uint8_t val)
{
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addword(uint16_t val)
{
*(uint16_t *)(void *)&codeblock[block_current].data[block_pos] = val;
block_pos += 2;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addlong(uint32_t val)
{
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
static inline void addquad(uint64_t val)
{
*(uint64_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 8;
if (block_pos >= BLOCK_MAX)
{
CPU_BLOCK_END();
}
}
struct ir_data_t;
struct uop_t;
struct ir_data_t *codegen_get_ir_data();
typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop);
extern const uOpFn uop_handlers[];

101
src/codegen_backend_arm.c Normal file
View file

@ -0,0 +1,101 @@
#ifdef __ARM_EABI__
#include <stdlib.h>
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_arm_defs.h"
#include "x86.h"
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
#include <windows.h>
#endif
void codegen_backend_init()
{
int c;
#if defined(__linux__) || defined(__APPLE__)
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
long pagemask = ~(pagesize - 1);
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
#endif
if (!codeblock)
fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t));
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
#if defined(__linux__) || defined(__APPLE__)
start = (void *)((long)codeblock & pagemask);
len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
/*R11 - literal pool
R10 - cpu_state*/
void codegen_backend_prologue(codeblock_t *block)
{
int offset;
codegen_reset_literal_pool(block);
block_pos = 0;
block_pos = BLOCK_GPF_OFFSET;
host_arm_MOV_IMM(block, REG_R0, 0);
host_arm_MOV_IMM(block, REG_R1, 0);
host_arm_call(block, x86gpf);
while (block_pos != BLOCK_EXIT_OFFSET)
host_arm_nop(block);
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC);
while (block_pos != BLOCK_START)
host_arm_nop(block);
/*Entry code*/
host_arm_STMDB_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_LR);
host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET);
host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START);
offset = add_literal(block, (uintptr_t)&cpu_state);
host_arm_LDR_IMM(block, REG_CPUSTATE, REG_R11, offset);
}
void codegen_backend_epilogue(codeblock_t *block)
{
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC);
if (block_pos > ARM_LITERAL_POOL_OFFSET)
fatal("Over limit!\n");
__clear_cache(&block->data[0], &block->data[block_pos]);
}
#endif

33
src/codegen_backend_arm.h Normal file
View file

@ -0,0 +1,33 @@
#define BLOCK_SIZE 0x1000
#define BLOCK_MASK 0x0fff
#define BLOCK_START 32
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
/*Hack until better memory management written*/
/*#define BLOCK_EXIT_OFFSET 0x7f0*/
#define BLOCK_GPF_OFFSET 0
#define BLOCK_EXIT_OFFSET 16
#define ARM_LITERAL_POOL_OFFSET 0xf000
/*#define BLOCK_MAX 1720*/
#define BLOCK_MAX 65208
void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask);
void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset);
void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm);
void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask);
void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
void host_arm_call(codeblock_t *block, void *dst_addr);
void host_arm_nop(codeblock_t *block);
void codegen_reset_literal_pool(codeblock_t *block);
int add_literal(codeblock_t *block, uint32_t data);

115
src/codegen_backend_arm64.c Normal file
View file

@ -0,0 +1,115 @@
#ifdef __aarch64__
#include <stdlib.h>
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_arm64_defs.h"
#include "x86.h"
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
#include <windows.h>
#endif
void codegen_backend_init()
{
int c;
#if defined(__linux__) || defined(__APPLE__)
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
long pagemask = ~(pagesize - 1);
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
#endif
if (!codeblock)
fatal("codeblock failed to alloc - %i\n", (BLOCK_SIZE+1) * sizeof(codeblock_t));
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
#if defined(__linux__) || defined(__APPLE__)
start = (void *)((long)codeblock & pagemask);
len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
/*R11 - literal pool
R10 - cpu_state*/
void codegen_backend_prologue(codeblock_t *block)
{
int offset;
codegen_reset_literal_pool(block);
block_pos = 0;
block_pos = BLOCK_GPF_OFFSET;
host_arm64_mov_imm(block, REG_ARG0, 0);
host_arm64_mov_imm(block, REG_ARG1, 0);
host_arm64_call(block, x86gpf);
while (block_pos != BLOCK_EXIT_OFFSET)
host_arm64_NOP(block);
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
host_arm64_RET(block, REG_X30);
while (block_pos != BLOCK_START)
host_arm64_NOP(block);
/*Entry code*/
host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -16);
offset = add_literal_q(block, (uintptr_t)&cpu_state);
host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset);
}
void codegen_backend_epilogue(codeblock_t *block)
{
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
host_arm64_RET(block, REG_X30);
if (block_pos > ARM_LITERAL_POOL_OFFSET)
fatal("Over limit!\n");
__clear_cache(&block->data[0], &block->data[block_pos]);
}
#endif

View file

@ -0,0 +1,40 @@
#define BLOCK_SIZE 0x1000
#define BLOCK_MASK 0x0fff
#define BLOCK_START 64
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
/*Hack until better memory management written*/
/*#define BLOCK_EXIT_OFFSET 0x7f0*/
#define BLOCK_GPF_OFFSET 0
#define BLOCK_EXIT_OFFSET 32
#define ARM_LITERAL_POOL_OFFSET 0xf000
/*#define BLOCK_MAX 1720*/
#define BLOCK_MAX 65208
void host_arm64_BLR(codeblock_t *block, int addr_reg);
void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest);
void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data);
void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data);
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset);
void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset);
void host_arm64_NOP(codeblock_t *block);
void host_arm64_RET(codeblock_t *block, int reg);
void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
void host_arm64_STRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
void host_arm64_call(codeblock_t *block, void *dst_addr);
void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data);
void codegen_reset_literal_pool(codeblock_t *block);
int add_literal(codeblock_t *block, uint32_t data);
int add_literal_q(codeblock_t *block, uint64_t data);

View file

@ -0,0 +1,72 @@
#define REG_W0 0
#define REG_W1 1
#define REG_W2 2
#define REG_W3 3
#define REG_W4 4
#define REG_W5 5
#define REG_W6 6
#define REG_W7 7
#define REG_W8 8
#define REG_W9 9
#define REG_W10 10
#define REG_W11 11
#define REG_W12 12
#define REG_W13 13
#define REG_W14 14
#define REG_W15 15
#define REG_W16 16
#define REG_W17 17
#define REG_W18 18
#define REG_W19 19
#define REG_W20 20
#define REG_W21 21
#define REG_W22 22
#define REG_W23 23
#define REG_W24 24
#define REG_W25 25
#define REG_W26 26
#define REG_W27 27
#define REG_W28 28
#define REG_W29 29
#define REG_W30 30
#define REG_X0 0
#define REG_X1 1
#define REG_X2 2
#define REG_X3 3
#define REG_X4 4
#define REG_X5 5
#define REG_X6 6
#define REG_X7 7
#define REG_X8 8
#define REG_X9 9
#define REG_X10 10
#define REG_X11 11
#define REG_X12 12
#define REG_X13 13
#define REG_X14 14
#define REG_X15 15
#define REG_X16 16
#define REG_X17 17
#define REG_X18 18
#define REG_X19 19
#define REG_X20 20
#define REG_X21 21
#define REG_X22 22
#define REG_X23 23
#define REG_X24 24
#define REG_X25 25
#define REG_X26 26
#define REG_X27 27
#define REG_X28 28
#define REG_X29 29
#define REG_X30 30
#define REG_SP 31
#define REG_ARG0 REG_X0
#define REG_ARG1 REG_X1
#define REG_ARG2 REG_X2
#define REG_ARG3 REG_X3
#define REG_CPUSTATE REG_X29

View file

@ -0,0 +1,300 @@
#ifdef __aarch64__
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_arm64_defs.h"
#include "codegen_ir_defs.h"
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
*(uint32_t *)&block->data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addlong over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
#define Rt(x) (x)
#define Rd(x) (x)
#define Rn(x) ((x) << 5)
#define Rt2(x) ((x) << 10)
#define DATA_OFFSET_UP (1 << 23)
#define DATA_OFFSET_DOWN (0 << 23)
#define COND_SHIFT 28
#define COND_NE (0x1 << COND_SHIFT)
#define COND_AL (0xe << COND_SHIFT)
#define OPCODE_SHIFT 24
#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT)
#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT)
#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT)
#define OPCODE_MOVK_W (0x0e5 << 23)
#define OPCODE_MOVZ_W (0x0a5 << 23)
#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22)
#define OPCODE_STP_PREIDX_X (0x2a6 << 22)
#define OPCODE_STR_IMM_W (0x2e4 << 22)
#define OPCODE_STRB_IMM (0x0e4 << 22)
#define OPCODE_BLR (0xd63f0000)
#define OPCODE_NOP (0xd503201f)
#define OPCODE_RET (0xd65f0000)
#define MOV_WIDE_HW(hw) (hw << 21)
#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15)
#define IMM16(imm_data) (imm_data << 5)
#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0)
#define OFFSET12_B(offset) (offset << 10)
#define OFFSET12_W(offset) ((offset >> 2) << 10)
static int literal_offset = 0;
void codegen_reset_literal_pool(codeblock_t *block)
{
literal_offset = 0;
}
/*Returns true if offset fits into 19 bits*/
static int offset_is_19bit(int offset)
{
if (offset >= (1 << (18+2)))
return 0;
if (offset < -(1 << (18+2)))
return 0;
return 1;
}
#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7))
#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000))
#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3))
int add_literal(codeblock_t *block, uint32_t data)
{
if (literal_offset >= 4096)
fatal("add_literal - literal pool full\n");
*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data;
literal_offset += 4;
return literal_offset - 4;
}
int add_literal_q(codeblock_t *block, uint64_t data)
{
if (literal_offset & 4)
literal_offset += 4;
if (literal_offset >= 4096-4)
fatal("add_literal - literal pool full\n");
*(uint64_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data;
literal_offset += 8;
return literal_offset - 8;
}
static inline int imm_is_imm16(uint32_t imm_data)
{
if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff))
return 1;
return 0;
}
void host_arm64_BLR(codeblock_t *block, int addr_reg)
{
codegen_addlong(block, OPCODE_BLR | Rn(addr_reg));
}
void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest)
{
int offset = dest - (uintptr_t)&block->data[block_pos];
if (!offset_is_19bit(offset))
fatal("host_arm64_CBNZ - offset out of range %x\n", offset);
codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg));
}
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset)
{
if (!in_range7_x(offset))
fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset);
codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2));
}
void host_arm64_LDR_LITERAL_W(codeblock_t *block, int dest_reg, int literal_offset)
{
int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos;
if (!offset_is_19bit(offset))
fatal("host_arm64_CBNZ - offset out of range %x\n", offset);
codegen_addlong(block, OPCODE_LDR_LITERAL_W | OFFSET19(offset) | Rt(dest_reg));
}
void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offset)
{
int offset = (ARM_LITERAL_POOL_OFFSET + literal_offset) - block_pos;
if (!offset_is_19bit(offset))
fatal("host_arm64_CBNZ - offset out of range %x\n", offset);
codegen_addlong(block, OPCODE_LDR_LITERAL_X | OFFSET19(offset) | Rt(dest_reg));
}
void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data)
{
int hw;
if (!imm_is_imm16(imm_data))
fatal("MOVZ_IMM - imm not representable %08x\n", imm_data);
hw = (imm_data & 0xffff0000) ? 1 : 0;
if (hw)
imm_data >>= 16;
codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg));
}
void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data)
{
int hw;
if (!imm_is_imm16(imm_data))
fatal("MOVK_IMM - imm not representable %08x\n", imm_data);
hw = (imm_data & 0xffff0000) ? 1 : 0;
if (hw)
imm_data >>= 16;
codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg));
}
void host_arm64_NOP(codeblock_t *block)
{
codegen_addlong(block, OPCODE_NOP);
}
void host_arm64_RET(codeblock_t *block, int reg)
{
codegen_addlong(block, OPCODE_RET | Rn(reg));
}
void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset)
{
if (!in_range7_x(offset))
fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset);
codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2));
}
void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset)
{
if (!in_range12_w(offset))
fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset);
codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg));
}
void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset)
{
if (!in_range12_b(offset))
fatal("host_arm64_STRB_IMM out of range12 %i\n", offset);
codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg));
}
void host_arm64_call(codeblock_t *block, void *dst_addr)
{
int offset = add_literal_q(block, (uintptr_t)dst_addr);
host_arm64_LDR_LITERAL_X(block, REG_X16, offset);
host_arm64_BLR(block, REG_X16);
}
void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data)
{
if (imm_is_imm16(imm_data))
host_arm64_MOVZ_IMM(block, reg, imm_data);
else
{
host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff);
host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000);
}
}
static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
{
host_arm64_call(block, uop->p);
host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
return 0;
}
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_ARG0, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_ARG1, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_ARG2, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_ARG3, uop->imm_data);
return 0;
}
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_W16, uop->imm_data);
if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state))
host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state);
else
fatal("codegen_STORE_PTR_IMM - not in range\n");
return 0;
}
static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
{
host_arm64_mov_imm(block, REG_W16, uop->imm_data);
if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state))
host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state);
else
fatal("codegen_STORE_PTR_IMM - not in range\n");
return 0;
}
const uOpFn uop_handlers[UOP_MAX] =
{
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
[UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM,
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8
};
#endif

View file

@ -0,0 +1,44 @@
#define REG_R0 0
#define REG_R1 1
#define REG_R2 2
#define REG_R3 3
#define REG_R4 4
#define REG_R5 5
#define REG_R6 6
#define REG_R7 7
#define REG_R8 8
#define REG_R9 9
#define REG_R10 10
#define REG_R11 11
#define REG_R12 12
#define REG_SP 13
#define REG_LR 14
#define REG_PC 15
#define REG_ARG0 REG_R0
#define REG_ARG1 REG_R1
#define REG_ARG2 REG_R2
#define REG_ARG3 REG_R3
#define REG_CPUSTATE REG_R10
#define REG_LITERAL REG_R11
#define REG_MASK_R0 (1 << REG_R0)
#define REG_MASK_R1 (1 << REG_R1)
#define REG_MASK_R2 (1 << REG_R2)
#define REG_MASK_R3 (1 << REG_R3)
#define REG_MASK_R4 (1 << REG_R4)
#define REG_MASK_R5 (1 << REG_R5)
#define REG_MASK_R6 (1 << REG_R6)
#define REG_MASK_R7 (1 << REG_R7)
#define REG_MASK_R8 (1 << REG_R8)
#define REG_MASK_R9 (1 << REG_R9)
#define REG_MASK_R10 (1 << REG_R10)
#define REG_MASK_R11 (1 << REG_R11)
#define REG_MASK_R12 (1 << REG_R12)
#define REG_MASK_SP (1 << REG_SP)
#define REG_MASK_LR (1 << REG_LR)
#define REG_MASK_PC (1 << REG_PC)
#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \
REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11)

View file

@ -0,0 +1,314 @@
#ifdef __ARM_EABI__
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_arm_defs.h"
#include "codegen_ir_defs.h"
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
*(uint32_t *)&block->data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addlong over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
#define Rm(x) (x)
#define Rd(x) ((x) << 12)
#define Rn(x) ((x) << 16)
#define DATA_OFFSET_UP (1 << 23)
#define DATA_OFFSET_DOWN (0 << 23)
#define COND_SHIFT 28
#define COND_NE (0x1 << COND_SHIFT)
#define COND_AL (0xe << COND_SHIFT)
#define OPCODE_SHIFT 20
#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT)
#define OPCODE_B (0xa0 << OPCODE_SHIFT)
#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT)
#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT)
#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT)
#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT)
#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT)
#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT)
#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT)
#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT)
#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT)
#define OPCODE_BLX 0xe12fff30
#define B_OFFSET(x) (((x) >> 2) & 0xffffff)
static int literal_offset = 0;
void codegen_reset_literal_pool(codeblock_t *block)
{
literal_offset = 0;
}
int add_literal(codeblock_t *block, uint32_t data)
{
if (literal_offset >= 4096)
fatal("add_literal - literal pool full\n");
*(uint32_t *)&block->data[ARM_LITERAL_POOL_OFFSET + literal_offset] = data;
literal_offset += 4;
return literal_offset - 4;
}
static inline uint32_t arm_data_offset(int offset)
{
if (offset < -0xffc || offset > 0xffc)
fatal("arm_data_offset out of range - %i\n", offset);
if (offset >= 0)
return offset | DATA_OFFSET_UP;
return (-offset) | DATA_OFFSET_DOWN;
}
static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm)
{
int shift = 0;
//pclog("get_arm_imm - imm_data=%08x\n", imm_data);
if (!(imm_data & 0xffff))
{
shift += 16;
imm_data >>= 16;
}
if (!(imm_data & 0xff))
{
shift += 8;
imm_data >>= 8;
}
if (!(imm_data & 0xf))
{
shift += 4;
imm_data >>= 4;
}
if (!(imm_data & 0x3))
{
shift += 2;
imm_data >>= 2;
}
if (imm_data > 0xff) /*Note - should handle rotation round the word*/
return 0;
//pclog(" imm_data=%02x shift=%i\n", imm_data, shift);
*arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8);
return 1;
}
static inline int in_range(void *addr, void *base)
{
int diff = (uintptr_t)addr - (uintptr_t)base;
if (diff < -4095 || diff > 4095)
return 0;
return 1;
}
void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm)
{
uint32_t arm_imm;
if (!get_arm_imm(imm, &arm_imm))
fatal("host_arm_ADD_IMM !check_arm_imm %08x\n", imm);
codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm);
}
void host_arm_BLX(codeblock_t *block, int addr_reg)
{
codegen_addlong(block, OPCODE_BLX | Rm(addr_reg));
}
void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr)
{
uint32_t offset = (dest_addr - (uintptr_t)&block->data[block_pos]) - 8;
if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000)
fatal("host_arm_BNE - out of range %08x %i\n", offset, offset);
codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset));
}
void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask)
{
codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask);
}
void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset)
{
codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset));
}
void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm)
{
uint32_t arm_imm;
if (!get_arm_imm(imm, &arm_imm))
fatal("host_arm_MOV_IMM !check_arm_imm %08x\n", imm);
codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm);
}
void host_arm_MOV_REG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg));
}
void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask)
{
codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask);
}
void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset)
{
codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset));
}
void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset)
{
codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset));
}
void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm)
{
uint32_t arm_imm;
if (!get_arm_imm(imm, &arm_imm))
fatal("host_arm_SUB_IMM !check_arm_imm %08x\n", imm);
codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm);
}
void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2)
{
codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2));
}
void host_arm_call(codeblock_t *block, void *dst_addr)
{
int offset = add_literal(block, (uintptr_t)dst_addr);
host_arm_LDR_IMM(block, REG_R3, REG_LITERAL, offset);
host_arm_BLX(block, REG_R3);
}
void host_arm_nop(codeblock_t *block)
{
host_arm_MOV_REG(block, REG_R0, REG_R0);
}
static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
{
host_arm_call(block, uop->p);
host_arm_TST_REG(block, REG_R0, REG_R0);
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
return 0;
}
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
{
uint32_t arm_imm;
if (get_arm_imm(uop->imm_data, &arm_imm))
host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data);
else
{
int offset = add_literal(block, uop->imm_data);
host_arm_LDR_IMM(block, REG_ARG0, REG_LITERAL, offset);
}
return 0;
}
static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop)
{
uint32_t arm_imm;
if (get_arm_imm(uop->imm_data, &arm_imm))
host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data);
else
{
int offset = add_literal(block, uop->imm_data);
host_arm_LDR_IMM(block, REG_ARG1, REG_LITERAL, offset);
}
return 0;
}
static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop)
{
uint32_t arm_imm;
if (get_arm_imm(uop->imm_data, &arm_imm))
host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data);
else
{
int offset = add_literal(block, uop->imm_data);
host_arm_LDR_IMM(block, REG_ARG2, REG_LITERAL, offset);
}
return 0;
}
static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
{
uint32_t arm_imm;
if (get_arm_imm(uop->imm_data, &arm_imm))
host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data);
else
{
int offset = add_literal(block, uop->imm_data);
host_arm_LDR_IMM(block, REG_ARG3, REG_LITERAL, offset);
}
return 0;
}
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
{
uint32_t arm_imm;
if (get_arm_imm(uop->imm_data, &arm_imm))
host_arm_MOV_IMM(block, REG_R0, uop->imm_data);
else
{
int offset = add_literal(block, uop->imm_data);
host_arm_LDR_IMM(block, REG_R0, REG_LITERAL, offset);
}
if (in_range(uop->p, &cpu_state))
host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state);
else
fatal("codegen_STORE_PTR_IMM - not in range\n");
return 0;
}
static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
{
host_arm_MOV_IMM(block, REG_R0, uop->imm_data);
if (in_range(uop->p, &cpu_state))
host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state);
else
fatal("codegen_STORE_PTR_IMM - not in range\n");
return 0;
}
const uOpFn uop_handlers[UOP_MAX] =
{
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
[UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM,
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8
};
#endif

View file

@ -0,0 +1,156 @@
#ifdef __amd64__
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "x86.h"
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
#include <windows.h>
#endif
static void *mem_abrt_rout;
void codegen_backend_init()
{
int c;
#if defined(__linux__) || defined(__APPLE__)
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
long pagemask = ~(pagesize - 1);
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
#endif
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
#if defined(__linux__) || defined(__APPLE__)
start = (void *)((long)codeblock & pagemask);
len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
static inline void call(codeblock_t *block, uintptr_t func)
{
uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5];
if (diff >= -0x80000000 && diff < 0x7fffffff)
{
addbyte(0xE8); /*CALL*/
addlong((uint32_t)diff);
}
else
{
addbyte(0x48); /*MOV RAX, func*/
addbyte(0xb8);
addquad(func);
addbyte(0xff); /*CALL RAX*/
addbyte(0xd0);
}
}
void codegen_backend_prologue(codeblock_t *block)
{
block_pos = 0; /*Entry code*/
addbyte(0x53); /*PUSH RBX*/
addbyte(0x55); /*PUSH RBP*/
addbyte(0x56); /*PUSH RSI*/
addbyte(0x57); /*PUSH RDI*/
addbyte(0x41); /*PUSH R12*/
addbyte(0x54);
addbyte(0x41); /*PUSH R13*/
addbyte(0x55);
addbyte(0x41); /*PUSH R14*/
addbyte(0x56);
addbyte(0x41); /*PUSH R15*/
addbyte(0x57);
addbyte(0x48); /*SUBL $40,%rsp*/
addbyte(0x83);
addbyte(0xEC);
addbyte(0x28);
addbyte(0x48); /*MOVL RBP, &cpu_state*/
addbyte(0xBD);
addquad(((uintptr_t)&cpu_state) + 128);
}
void codegen_backend_epilogue(codeblock_t *block)
{
addbyte(0x48); /*ADDL $40,%rsp*/
addbyte(0x83);
addbyte(0xC4);
addbyte(0x28);
addbyte(0x41); /*POP R15*/
addbyte(0x5f);
addbyte(0x41); /*POP R14*/
addbyte(0x5e);
addbyte(0x41); /*POP R13*/
addbyte(0x5d);
addbyte(0x41); /*POP R12*/
addbyte(0x5c);
addbyte(0x5f); /*POP RDI*/
addbyte(0x5e); /*POP RSI*/
addbyte(0x5d); /*POP RBP*/
addbyte(0x5b); /*POP RDX*/
addbyte(0xC3); /*RET*/
if (block_pos > BLOCK_GPF_OFFSET)
fatal("Over limit!\n");
block_pos = BLOCK_GPF_OFFSET;
#if WIN64
addbyte(0x48); /*XOR RCX, RCX*/
addbyte(0x31);
addbyte(0xc9);
addbyte(0x31); /*XOR EDX, EDX*/
addbyte(0xd2);
#else
addbyte(0x48); /*XOR RDI, RDI*/
addbyte(0x31);
addbyte(0xff);
addbyte(0x31); /*XOR ESI, ESI*/
addbyte(0xf6);
#endif
call(block, (uintptr_t)x86gpf);
while (block_pos < BLOCK_EXIT_OFFSET)
addbyte(0x90); /*NOP*/
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
addbyte(0x48); /*ADDL $40,%rsp*/
addbyte(0x83);
addbyte(0xC4);
addbyte(0x28);
addbyte(0x41); /*POP R15*/
addbyte(0x5f);
addbyte(0x41); /*POP R14*/
addbyte(0x5e);
addbyte(0x41); /*POP R13*/
addbyte(0x5d);
addbyte(0x41); /*POP R12*/
addbyte(0x5c);
addbyte(0x5f); /*POP RDI*/
addbyte(0x5e); /*POP RSI*/
addbyte(0x5d); /*POP RBP*/
addbyte(0x5b); /*POP RDX*/
addbyte(0xC3); /*RET*/
}
#endif

View file

@ -0,0 +1,16 @@
#define BLOCK_SIZE 0x4000
#define BLOCK_MASK 0x3fff
#define BLOCK_START 0
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
/*Hack until better memory management written*/
#define BLOCK_EXIT_OFFSET 0xffe0
/*#define BLOCK_EXIT_OFFSET 0x7f0*/
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
/*#define BLOCK_MAX 1720*/
#define BLOCK_MAX 65208

View file

@ -0,0 +1,8 @@
#define REG_EAX 0
#define REG_ECX 1
#define REG_EDX 2
#define REG_EBX 3
#define REG_ESP 4
#define REG_EBP 5
#define REG_ESI 6
#define REG_EDI 7

View file

@ -0,0 +1,232 @@
#ifdef __amd64__
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_x86-64_defs.h"
#include "codegen_ir_defs.h"
#define STACK_ARG0 (0)
#define STACK_ARG1 (4)
#define STACK_ARG2 (8)
#define STACK_ARG3 (12)
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
{
block->data[block_pos++] = val;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte over! %i\n", block_pos);
// CPU_BLOCK_END();
}
}
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte2 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
block->data[block_pos++] = valc;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte3 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
block->data[block_pos++] = valc;
block->data[block_pos++] = vald;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte4 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addword(codeblock_t *block, uint16_t val)
{
*(uint16_t *)&block->data[block_pos] = val;
block_pos += 2;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addword over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
*(uint32_t *)&block->data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addlong over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addquad(codeblock_t *block, uint64_t val)
{
*(uint64_t *)&block->data[block_pos] = val;
block_pos += 8;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addquad over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void call(codeblock_t *block, uintptr_t func)
{
uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5];
if (diff >= -0x80000000 && diff < 0x7fffffff)
{
codegen_addbyte(block, 0xE8); /*CALL*/
codegen_addlong(block, (uint32_t)diff);
}
else
{
codegen_addbyte2(block, 0x48, 0xb8); /*MOV RAX, func*/
codegen_addquad(block, func);
codegen_addbyte2(block, 0xff, 0xd0); /*CALL RAX*/
}
}
static void host_x86_CALL(codeblock_t *block, void *p)
{
call(block, (uintptr_t)p);
}
static void host_x86_JNZ(codeblock_t *block, void *p)
{
codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/
codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]);
}
static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/
codegen_addlong(block, (uint32_t)p);
codegen_addlong(block, imm_data);
}
static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/
codegen_addlong(block, (uint32_t)p);
codegen_addbyte(block, imm_data);
}
static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data)
{
if (reg & 8)
fatal("host_x86_MOV32_REG_IMM reg & 8\n");
codegen_addbyte(block, 0xb8 | reg); /*MOV reg, imm_data*/
codegen_addlong(block, imm_data);
}
static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data)
{
if (!offset)
{
codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/
codegen_addlong(block, imm_data);
}
else if (offset >= -80 || offset < 0x80)
{
codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/
codegen_addlong(block, offset);
codegen_addlong(block, imm_data);
}
}
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg)
{
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/
}
static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
{
host_x86_CALL(block, uop->p);
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
return 0;
}
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
{
#if WIN64
host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data);
#else
host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data);
#endif
return 0;
}
static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop)
{
#if WIN64
host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data);
#else
host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data);
#endif
return 0;
}
static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop)
{
fatal("codegen_LOAD_FUNC_ARG2_IMM\n");
return 0;
}
static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
{
fatal("codegen_LOAD_FUNC_ARG3_IMM\n");
return 0;
}
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
{
if (((uintptr_t)uop->p) >> 32)
fatal("STORE_PTR_IMM 64-bit addr\n");
host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
{
if (((uintptr_t)uop->p) >> 32)
fatal("STORE_PTR_IMM_8 64-bit addr\n");
host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
const uOpFn uop_handlers[UOP_MAX] =
{
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
[UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM,
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8
};
#endif

121
src/codegen_backend_x86.c Normal file
View file

@ -0,0 +1,121 @@
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "x86.h"
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
#include <windows.h>
#endif
static void *mem_abrt_rout;
void codegen_backend_init()
{
int c;
#if defined(__linux__) || defined(__APPLE__)
void *start;
size_t len;
long pagesize = sysconf(_SC_PAGESIZE);
long pagemask = ~(pagesize - 1);
#endif
#if defined WIN32 || defined _WIN32 || defined _WIN32
codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t));
#endif
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
#if defined(__linux__) || defined(__APPLE__)
start = (void *)((long)codeblock & pagemask);
len = (((BLOCK_SIZE+1) * sizeof(codeblock_t)) + pagesize) & pagemask;
if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
perror("mprotect");
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
block_current = BLOCK_SIZE;
block_pos = 0;
mem_abrt_rout = &codeblock[block_current].data[block_pos];
addbyte(0x83); /*ADDL $16+4,%esp*/
addbyte(0xC4);
addbyte(0x10+4);
addbyte(0x5f); /*POP EDI*/
addbyte(0x5e); /*POP ESI*/
addbyte(0x5d); /*POP EBP*/
addbyte(0x5b); /*POP EDX*/
addbyte(0xC3); /*RET*/
asm(
"fstcw %0\n"
: "=m" (cpu_state.old_npxc)
);
}
void codegen_backend_prologue(codeblock_t *block)
{
block_pos = 0; /*Entry code*/
addbyte(0x53); /*PUSH EBX*/
addbyte(0x55); /*PUSH EBP*/
addbyte(0x56); /*PUSH ESI*/
addbyte(0x57); /*PUSH EDI*/
addbyte(0x83); /*SUBL $16,%esp*/
addbyte(0xEC);
addbyte(0x10);
addbyte(0xBD); /*MOVL EBP, &cpu_state*/
addlong(((uintptr_t)&cpu_state) + 128);
}
void codegen_backend_epilogue(codeblock_t *block)
{
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0xC4);
addbyte(0x10);
addbyte(0x5f); /*POP EDI*/
addbyte(0x5e); /*POP ESI*/
addbyte(0x5d); /*POP EBP*/
addbyte(0x5b); /*POP EDX*/
addbyte(0xC3); /*RET*/
if (block_pos > BLOCK_GPF_OFFSET)
fatal("Over limit!\n");
block_pos = BLOCK_GPF_OFFSET;
addbyte(0xc7); /*MOV [ESP],0*/
addbyte(0x04);
addbyte(0x24);
addlong(0);
addbyte(0xc7); /*MOV [ESP+4],0*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addlong(0);
addbyte(0xe8); /*CALL x86gpf*/
addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0xC4);
addbyte(0x10);
addbyte(0x5f); /*POP EDI*/
addbyte(0x5e); /*POP ESI*/
addbyte(0x5d); /*POP EBP*/
addbyte(0x5b); /*POP EDX*/
addbyte(0xC3); /*RET*/
}
#endif

16
src/codegen_backend_x86.h Normal file
View file

@ -0,0 +1,16 @@
#define BLOCK_SIZE 0x4000
#define BLOCK_MASK 0x3fff
#define BLOCK_START 0
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
/*Hack until better memory management written*/
#define BLOCK_EXIT_OFFSET 0xfff0
/*#define BLOCK_EXIT_OFFSET 0x7f0*/
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
/*#define BLOCK_MAX 1720*/
#define BLOCK_MAX 65208

View file

@ -0,0 +1,8 @@
#define REG_EAX 0
#define REG_ECX 1
#define REG_EDX 2
#define REG_EBX 3
#define REG_ESP 4
#define REG_EBP 5
#define REG_ESI 6
#define REG_EDI 7

View file

@ -0,0 +1,195 @@
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_backend_x86_defs.h"
#include "codegen_ir_defs.h"
#define STACK_ARG0 (0)
#define STACK_ARG1 (4)
#define STACK_ARG2 (8)
#define STACK_ARG3 (12)
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
{
block->data[block_pos++] = val;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte over! %i\n", block_pos);
// CPU_BLOCK_END();
}
}
static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte2 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
block->data[block_pos++] = valc;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte3 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
{
block->data[block_pos++] = vala;
block->data[block_pos++] = valb;
block->data[block_pos++] = valc;
block->data[block_pos++] = vald;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addbyte4 over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addword(codeblock_t *block, uint16_t val)
{
*(uint16_t *)&block->data[block_pos] = val;
block_pos += 2;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addword over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addlong(codeblock_t *block, uint32_t val)
{
*(uint32_t *)&block->data[block_pos] = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addlong over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static inline void codegen_addquad(codeblock_t *block, uint64_t val)
{
*(uint64_t *)&block->data[block_pos] = val;
block_pos += 8;
if (block_pos >= BLOCK_MAX)
{
fatal("codegen_addquad over! %i\n", block_pos);
CPU_BLOCK_END();
}
}
static void host_x86_CALL(codeblock_t *block, void *p)
{
codegen_addbyte(block, 0xe8); /*CALL*/
codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]);
}
static void host_x86_JNZ(codeblock_t *block, void *p)
{
codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/
codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block->data[block_pos + 4]);
}
static void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/
codegen_addlong(block, (uint32_t)p);
codegen_addlong(block, imm_data);
}
static void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/
codegen_addlong(block, (uint32_t)p);
codegen_addbyte(block, imm_data);
}
static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data)
{
if (!offset)
{
codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/
codegen_addlong(block, imm_data);
}
else if (offset >= -80 || offset < 0x80)
{
codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/
codegen_addlong(block, imm_data);
}
else
{
codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/
codegen_addlong(block, offset);
codegen_addlong(block, imm_data);
}
}
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg)
{
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/
}
static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop)
{
host_x86_CALL(block, uop->p);
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
return 0;
}
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data);
return 0;
}
static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data);
return 0;
}
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
{
host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
{
host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
const uOpFn uop_handlers[UOP_MAX] =
{
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
[UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM,
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8
};
#endif

34
src/codegen_ir.c Normal file
View file

@ -0,0 +1,34 @@
#include "ibm.h"
#include "codegen.h"
#include "codegen_backend.h"
#include "codegen_ir.h"
static ir_data_t ir_block;
ir_data_t *codegen_ir_init()
{
ir_block.wr_pos = 0;
//pclog("codegen_ir_init\n");
return &ir_block;
}
void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
{
int c;
codegen_backend_prologue(block);
for (c = 0; c < ir->wr_pos; c++)
{
uop_t *uop = &ir->uops[c];
//pclog("uOP %i : %08x\n", c, uop->type);
uop_handlers[uop->type & UOP_MASK](block, uop);
}
codegen_backend_epilogue(block);
// fatal("IR compilation complete\n");
}

5
src/codegen_ir.h Normal file
View file

@ -0,0 +1,5 @@
#include "codegen_ir_defs.h"
ir_data_t *codegen_ir_init();
void codegen_ir_compile(ir_data_t *ir, codeblock_t *block);

152
src/codegen_ir_defs.h Normal file
View file

@ -0,0 +1,152 @@
#ifndef _CODEGEN_IR_DEFS_
#define _CODEGEN_IR_DEFS_
#define IREG_L (0 << 6)
#define IREG_W (1 << 6)
#define IREG_B (2 << 6)
#define IREG_BH (3 << 6)
enum
{
ireg_EAX = 0,
ireg_ECX = 1,
ireg_EDX = 2,
ireg_EBX = 3,
ireg_ESP = 4,
ireg_EBP = 5,
ireg_ESI = 6,
ireg_EDI = 7,
ireg_flags_op = 8,
ireg_flags_reg = 9,
ireg_flags_op1 = 10,
ireg_flags_op2 = 11,
ireg_flags_pc = 12,
ireg_flags_oldpc = 13,
ireg_eaaddr = 14,
/*Temporary registers are stored on the stack, and are not guaranteed to
be preserved across uOPs. They will not be written back if they will
not be read again.*/
ireg_temp0 = 16,
ireg_temp1 = 17,
ireg_temp2 = 18,
ireg_temp3 = 19
};
#define UOP_REG(reg, size, version) ((reg) | (size) | (version << 8))
#define UOP_REG_UNUSED 0xffff
/*uOP is a barrier. All previous uOPs must have completed before this one executes.
All registers must have been written back or discarded*/
#define UOP_TYPE_BARRIER (1 << 31)
/*uOP uses source and dest registers*/
#define UOP_TYPE_PARAMS_REGS (1 << 28)
/*uOP uses pointer*/
#define UOP_TYPE_PARAMS_POINTER (1 << 29)
/*uOP uses immediate data*/
#define UOP_TYPE_PARAMS_IMM (1 << 30)
#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00)
#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01)
#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02)
#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03)
#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08)
#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09)
#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a)
#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b)
#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER)
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER)
#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12)
#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13)
#define UOP_MAX 0x14
#define UOP_MASK 0xffff
typedef struct uop_t
{
uint32_t type;
uint16_t dest_reg_a;
uint16_t src_reg_a;
uint16_t src_reg_b;
uint16_t src_reg_c;
uint32_t imm_data;
void *p;
} uop_t;
#define UOP_NR_MAX 4096
typedef struct ir_data_t
{
uop_t uops[UOP_NR_MAX];
int wr_pos;
} ir_data_t;
static inline uop_t *uop_alloc(ir_data_t *ir)
{
uop_t *uop;
if (ir->wr_pos >= UOP_NR_MAX)
fatal("Exceeded uOP max\n");
uop = &ir->uops[ir->wr_pos++];
uop->dest_reg_a = UOP_REG_UNUSED;
uop->src_reg_a = UOP_REG_UNUSED;
uop->src_reg_b = UOP_REG_UNUSED;
uop->src_reg_c = UOP_REG_UNUSED;
return uop;
}
static inline void uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int arg, uint16_t src_reg_a)
{
uop_t *uop = uop_alloc(ir);
uop->type = uop_type;
uop->src_reg_a = src_reg_a;
}
static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm)
{
uop_t *uop = uop_alloc(ir);
uop->type = uop_type;
uop->imm_data = imm;
}
static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p)
{
uop_t *uop = uop_alloc(ir);
uop->type = uop_type;
uop->p = p;
}
static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm)
{
uop_t *uop = uop_alloc(ir);
uop->type = uop_type;
uop->p = p;
uop->imm_data = imm;
}
#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg)
#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm)
#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p)
#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p)
#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm)
#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm)
#endif

View file

@ -1,591 +0,0 @@
#include "ibm.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86_flags.h"
#include "x87.h"
#include "386_common.h"
#include "cpu.h"
#include "codegen.h"
#include "codegen_ops.h"
#ifdef __amd64__
#include "codegen_ops_x86-64.h"
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
#include "codegen_ops_x86.h"
#endif
#include "codegen_ops_arith.h"
#include "codegen_ops_fpu.h"
#include "codegen_ops_jump.h"
#include "codegen_ops_logic.h"
#include "codegen_ops_misc.h"
#include "codegen_ops_mmx.h"
#include "codegen_ops_mov.h"
#include "codegen_ops_shift.h"
#include "codegen_ops_stack.h"
#include "codegen_ops_xchg.h"
RecompOpFn recomp_opcodes[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16,
/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL,
/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL,
/*40*/ ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw,
/*50*/ ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,NULL, NULL, NULL, NULL, NULL,
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE,
/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_w, ropMOV_seg_w, NULL,
/*90*/ ropNOP, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropMOV_AL_a, ropMOV_AX_a, ropMOV_a_AL, ropMOV_a_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES, ropLDS, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ ropD0, ropD1_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_w, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_16,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32,
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
/*40*/ ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl,
/*50*/ ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,NULL, NULL, NULL, NULL, NULL,
/*70*/ ropJO, ropJNO, ropJB, ropJNB, ropJE, ropJNE, ropJBE, ropJNBE, ropJS, ropJNS, ropJP, ropJNP, ropJL, ropJNL, ropJLE, ropJNLE,
/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_w_seg, ropLEA_l, ropMOV_seg_w, NULL,
/*90*/ ropNOP, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropMOV_AL_a, ropMOV_EAX_a, ropMOV_a_AL, ropMOV_a_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES, ropLDS, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32
};
RecompOpFn recomp_opcodes_0f[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_mm_l, ropMOVQ_mm_q,
/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, ropEMMS, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_l_mm, ropMOVQ_q_mm,
/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
};
RecompOpFn recomp_opcodes_d8[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL,
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR,
/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs,
/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs,
/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs,
/*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL,
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR,
/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR,
};
RecompOpFn recomp_opcodes_d9[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW,
/*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_da[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil,
/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil,
/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_db[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl, ropFISTPl,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_dc[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr,
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr,
/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd,
/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd,
/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd,
/*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr,
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr,
/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr,
};
RecompOpFn recomp_opcodes_dd[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_de[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw,
/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw,
/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw,
/*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
};
RecompOpFn recomp_opcodes_df[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_REPE[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_REPNE[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};

File diff suppressed because it is too large Load diff

View file

@ -1,645 +0,0 @@
static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_FXCH(opcode & 7);
return op_pc;
}
static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_FLD(opcode & 7);
return op_pc;
}
static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_FST(opcode & 7);
return op_pc;
}
static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_FST(opcode & 7);
FP_POP();
return op_pc;
}
static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_LOAD_S();
return op_pc + 1;
}
static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_Q(target_seg);
FP_LOAD_D();
return op_pc + 1;
}
static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
FP_LOAD_IW();
return op_pc + 1;
}
static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_LOAD_IL();
return op_pc + 1;
}
static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_Q(target_seg);
FP_LOAD_IQ();
codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
return op_pc + 1;
}
static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
host_reg = FP_LOAD_REG(0);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
return op_pc + 1;
}
static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg1, host_reg2;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 7);
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
return op_pc + 1;
}
static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
FP_POP();
return new_pc;
}
static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
FP_POP();
return new_pc;
}
#define ropFarith(name, size, load, op) \
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
x86seg *target_seg; \
\
FP_ENTER(); \
op_pc--; \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
load(target_seg); \
\
op(FPU_ ## name); \
\
return op_pc + 1; \
}
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
#define ropFcompare(name, size, load, op) \
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
x86seg *target_seg; \
\
FP_ENTER(); \
op_pc--; \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
load(target_seg); \
\
op(); \
\
return op_pc + 1; \
} \
static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \
\
FP_POP(); \
\
return new_pc; \
}
ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S);
ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D);
ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW);
ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL);
/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_ADD);
return op_pc + 1;
}
static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_DIV);
return op_pc + 1;
}
static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_MUL);
return op_pc + 1;
}
static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_SUB);
return op_pc + 1;
}*/
static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_ADD, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_COMPARE_REG(0, opcode & 7);
return op_pc;
}
static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIV, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIVR, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_MUL, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUB, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUBR, 0, opcode & 7);
return op_pc;
}
static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_ADD, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIV, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_MUL, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUB, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
return op_pc;
}
static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_ADD, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_COMPARE_REG(0, opcode & 7);
FP_POP();
return op_pc;
}
static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIV, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_MUL, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUB, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
FP_POP();
return op_pc;
}
static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_COMPARE_REG(0, 1);
FP_POP2();
return op_pc;
}
static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
FP_ENTER();
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs);
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
return op_pc;
}
static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
host_reg = FP_LOAD_REG_INT_W(0);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
return op_pc + 1;
}
static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
host_reg = FP_LOAD_REG_INT(0);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
return op_pc + 1;
}
static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
FP_POP();
return new_pc;
}
static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
FP_POP();
return new_pc;
}
static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg1, host_reg2;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
FP_POP();
return op_pc + 1;
}
static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
UPDATE_NPXC(0);
return op_pc + 1;
}
static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
CHECK_SEG_WRITE(target_seg);
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
return op_pc + 1;
}
static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_FCHS();
return op_pc;
}
#define opFLDimm(name, v) \
static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
static double fp_imm = v; \
\
FP_ENTER(); \
FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \
\
return op_pc; \
}
opFLDimm(1, 1.0)
opFLDimm(L2T, 3.3219280948873623)
opFLDimm(L2E, 1.4426950408889634);
opFLDimm(PI, 3.141592653589793);
opFLDimm(EG2, 0.3010299956639812);
opFLDimm(Z, 0.0)
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
FP_ENTER();
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
return op_pc;
}

View file

@ -1,270 +0,0 @@
static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t offset = fetchdat & 0xff;
if (offset & 0x80)
offset |= 0xffffff00;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset);
return -1;
}
static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
return -1;
}
static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t offset = fastreadl(cs + op_pc);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
return -1;
}
static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t offset = fetchdat & 0xff;
if (offset & 0x80)
offset |= 0xffffff00;
if (op_32 & 0x200)
{
int host_reg = LOAD_REG_L(REG_ECX);
TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
}
else
{
int host_reg = LOAD_REG_W(REG_CX);
TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
}
return op_pc+1;
}
static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t offset = fetchdat & 0xff;
if (offset & 0x80)
offset |= 0xffffff00;
if (op_32 & 0x200)
{
int host_reg = LOAD_REG_L(REG_ECX);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_REG_L_RELEASE(host_reg);
TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
}
else
{
int host_reg = LOAD_REG_W(REG_CX);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_REG_W_RELEASE(host_reg);
TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
}
return op_pc+1;
}
static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC((uintptr_t)CF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
int host_reg;
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN)
{
case FLAGS_ZN8:
case FLAGS_ZN16:
case FLAGS_ZN32:
case FLAGS_ADD8:
case FLAGS_ADD16:
case FLAGS_ADD32:
case FLAGS_SUB8:
case FLAGS_SUB16:
case FLAGS_SUB32:
case FLAGS_SHL8:
case FLAGS_SHL16:
case FLAGS_SHL32:
case FLAGS_SHR8:
case FLAGS_SHR16:
case FLAGS_SHR32:
case FLAGS_SAR8:
case FLAGS_SAR16:
case FLAGS_SAR32:
case FLAGS_INC8:
case FLAGS_INC16:
case FLAGS_INC32:
case FLAGS_DEC8:
case FLAGS_DEC16:
case FLAGS_DEC32:
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
if (not)
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
else
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
break;
case FLAGS_UNKNOWN:
CALL_FUNC((uintptr_t)ZF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
break;
}
}
static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC((uintptr_t)VF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC((uintptr_t)PF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
int host_reg;
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN)
{
case FLAGS_ZN8:
case FLAGS_ADD8:
case FLAGS_SUB8:
case FLAGS_SHL8:
case FLAGS_SHR8:
case FLAGS_SAR8:
case FLAGS_INC8:
case FLAGS_DEC8:
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
AND_HOST_REG_IMM(host_reg, 0x80);
if (not)
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
break;
case FLAGS_ZN16:
case FLAGS_ADD16:
case FLAGS_SUB16:
case FLAGS_SHL16:
case FLAGS_SHR16:
case FLAGS_SAR16:
case FLAGS_INC16:
case FLAGS_DEC16:
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
AND_HOST_REG_IMM(host_reg, 0x8000);
if (not)
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
break;
case FLAGS_ZN32:
case FLAGS_ADD32:
case FLAGS_SUB32:
case FLAGS_SHL32:
case FLAGS_SHR32:
case FLAGS_SAR32:
case FLAGS_INC32:
case FLAGS_DEC32:
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
AND_HOST_REG_IMM(host_reg, 0x80000000);
if (not)
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
break;
case FLAGS_UNKNOWN:
CALL_FUNC((uintptr_t)NF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
break;
}
}
#define ropBRANCH(name, func, not) \
static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \
uint32_t op_32, uint32_t op_pc, \
codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xff; \
\
if (offset & 0x80) \
offset |= 0xffffff00; \
\
func(1, op_pc, offset, not); \
\
return op_pc+1; \
} \
static uint32_t rop ## name ## _w(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xffff; \
\
if (offset & 0x8000) \
offset |= 0xffff0000; \
\
func(2, op_pc, offset, not); \
\
return op_pc+2; \
} \
static uint32_t rop ## name ## _l(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fastreadl(cs + op_pc); \
\
func(4, op_pc, offset, not); \
\
return op_pc+4; \
}
ropBRANCH(JB, BRANCH_COND_B, 0)
ropBRANCH(JNB, BRANCH_COND_B, 1)
ropBRANCH(JE, BRANCH_COND_E, 0)
ropBRANCH(JNE, BRANCH_COND_E, 1)
ropBRANCH(JO, BRANCH_COND_O, 0)
ropBRANCH(JNO, BRANCH_COND_O, 1)
ropBRANCH(JP, BRANCH_COND_P, 0)
ropBRANCH(JNP, BRANCH_COND_P, 1)
ropBRANCH(JS, BRANCH_COND_S, 0)
ropBRANCH(JNS, BRANCH_COND_S, 1)
ropBRANCH(JL, BRANCH_COND_L, 0)
ropBRANCH(JNL, BRANCH_COND_L, 1)
ropBRANCH(JLE, BRANCH_COND_LE, 0)
ropBRANCH(JNLE, BRANCH_COND_LE, 1)
ropBRANCH(JBE, BRANCH_COND_BE, 0)
ropBRANCH(JNBE, BRANCH_COND_BE, 1)

View file

@ -1,564 +0,0 @@
#define ROP_LOGIC(name, op, writeback) \
static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
dst_reg = LOAD_REG_B(fetchdat & 7); \
} \
else \
{ \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_B_RELEASE(dst_reg); \
else \
{ \
LOAD_EA(); \
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \
} \
} \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
dst_reg = LOAD_REG_W(fetchdat & 7); \
} \
else \
{ \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_W_RELEASE(dst_reg); \
else \
{ \
LOAD_EA(); \
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \
} \
} \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
dst_reg = LOAD_REG_L(fetchdat & 7); \
} \
else \
{ \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_L_RELEASE(dst_reg); \
else \
{ \
LOAD_EA(); \
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \
} \
} \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_B(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_W(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_L(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
}
ROP_LOGIC(AND, AND, 1)
ROP_LOGIC(OR, OR, 1)
ROP_LOGIC(XOR, XOR, 1)
static uint32_t ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) == 0xc0)
{
src_reg = LOAD_REG_B(fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_B(target_seg);
src_reg = 0;
}
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
dst_reg = TEST_HOST_REG_B(dst_reg, src_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
return op_pc + 1;
}
static uint32_t ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) == 0xc0)
{
src_reg = LOAD_REG_W(fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_W(target_seg);
src_reg = 0;
}
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
dst_reg = TEST_HOST_REG_W(dst_reg, src_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
return op_pc + 1;
}
static uint32_t ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) == 0xc0)
{
src_reg = LOAD_REG_L(fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_L(target_seg);
src_reg = 0;
}
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
dst_reg = TEST_HOST_REG_L(dst_reg, src_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
return op_pc + 1;
}
static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
AND_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
OR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 1;
}
static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 2;
}
static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 4;
}
static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
XOR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
uint8_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST b,#8*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_B(fetchdat & 7);
imm = (fetchdat >> 8) & 0xff;
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadb(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_B(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 2;
case 0x10: /*NOT b*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xff);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG b*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
host_reg = LOAD_REG_B(fetchdat & 7);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, host_reg);
NEG_HOST_REG_B(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0);
STORE_REG_B_RELEASE(host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
return op_pc + 1;
}
return 0;
}
static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
uint16_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST w,#*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_W(fetchdat & 7);
imm = (fetchdat >> 8) & 0xffff;
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadw(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_W(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 3;
case 0x10: /*NOT w*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xffff);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG w*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
host_reg = LOAD_REG_W(fetchdat & 7);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, host_reg);
NEG_HOST_REG_W(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0);
STORE_REG_W_RELEASE(host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
return op_pc + 1;
}
return 0;
}
static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
int host_reg;
uint32_t imm;
switch (fetchdat & 0x38)
{
case 0x00: /*TEST l,#*/
if ((fetchdat & 0xc0) == 0xc0)
{
host_reg = LOAD_REG_L(fetchdat & 7);
imm = fastreadl(cs + op_pc + 1);
}
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
imm = fastreadl(cs + op_pc + 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_EA_L(target_seg);
host_reg = 0;
}
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 5;
case 0x10: /*NOT l*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_L(fetchdat & 7);
XOR_HOST_REG_IMM(host_reg, 0xffffffff);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 1;
case 0x18: /*NEG l*/
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
host_reg = LOAD_REG_L(fetchdat & 7);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, host_reg);
NEG_HOST_REG_L(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0);
STORE_REG_L_RELEASE(host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
return op_pc + 1;
}
return 0;
}

View file

@ -1,269 +0,0 @@
static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
return op_pc;
}
static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
CLEAR_BITS((uintptr_t)&flags, D_FLAG);
return op_pc;
}
static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
SET_BITS((uintptr_t)&flags, D_FLAG);
return op_pc;
}
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
return 0;
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
return op_pc;
}
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
return 0;
SET_BITS((uintptr_t)&flags, I_FLAG);
return op_pc;
}
static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00)
return 0;
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_B(fetchdat & 7);
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
SAVE_EA();
MEM_CHECK_WRITE(target_seg);
host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg);
}
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
break;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
break;
}
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_B_RELEASE(host_reg);
else
{
LOAD_EA();
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg);
}
codegen_flags_changed = 1;
return op_pc + 1;
}
static uint32_t codegen_temp;
static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
return 0;
if ((fetchdat & 0x30) == 0x00)
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_W(fetchdat & 7);
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
if ((fetchdat & 0x30) != 0x00)
{
MEM_LOAD_ADDR_EA_W(target_seg);
host_reg = 0;
}
else
{
SAVE_EA();
MEM_CHECK_WRITE_W(target_seg);
host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg);
}
}
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_W_RELEASE(host_reg);
else
{
LOAD_EA();
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
}
codegen_flags_changed = 1;
return op_pc + 1;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_W_RELEASE(host_reg);
else
{
LOAD_EA();
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
}
codegen_flags_changed = 1;
return op_pc + 1;
case 0x10: /*CALL*/
STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg);
RELEASE_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(op_pc + 1);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp);
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg);
return -1;
case 0x20: /*JMP*/
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
return -1;
case 0x30: /*PUSH*/
if (!host_reg)
host_reg = LOAD_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
return op_pc + 1;
}
return 0;
}
static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
return 0;
if ((fetchdat & 0x30) == 0x00)
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_L(fetchdat & 7);
else
{
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
if ((fetchdat & 0x30) != 0x00)
{
MEM_LOAD_ADDR_EA_L(target_seg);
host_reg = 0;
}
else
{
SAVE_EA();
MEM_CHECK_WRITE_L(target_seg);
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
}
}
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_L_RELEASE(host_reg);
else
{
LOAD_EA();
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
}
codegen_flags_changed = 1;
return op_pc + 1;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_L_RELEASE(host_reg);
else
{
LOAD_EA();
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
}
codegen_flags_changed = 1;
return op_pc + 1;
case 0x10: /*CALL*/
STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg);
RELEASE_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(op_pc + 1);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
return -1;
case 0x20: /*JMP*/
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
return -1;
case 0x30: /*PUSH*/
if (!host_reg)
host_reg = LOAD_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
return op_pc + 1;
}
return 0;
}

View file

@ -1,277 +0,0 @@
static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg1, host_reg2;
MMX_ENTER();
LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 7);
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
}
return op_pc + 1;
}
static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
MMX_ENTER();
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg1, host_reg2;
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_Q(target_seg);
STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2);
}
return op_pc + 1;
}
static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
MMX_ENTER();
host_reg = LOAD_MMX_D((fetchdat >> 3) & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 3);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
}
return op_pc + 1;
}
static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
MMX_ENTER();
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_L(fetchdat & 7);
STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
STORE_MMX_LQ((fetchdat >> 3) & 7, 0);
}
return op_pc + 1;
}
#define MMX_OP(name, func) \
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg1, src_reg2; \
int xmm_src, xmm_dst; \
\
MMX_ENTER(); \
\
if ((fetchdat & 0xc0) == 0xc0) \
{ \
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
\
MEM_LOAD_ADDR_EA_Q(target_seg); \
src_reg1 = LOAD_Q_REG_1; \
src_reg2 = LOAD_Q_REG_2; \
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
} \
xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \
func(xmm_dst, xmm_src); \
STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \
\
return op_pc + 1; \
}
MMX_OP(ropPAND, MMX_AND)
MMX_OP(ropPANDN, MMX_ANDN)
MMX_OP(ropPOR, MMX_OR)
MMX_OP(ropPXOR, MMX_XOR)
MMX_OP(ropPADDB, MMX_ADDB)
MMX_OP(ropPADDW, MMX_ADDW)
MMX_OP(ropPADDD, MMX_ADDD)
MMX_OP(ropPADDSB, MMX_ADDSB)
MMX_OP(ropPADDSW, MMX_ADDSW)
MMX_OP(ropPADDUSB, MMX_ADDUSB)
MMX_OP(ropPADDUSW, MMX_ADDUSW)
MMX_OP(ropPSUBB, MMX_SUBB)
MMX_OP(ropPSUBW, MMX_SUBW)
MMX_OP(ropPSUBD, MMX_SUBD)
MMX_OP(ropPSUBSB, MMX_SUBSB)
MMX_OP(ropPSUBSW, MMX_SUBSW)
MMX_OP(ropPSUBUSB, MMX_SUBUSB)
MMX_OP(ropPSUBUSW, MMX_SUBUSW)
MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW);
MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD);
MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ);
MMX_OP(ropPACKSSWB, MMX_PACKSSWB);
MMX_OP(ropPCMPGTB, MMX_PCMPGTB);
MMX_OP(ropPCMPGTW, MMX_PCMPGTW);
MMX_OP(ropPCMPGTD, MMX_PCMPGTD);
MMX_OP(ropPACKUSWB, MMX_PACKUSWB);
MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW);
MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD);
MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ);
MMX_OP(ropPACKSSDW, MMX_PACKSSDW);
MMX_OP(ropPCMPEQB, MMX_PCMPEQB);
MMX_OP(ropPCMPEQW, MMX_PCMPEQW);
MMX_OP(ropPCMPEQD, MMX_PCMPEQD);
MMX_OP(ropPSRLW, MMX_PSRLW)
MMX_OP(ropPSRLD, MMX_PSRLD)
MMX_OP(ropPSRLQ, MMX_PSRLQ)
MMX_OP(ropPSRAW, MMX_PSRAW)
MMX_OP(ropPSRAD, MMX_PSRAD)
MMX_OP(ropPSLLW, MMX_PSLLW)
MMX_OP(ropPSLLD, MMX_PSLLD)
MMX_OP(ropPSLLQ, MMX_PSLLQ)
MMX_OP(ropPMULLW, MMX_PMULLW);
MMX_OP(ropPMULHW, MMX_PMULHW);
MMX_OP(ropPMADDWD, MMX_PMADDWD);
static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int xmm_dst;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
return 0;
MMX_ENTER();
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
switch (fetchdat & 0x38)
{
case 0x10: /*PSRLW*/
MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x20: /*PSRAW*/
MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x30: /*PSLLW*/
MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
}
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
return op_pc + 2;
}
static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int xmm_dst;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
return 0;
MMX_ENTER();
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
switch (fetchdat & 0x38)
{
case 0x10: /*PSRLD*/
MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x20: /*PSRAD*/
MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x30: /*PSLLD*/
MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
}
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
return op_pc + 2;
}
static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int xmm_dst;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
return 0;
MMX_ENTER();
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
switch (fetchdat & 0x38)
{
case 0x10: /*PSRLQ*/
MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x20: /*PSRAQ*/
MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
case 0x30: /*PSLLQ*/
MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
break;
}
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
return op_pc + 2;
}
static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
codegen_mmx_entered = 0;
return 0;
}

View file

@ -1,656 +0,0 @@
static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff);
return op_pc + 1;
}
static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff);
return op_pc + 2;
}
static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
fetchdat = fastreadl(cs + op_pc);
STORE_IMM_REG_L(opcode & 7, fetchdat);
return op_pc + 4;
}
static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B((fetchdat >> 3) & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 0);
MEM_STORE_ADDR_EA_B(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 1;
}
static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W((fetchdat >> 3) & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 1);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 1;
}
static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
host_reg = LOAD_REG_L((fetchdat >> 3) & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 3);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 1;
}
static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_W(fetchdat & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_L(fetchdat & 7);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadb(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_B(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 2;
}
static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadw(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 3;
}
static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
uint32_t imm = fastreadl(cs + op_pc + 1);
STORE_IMM_REG_L(fetchdat & 7, imm);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadl(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 5;
}
static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr);
STORE_REG_TARGET_B_RELEASE(0, REG_AL);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr);
STORE_REG_TARGET_W_RELEASE(0, REG_AX);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr);
STORE_REG_TARGET_L_RELEASE(0, REG_EAX);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
host_reg = LOAD_REG_B(REG_AL);
MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
host_reg = LOAD_REG_W(REG_AX);
MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
host_reg = LOAD_REG_L(REG_EAX);
MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) == 0xc0)
return 0;
FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_REG_TARGET_W_RELEASE(0, dest_reg);
return op_pc + 1;
}
static uint32_t ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) == 0xc0)
return 0;
FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_REG_TARGET_L_RELEASE(0, dest_reg);
return op_pc + 1;
}
static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
host_reg = ZERO_EXTEND_W_B(host_reg);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
ZERO_EXTEND_W_B(0);
STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
host_reg = ZERO_EXTEND_L_B(host_reg);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
ZERO_EXTEND_L_B(0);
STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_W(fetchdat & 7);
host_reg = ZERO_EXTEND_L_W(host_reg);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
ZERO_EXTEND_L_W(0);
STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
host_reg = SIGN_EXTEND_W_B(host_reg);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
SIGN_EXTEND_W_B(0);
STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
host_reg = SIGN_EXTEND_L_B(host_reg);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
SIGN_EXTEND_L_B(0);
STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_W(fetchdat & 7);
host_reg = SIGN_EXTEND_L_W(host_reg);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
SIGN_EXTEND_L_W(0);
STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7);
}
return op_pc + 1;
}
static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
switch (fetchdat & 0x38)
{
case 0x00: /*ES*/
host_reg = LOAD_VAR_WL((uintptr_t)&ES);
break;
case 0x08: /*CS*/
host_reg = LOAD_VAR_WL((uintptr_t)&CS);
break;
case 0x18: /*DS*/
host_reg = LOAD_VAR_WL((uintptr_t)&DS);
break;
case 0x10: /*SS*/
host_reg = LOAD_VAR_WL((uintptr_t)&SS);
break;
case 0x20: /*FS*/
host_reg = LOAD_VAR_WL((uintptr_t)&FS);
break;
case 0x28: /*GS*/
host_reg = LOAD_VAR_WL((uintptr_t)&GS);
break;
default:
return 0;
}
if ((fetchdat & 0xc0) == 0xc0)
{
if (op_32 & 0x100)
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
else
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 1);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 1;
}
static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
switch (fetchdat & 0x38)
{
case 0x00: /*ES*/
case 0x18: /*DS*/
case 0x20: /*FS*/
case 0x28: /*GS*/
break;
case 0x10: /*SS*/
default:
return 0;
}
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_W(fetchdat & 7);
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
host_reg = 0;
}
switch (fetchdat & 0x38)
{
case 0x00: /*ES*/
LOAD_SEG(host_reg, &_es);
break;
case 0x18: /*DS*/
LOAD_SEG(host_reg, &_ds);
break;
case 0x20: /*FS*/
LOAD_SEG(host_reg, &_fs);
break;
case 0x28: /*GS*/
LOAD_SEG(host_reg, &_gs);
break;
}
return op_pc + 1;
}
#define ropLseg(seg, rseg) \
static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int dest_reg = (fetchdat >> 3) & 7; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) \
return 0; \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
SAVE_EA(); \
\
if (op_32 & 0x100) \
{ \
MEM_LOAD_ADDR_EA_L(target_seg); \
STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \
} \
else \
{ \
MEM_LOAD_ADDR_EA_W(target_seg); \
STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \
LOAD_EA(); \
MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \
} \
LOAD_SEG(0, &rseg); \
if (op_32 & 0x100) \
{ \
\
int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \
STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \
} \
else \
{ \
int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \
STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \
} \
\
if (&rseg == &_ss) \
CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \
return op_pc + 1; \
}
ropLseg(DS, _ds)
ropLseg(ES, _es)
ropLseg(FS, _fs)
ropLseg(GS, _gs)
ropLseg(SS, _ss)

View file

@ -1,125 +0,0 @@
#define SHIFT(size, size2, res_store, immediate) \
if ((fetchdat & 0xc0) == 0xc0) \
{ \
reg = LOAD_REG_ ## size(fetchdat & 7); \
if (immediate) count = (fetchdat >> 8) & 0x1f; \
} \
else \
{ \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_ ## size(target_seg); \
reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \
if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \
} \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \
\
res_store((uintptr_t)&cpu_state.flags_op1, reg); \
\
switch (fetchdat & 0x38) \
{ \
case 0x20: case 0x30: /*SHL*/ \
SHL_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \
break; \
\
case 0x28: /*SHR*/ \
SHR_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \
break; \
\
case 0x38: /*SAR*/ \
SAR_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \
break; \
} \
\
res_store((uintptr_t)&cpu_state.flags_res, reg); \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_ ## size ## _RELEASE(reg); \
else \
{ \
LOAD_EA(); \
MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \
}
static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);
return op_pc + 2;
}
static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);
return op_pc + 2;
}
static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);
return op_pc + 2;
}
static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count = 1;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);
return op_pc + 1;
}
static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count = 1;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);
return op_pc + 1;
}
static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg = NULL;
int count = 1;
int reg;
if ((fetchdat & 0x38) < 0x20)
return 0;
SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);
return op_pc + 1;
}

View file

@ -1,269 +0,0 @@
static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_W(opcode & 7);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
return op_pc;
}
static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_L(opcode & 7);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
return op_pc;
}
static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t imm = fetchdat & 0xffff;
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
return op_pc+2;
}
static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t imm = fastreadl(cs + op_pc);
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
return op_pc+4;
}
static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t imm = fetchdat & 0xff;
int host_reg;
if (imm & 0x80)
imm |= 0xff00;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
return op_pc+1;
}
static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t imm = fetchdat & 0xff;
int host_reg;
if (imm & 0x80)
imm |= 0xffffff00;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(imm);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
return op_pc+1;
}
static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
SP_MODIFY(2);
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
return op_pc;
}
static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
SP_MODIFY(4);
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
return op_pc;
}
static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(2);
return -1;
}
static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(4);
return -1;
}
static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(2+offset);
return -1;
}
static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
SP_MODIFY(4+offset);
return -1;
}
static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-2);
host_reg = LOAD_REG_IMM(op_pc+2);
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
SP_MODIFY(-2);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
return -1;
}
static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t offset = fastreadl(cs + op_pc);
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(-4);
host_reg = LOAD_REG_IMM(op_pc+4);
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
SP_MODIFY(-4);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
return -1;
}
static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
ADD_HOST_REG_IMM_W(host_reg, 2);
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
return op_pc;
}
static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
ADD_HOST_REG_IMM(host_reg, 4);
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
return op_pc;
}
#define ROP_PUSH_SEG(seg) \
static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-2); \
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
MEM_STORE_ADDR_EA_W(&_ss, host_reg); \
SP_MODIFY(-2); \
\
return op_pc; \
} \
static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-4); \
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
MEM_STORE_ADDR_EA_L(&_ss, host_reg); \
SP_MODIFY(-4); \
\
return op_pc; \
}
ROP_PUSH_SEG(CS)
ROP_PUSH_SEG(DS)
ROP_PUSH_SEG(ES)
ROP_PUSH_SEG(FS)
ROP_PUSH_SEG(GS)
ROP_PUSH_SEG(SS)
#define ROP_POP_SEG(seg, rseg) \
static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(2); \
\
return op_pc; \
} \
static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(4); \
\
return op_pc; \
}
ROP_POP_SEG(DS, _ds)
ROP_POP_SEG(ES, _es)
ROP_POP_SEG(FS, _fs)
ROP_POP_SEG(GS, _gs)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,93 +0,0 @@
#define OP_XCHG_AX_(reg) \
static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int ax_reg, host_reg, temp_reg; \
\
ax_reg = LOAD_REG_W(REG_AX); \
host_reg = LOAD_REG_W(REG_ ## reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
\
return op_pc; \
}
OP_XCHG_AX_(BX)
OP_XCHG_AX_(CX)
OP_XCHG_AX_(DX)
OP_XCHG_AX_(SI)
OP_XCHG_AX_(DI)
OP_XCHG_AX_(SP)
OP_XCHG_AX_(BP)
#define OP_XCHG_EAX_(reg) \
static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int eax_reg, host_reg, temp_reg; \
\
eax_reg = LOAD_REG_L(REG_EAX); \
host_reg = LOAD_REG_L(REG_ ## reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
\
return op_pc; \
}
OP_XCHG_EAX_(EBX)
OP_XCHG_EAX_(ECX)
OP_XCHG_EAX_(EDX)
OP_XCHG_EAX_(ESI)
OP_XCHG_EAX_(EDI)
OP_XCHG_EAX_(ESP)
OP_XCHG_EAX_(EBP)
static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
#ifdef __amd64__
return 0;
#else
int src_reg, dst_reg, temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_B(fetchdat & 7);
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
temp_reg = COPY_REG(src_reg);
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
return op_pc + 1;
#endif
}
static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg, temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_W(fetchdat & 7);
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
temp_reg = COPY_REG(src_reg);
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg, temp_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_L(fetchdat & 7);
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
temp_reg = COPY_REG(src_reg);
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
return op_pc + 1;
}

File diff suppressed because it is too large Load diff

View file

@ -1,42 +0,0 @@
#define BLOCK_SIZE 0x4000
#define BLOCK_MASK 0x3fff
#define BLOCK_START 0
#define HASH_SIZE 0x20000
#define HASH_MASK 0x1ffff
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_EXIT_OFFSET 0x7f0
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
#define BLOCK_MAX 1720
enum
{
OP_RET = 0xc3
};
#define NR_HOST_REGS 4
extern int host_reg_mapping[NR_HOST_REGS];
#define NR_HOST_XMM_REGS 7
extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS];
extern uint32_t mem_load_addr_ea_b;
extern uint32_t mem_load_addr_ea_w;
extern uint32_t mem_load_addr_ea_l;
extern uint32_t mem_load_addr_ea_q;
extern uint32_t mem_store_addr_ea_b;
extern uint32_t mem_store_addr_ea_w;
extern uint32_t mem_store_addr_ea_l;
extern uint32_t mem_store_addr_ea_q;
extern uint32_t mem_load_addr_ea_b_no_abrt;
extern uint32_t mem_store_addr_ea_b_no_abrt;
extern uint32_t mem_load_addr_ea_w_no_abrt;
extern uint32_t mem_store_addr_ea_w_no_abrt;
extern uint32_t mem_load_addr_ea_l_no_abrt;
extern uint32_t mem_store_addr_ea_l_no_abrt;
extern uint32_t mem_check_write;
extern uint32_t mem_check_write_w;
extern uint32_t mem_check_write_l;

View file

@ -12,6 +12,7 @@
#include <wx/wfstream.h>
#include <wx/progdlg.h>
#include <wx/choicebk.h>
#include <wx/combobox.h>
#include "wx-dialogbox.h"
#include "wx-app.h"