Search
lxdream.org :: lxdream :: r539:75f3e594d4a7
lxdream 0.9.1
released Jun 29
Download Now
changeset539:75f3e594d4a7
parent538:7f176617a968
child540:a3767018a96d
authornkeynes
dateWed Nov 21 11:40:15 2007 +0000 (12 years ago)
Add support for the darwin ABI
config.h.in
configure
configure.in
src/Makefile.am
src/Makefile.in
src/sh4/ia32abi.h
src/sh4/ia32mac.h
src/sh4/ia64abi.h
src/sh4/sh4x86.c
src/sh4/sh4x86.in
src/sh4/x86op.h
1.1 --- a/config.h.in Tue Nov 20 11:16:09 2007 +0000
1.2 +++ b/config.h.in Wed Nov 21 11:40:15 2007 +0000
1.3 @@ -7,6 +7,9 @@
1.4 #undef HAVE_STPCPY
1.5 #undef HAVE_LIBSM
1.6
1.7 +/* Building on an apple platform. Things are different... */
1.8 +#undef APPLE_BUILD
1.9 +
1.10 /* always defined to indicate that i18n is enabled */
1.11 #undef ENABLE_NLS
1.12
1.13 @@ -16,6 +19,9 @@
1.14 /* Define to 1 if you have the `bind_textdomain_codeset' function. */
1.15 #undef HAVE_BIND_TEXTDOMAIN_CODESET
1.16
1.17 +/* Have Carbon framework */
1.18 +#undef HAVE_CARBON
1.19 +
1.20 /* Define to 1 if you have the `dcgettext' function. */
1.21 #undef HAVE_DCGETTEXT
1.22
1.23 @@ -25,6 +31,9 @@
1.24 /* Define if the GNU gettext() function is already present or preinstalled. */
1.25 #undef HAVE_GETTEXT
1.26
1.27 +/* Have GTK libraries */
1.28 +#undef HAVE_GTK
1.29 +
1.30 /* Define to 1 if you have the <inttypes.h> header file. */
1.31 #undef HAVE_INTTYPES_H
1.32
2.1 --- a/configure Tue Nov 20 11:16:09 2007 +0000
2.2 +++ b/configure Wed Nov 21 11:40:15 2007 +0000
2.3 @@ -703,6 +703,8 @@
2.4 LIBPNG_LIBS
2.5 GTK_CFLAGS
2.6 GTK_LIBS
2.7 +GUI_CARBON_TRUE
2.8 +GUI_CARBON_FALSE
2.9 GUI_GTK_TRUE
2.10 GUI_GTK_FALSE
2.11 BUILD_SH4X86_TRUE
2.12 @@ -4942,6 +4944,220 @@
2.13
2.14
2.15
2.16 +# On IRIX 5.3, sys/types and inttypes.h are conflicting.
2.17 +
2.18 +
2.19 +
2.20 +
2.21 +
2.22 +
2.23 +
2.24 +
2.25 +
2.26 +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
2.27 + inttypes.h stdint.h unistd.h
2.28 +do
2.29 +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
2.30 +{ echo "$as_me:$LINENO: checking for $ac_header" >&5
2.31 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
2.32 +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
2.33 + echo $ECHO_N "(cached) $ECHO_C" >&6
2.34 +else
2.35 + cat >conftest.$ac_ext <<_ACEOF
2.36 +/* confdefs.h. */
2.37 +_ACEOF
2.38 +cat confdefs.h >>conftest.$ac_ext
2.39 +cat >>conftest.$ac_ext <<_ACEOF
2.40 +/* end confdefs.h. */
2.41 +$ac_includes_default
2.42 +
2.43 +#include <$ac_header>
2.44 +_ACEOF
2.45 +rm -f conftest.$ac_objext
2.46 +if { (ac_try="$ac_compile"
2.47 +case "(($ac_try" in
2.48 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.49 + *) ac_try_echo=$ac_try;;
2.50 +esac
2.51 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.52 + (eval "$ac_compile") 2>conftest.er1
2.53 + ac_status=$?
2.54 + grep -v '^ *+' conftest.er1 >conftest.err
2.55 + rm -f conftest.er1
2.56 + cat conftest.err >&5
2.57 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.58 + (exit $ac_status); } && {
2.59 + test -z "$ac_c_werror_flag" ||
2.60 + test ! -s conftest.err
2.61 + } && test -s conftest.$ac_objext; then
2.62 + eval "$as_ac_Header=yes"
2.63 +else
2.64 + echo "$as_me: failed program was:" >&5
2.65 +sed 's/^/| /' conftest.$ac_ext >&5
2.66 +
2.67 + eval "$as_ac_Header=no"
2.68 +fi
2.69 +
2.70 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2.71 +fi
2.72 +ac_res=`eval echo '${'$as_ac_Header'}'`
2.73 + { echo "$as_me:$LINENO: result: $ac_res" >&5
2.74 +echo "${ECHO_T}$ac_res" >&6; }
2.75 +if test `eval echo '${'$as_ac_Header'}'` = yes; then
2.76 + cat >>confdefs.h <<_ACEOF
2.77 +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
2.78 +_ACEOF
2.79 +
2.80 +fi
2.81 +
2.82 +done
2.83 +
2.84 +
2.85 +if test "${ac_cv_header_Carbon_Carbon_h+set}" = set; then
2.86 + { echo "$as_me:$LINENO: checking for Carbon/Carbon.h" >&5
2.87 +echo $ECHO_N "checking for Carbon/Carbon.h... $ECHO_C" >&6; }
2.88 +if test "${ac_cv_header_Carbon_Carbon_h+set}" = set; then
2.89 + echo $ECHO_N "(cached) $ECHO_C" >&6
2.90 +fi
2.91 +{ echo "$as_me:$LINENO: result: $ac_cv_header_Carbon_Carbon_h" >&5
2.92 +echo "${ECHO_T}$ac_cv_header_Carbon_Carbon_h" >&6; }
2.93 +else
2.94 + # Is the header compilable?
2.95 +{ echo "$as_me:$LINENO: checking Carbon/Carbon.h usability" >&5
2.96 +echo $ECHO_N "checking Carbon/Carbon.h usability... $ECHO_C" >&6; }
2.97 +cat >conftest.$ac_ext <<_ACEOF
2.98 +/* confdefs.h. */
2.99 +_ACEOF
2.100 +cat confdefs.h >>conftest.$ac_ext
2.101 +cat >>conftest.$ac_ext <<_ACEOF
2.102 +/* end confdefs.h. */
2.103 +$ac_includes_default
2.104 +#include <Carbon/Carbon.h>
2.105 +_ACEOF
2.106 +rm -f conftest.$ac_objext
2.107 +if { (ac_try="$ac_compile"
2.108 +case "(($ac_try" in
2.109 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.110 + *) ac_try_echo=$ac_try;;
2.111 +esac
2.112 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.113 + (eval "$ac_compile") 2>conftest.er1
2.114 + ac_status=$?
2.115 + grep -v '^ *+' conftest.er1 >conftest.err
2.116 + rm -f conftest.er1
2.117 + cat conftest.err >&5
2.118 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.119 + (exit $ac_status); } && {
2.120 + test -z "$ac_c_werror_flag" ||
2.121 + test ! -s conftest.err
2.122 + } && test -s conftest.$ac_objext; then
2.123 + ac_header_compiler=yes
2.124 +else
2.125 + echo "$as_me: failed program was:" >&5
2.126 +sed 's/^/| /' conftest.$ac_ext >&5
2.127 +
2.128 + ac_header_compiler=no
2.129 +fi
2.130 +
2.131 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2.132 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
2.133 +echo "${ECHO_T}$ac_header_compiler" >&6; }
2.134 +
2.135 +# Is the header present?
2.136 +{ echo "$as_me:$LINENO: checking Carbon/Carbon.h presence" >&5
2.137 +echo $ECHO_N "checking Carbon/Carbon.h presence... $ECHO_C" >&6; }
2.138 +cat >conftest.$ac_ext <<_ACEOF
2.139 +/* confdefs.h. */
2.140 +_ACEOF
2.141 +cat confdefs.h >>conftest.$ac_ext
2.142 +cat >>conftest.$ac_ext <<_ACEOF
2.143 +/* end confdefs.h. */
2.144 +#include <Carbon/Carbon.h>
2.145 +_ACEOF
2.146 +if { (ac_try="$ac_cpp conftest.$ac_ext"
2.147 +case "(($ac_try" in
2.148 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.149 + *) ac_try_echo=$ac_try;;
2.150 +esac
2.151 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.152 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
2.153 + ac_status=$?
2.154 + grep -v '^ *+' conftest.er1 >conftest.err
2.155 + rm -f conftest.er1
2.156 + cat conftest.err >&5
2.157 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.158 + (exit $ac_status); } >/dev/null && {
2.159 + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
2.160 + test ! -s conftest.err
2.161 + }; then
2.162 + ac_header_preproc=yes
2.163 +else
2.164 + echo "$as_me: failed program was:" >&5
2.165 +sed 's/^/| /' conftest.$ac_ext >&5
2.166 +
2.167 + ac_header_preproc=no
2.168 +fi
2.169 +
2.170 +rm -f conftest.err conftest.$ac_ext
2.171 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
2.172 +echo "${ECHO_T}$ac_header_preproc" >&6; }
2.173 +
2.174 +# So? What about this header?
2.175 +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
2.176 + yes:no: )
2.177 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: accepted by the compiler, rejected by the preprocessor!" >&5
2.178 +echo "$as_me: WARNING: Carbon/Carbon.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
2.179 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: proceeding with the compiler's result" >&5
2.180 +echo "$as_me: WARNING: Carbon/Carbon.h: proceeding with the compiler's result" >&2;}
2.181 + ac_header_preproc=yes
2.182 + ;;
2.183 + no:yes:* )
2.184 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: present but cannot be compiled" >&5
2.185 +echo "$as_me: WARNING: Carbon/Carbon.h: present but cannot be compiled" >&2;}
2.186 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: check for missing prerequisite headers?" >&5
2.187 +echo "$as_me: WARNING: Carbon/Carbon.h: check for missing prerequisite headers?" >&2;}
2.188 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: see the Autoconf documentation" >&5
2.189 +echo "$as_me: WARNING: Carbon/Carbon.h: see the Autoconf documentation" >&2;}
2.190 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: section \"Present But Cannot Be Compiled\"" >&5
2.191 +echo "$as_me: WARNING: Carbon/Carbon.h: section \"Present But Cannot Be Compiled\"" >&2;}
2.192 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: proceeding with the preprocessor's result" >&5
2.193 +echo "$as_me: WARNING: Carbon/Carbon.h: proceeding with the preprocessor's result" >&2;}
2.194 + { echo "$as_me:$LINENO: WARNING: Carbon/Carbon.h: in the future, the compiler will take precedence" >&5
2.195 +echo "$as_me: WARNING: Carbon/Carbon.h: in the future, the compiler will take precedence" >&2;}
2.196 +
2.197 + ;;
2.198 +esac
2.199 +{ echo "$as_me:$LINENO: checking for Carbon/Carbon.h" >&5
2.200 +echo $ECHO_N "checking for Carbon/Carbon.h... $ECHO_C" >&6; }
2.201 +if test "${ac_cv_header_Carbon_Carbon_h+set}" = set; then
2.202 + echo $ECHO_N "(cached) $ECHO_C" >&6
2.203 +else
2.204 + ac_cv_header_Carbon_Carbon_h=$ac_header_preproc
2.205 +fi
2.206 +{ echo "$as_me:$LINENO: result: $ac_cv_header_Carbon_Carbon_h" >&5
2.207 +echo "${ECHO_T}$ac_cv_header_Carbon_Carbon_h" >&6; }
2.208 +
2.209 +fi
2.210 +if test $ac_cv_header_Carbon_Carbon_h = yes; then
2.211 +
2.212 + HAVE_CARBON='yes'
2.213 + APPLE_BUILD='yes'
2.214 + LIBS="$LIBS -framework OpenGL -framework AGL -framework Carbon"
2.215 +
2.216 +cat >>confdefs.h <<\_ACEOF
2.217 +#define HAVE_CARBON 1
2.218 +_ACEOF
2.219 +
2.220 +
2.221 +cat >>confdefs.h <<\_ACEOF
2.222 +#define APPLE_BUILD 1
2.223 +_ACEOF
2.224 +
2.225 +
2.226 +fi
2.227 +
2.228 +
2.229 +
2.230
2.231
2.232 if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
2.233 @@ -5175,6 +5391,83 @@
2.234 fi
2.235
2.236
2.237 +{ echo "$as_me:$LINENO: checking for uncompress in -lz" >&5
2.238 +echo $ECHO_N "checking for uncompress in -lz... $ECHO_C" >&6; }
2.239 +if test "${ac_cv_lib_z_uncompress+set}" = set; then
2.240 + echo $ECHO_N "(cached) $ECHO_C" >&6
2.241 +else
2.242 + ac_check_lib_save_LIBS=$LIBS
2.243 +LIBS="-lz $LIBS"
2.244 +cat >conftest.$ac_ext <<_ACEOF
2.245 +/* confdefs.h. */
2.246 +_ACEOF
2.247 +cat confdefs.h >>conftest.$ac_ext
2.248 +cat >>conftest.$ac_ext <<_ACEOF
2.249 +/* end confdefs.h. */
2.250 +
2.251 +/* Override any GCC internal prototype to avoid an error.
2.252 + Use char because int might match the return type of a GCC
2.253 + builtin and then its argument prototype would still apply. */
2.254 +#ifdef __cplusplus
2.255 +extern "C"
2.256 +#endif
2.257 +char uncompress ();
2.258 +int
2.259 +main ()
2.260 +{
2.261 +return uncompress ();
2.262 + ;
2.263 + return 0;
2.264 +}
2.265 +_ACEOF
2.266 +rm -f conftest.$ac_objext conftest$ac_exeext
2.267 +if { (ac_try="$ac_link"
2.268 +case "(($ac_try" in
2.269 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.270 + *) ac_try_echo=$ac_try;;
2.271 +esac
2.272 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.273 + (eval "$ac_link") 2>conftest.er1
2.274 + ac_status=$?
2.275 + grep -v '^ *+' conftest.er1 >conftest.err
2.276 + rm -f conftest.er1
2.277 + cat conftest.err >&5
2.278 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.279 + (exit $ac_status); } && {
2.280 + test -z "$ac_c_werror_flag" ||
2.281 + test ! -s conftest.err
2.282 + } && test -s conftest$ac_exeext &&
2.283 + $as_test_x conftest$ac_exeext; then
2.284 + ac_cv_lib_z_uncompress=yes
2.285 +else
2.286 + echo "$as_me: failed program was:" >&5
2.287 +sed 's/^/| /' conftest.$ac_ext >&5
2.288 +
2.289 + ac_cv_lib_z_uncompress=no
2.290 +fi
2.291 +
2.292 +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
2.293 + conftest$ac_exeext conftest.$ac_ext
2.294 +LIBS=$ac_check_lib_save_LIBS
2.295 +fi
2.296 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_uncompress" >&5
2.297 +echo "${ECHO_T}$ac_cv_lib_z_uncompress" >&6; }
2.298 +if test $ac_cv_lib_z_uncompress = yes; then
2.299 + cat >>confdefs.h <<_ACEOF
2.300 +#define HAVE_LIBZ 1
2.301 +_ACEOF
2.302 +
2.303 + LIBS="-lz $LIBS"
2.304 +
2.305 +else
2.306 +
2.307 + echo "Zlib (libz.so) could not be found, but is required."
2.308 + exit 1
2.309 +fi
2.310 +
2.311 +
2.312 +if test "$APPLE_BUILD" != 'yes'; then
2.313 +
2.314 { echo "$as_me:$LINENO: checking for glXQueryVersion in -lGL" >&5
2.315 echo $ECHO_N "checking for glXQueryVersion in -lGL... $ECHO_C" >&6; }
2.316 if test "${ac_cv_lib_GL_glXQueryVersion+set}" = set; then
2.317 @@ -5249,75 +5542,6 @@
2.318 exit 1
2.319 fi
2.320
2.321 -# On IRIX 5.3, sys/types and inttypes.h are conflicting.
2.322 -
2.323 -
2.324 -
2.325 -
2.326 -
2.327 -
2.328 -
2.329 -
2.330 -
2.331 -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
2.332 - inttypes.h stdint.h unistd.h
2.333 -do
2.334 -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
2.335 -{ echo "$as_me:$LINENO: checking for $ac_header" >&5
2.336 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
2.337 -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
2.338 - echo $ECHO_N "(cached) $ECHO_C" >&6
2.339 -else
2.340 - cat >conftest.$ac_ext <<_ACEOF
2.341 -/* confdefs.h. */
2.342 -_ACEOF
2.343 -cat confdefs.h >>conftest.$ac_ext
2.344 -cat >>conftest.$ac_ext <<_ACEOF
2.345 -/* end confdefs.h. */
2.346 -$ac_includes_default
2.347 -
2.348 -#include <$ac_header>
2.349 -_ACEOF
2.350 -rm -f conftest.$ac_objext
2.351 -if { (ac_try="$ac_compile"
2.352 -case "(($ac_try" in
2.353 - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.354 - *) ac_try_echo=$ac_try;;
2.355 -esac
2.356 -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.357 - (eval "$ac_compile") 2>conftest.er1
2.358 - ac_status=$?
2.359 - grep -v '^ *+' conftest.er1 >conftest.err
2.360 - rm -f conftest.er1
2.361 - cat conftest.err >&5
2.362 - echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.363 - (exit $ac_status); } && {
2.364 - test -z "$ac_c_werror_flag" ||
2.365 - test ! -s conftest.err
2.366 - } && test -s conftest.$ac_objext; then
2.367 - eval "$as_ac_Header=yes"
2.368 -else
2.369 - echo "$as_me: failed program was:" >&5
2.370 -sed 's/^/| /' conftest.$ac_ext >&5
2.371 -
2.372 - eval "$as_ac_Header=no"
2.373 -fi
2.374 -
2.375 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2.376 -fi
2.377 -ac_res=`eval echo '${'$as_ac_Header'}'`
2.378 - { echo "$as_me:$LINENO: result: $ac_res" >&5
2.379 -echo "${ECHO_T}$ac_res" >&6; }
2.380 -if test `eval echo '${'$as_ac_Header'}'` = yes; then
2.381 - cat >>confdefs.h <<_ACEOF
2.382 -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
2.383 -_ACEOF
2.384 -
2.385 -fi
2.386 -
2.387 -done
2.388 -
2.389 -
2.390 if test "${ac_cv_header_GL_gl_h+set}" = set; then
2.391 { echo "$as_me:$LINENO: checking for GL/gl.h" >&5
2.392 echo $ECHO_N "checking for GL/gl.h... $ECHO_C" >&6; }
2.393 @@ -5452,81 +5676,7 @@
2.394 fi
2.395
2.396
2.397 -
2.398 -{ echo "$as_me:$LINENO: checking for uncompress in -lz" >&5
2.399 -echo $ECHO_N "checking for uncompress in -lz... $ECHO_C" >&6; }
2.400 -if test "${ac_cv_lib_z_uncompress+set}" = set; then
2.401 - echo $ECHO_N "(cached) $ECHO_C" >&6
2.402 -else
2.403 - ac_check_lib_save_LIBS=$LIBS
2.404 -LIBS="-lz $LIBS"
2.405 -cat >conftest.$ac_ext <<_ACEOF
2.406 -/* confdefs.h. */
2.407 -_ACEOF
2.408 -cat confdefs.h >>conftest.$ac_ext
2.409 -cat >>conftest.$ac_ext <<_ACEOF
2.410 -/* end confdefs.h. */
2.411 -
2.412 -/* Override any GCC internal prototype to avoid an error.
2.413 - Use char because int might match the return type of a GCC
2.414 - builtin and then its argument prototype would still apply. */
2.415 -#ifdef __cplusplus
2.416 -extern "C"
2.417 -#endif
2.418 -char uncompress ();
2.419 -int
2.420 -main ()
2.421 -{
2.422 -return uncompress ();
2.423 - ;
2.424 - return 0;
2.425 -}
2.426 -_ACEOF
2.427 -rm -f conftest.$ac_objext conftest$ac_exeext
2.428 -if { (ac_try="$ac_link"
2.429 -case "(($ac_try" in
2.430 - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
2.431 - *) ac_try_echo=$ac_try;;
2.432 -esac
2.433 -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
2.434 - (eval "$ac_link") 2>conftest.er1
2.435 - ac_status=$?
2.436 - grep -v '^ *+' conftest.er1 >conftest.err
2.437 - rm -f conftest.er1
2.438 - cat conftest.err >&5
2.439 - echo "$as_me:$LINENO: \$? = $ac_status" >&5
2.440 - (exit $ac_status); } && {
2.441 - test -z "$ac_c_werror_flag" ||
2.442 - test ! -s conftest.err
2.443 - } && test -s conftest$ac_exeext &&
2.444 - $as_test_x conftest$ac_exeext; then
2.445 - ac_cv_lib_z_uncompress=yes
2.446 -else
2.447 - echo "$as_me: failed program was:" >&5
2.448 -sed 's/^/| /' conftest.$ac_ext >&5
2.449 -
2.450 - ac_cv_lib_z_uncompress=no
2.451 -fi
2.452 -
2.453 -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
2.454 - conftest$ac_exeext conftest.$ac_ext
2.455 -LIBS=$ac_check_lib_save_LIBS
2.456 -fi
2.457 -{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_uncompress" >&5
2.458 -echo "${ECHO_T}$ac_cv_lib_z_uncompress" >&6; }
2.459 -if test $ac_cv_lib_z_uncompress = yes; then
2.460 - cat >>confdefs.h <<_ACEOF
2.461 -#define HAVE_LIBZ 1
2.462 -_ACEOF
2.463 -
2.464 - LIBS="-lz $LIBS"
2.465 -
2.466 -else
2.467 -
2.468 - echo "Zlib (libz.so) could not be found, but is required."
2.469 - exit 1
2.470 -fi
2.471 -
2.472 +fi
2.473
2.474
2.475 pkg_failed=no
2.476 @@ -5637,8 +5787,26 @@
2.477 GTK_LIBS=$pkg_cv_GTK_LIBS
2.478 { echo "$as_me:$LINENO: result: yes" >&5
2.479 echo "${ECHO_T}yes" >&6; }
2.480 - HAVE_GTK='yes'
2.481 -fi
2.482 +
2.483 + HAVE_GTK='yes'
2.484 +
2.485 +cat >>confdefs.h <<\_ACEOF
2.486 +#define HAVE_GTK 1
2.487 +_ACEOF
2.488 +
2.489 +
2.490 +fi
2.491 +
2.492 +
2.493 +
2.494 +if test "$HAVE_CARBON" = 'yes'; then
2.495 + GUI_CARBON_TRUE=
2.496 + GUI_CARBON_FALSE='#'
2.497 +else
2.498 + GUI_CARBON_TRUE='#'
2.499 + GUI_CARBON_FALSE=
2.500 +fi
2.501 +
2.502
2.503
2.504 if test "$HAVE_GTK" = 'yes'; then
2.505 @@ -7807,6 +7975,13 @@
2.506 Usually this means the macro was only invoked conditionally." >&2;}
2.507 { (exit 1); exit 1; }; }
2.508 fi
2.509 +if test -z "${GUI_CARBON_TRUE}" && test -z "${GUI_CARBON_FALSE}"; then
2.510 + { { echo "$as_me:$LINENO: error: conditional \"GUI_CARBON\" was never defined.
2.511 +Usually this means the macro was only invoked conditionally." >&5
2.512 +echo "$as_me: error: conditional \"GUI_CARBON\" was never defined.
2.513 +Usually this means the macro was only invoked conditionally." >&2;}
2.514 + { (exit 1); exit 1; }; }
2.515 +fi
2.516 if test -z "${GUI_GTK_TRUE}" && test -z "${GUI_GTK_FALSE}"; then
2.517 { { echo "$as_me:$LINENO: error: conditional \"GUI_GTK\" was never defined.
2.518 Usually this means the macro was only invoked conditionally." >&5
2.519 @@ -8475,13 +8650,13 @@
2.520 LIBPNG_LIBS!$LIBPNG_LIBS$ac_delim
2.521 GTK_CFLAGS!$GTK_CFLAGS$ac_delim
2.522 GTK_LIBS!$GTK_LIBS$ac_delim
2.523 +GUI_CARBON_TRUE!$GUI_CARBON_TRUE$ac_delim
2.524 +GUI_CARBON_FALSE!$GUI_CARBON_FALSE$ac_delim
2.525 GUI_GTK_TRUE!$GUI_GTK_TRUE$ac_delim
2.526 GUI_GTK_FALSE!$GUI_GTK_FALSE$ac_delim
2.527 BUILD_SH4X86_TRUE!$BUILD_SH4X86_TRUE$ac_delim
2.528 BUILD_SH4X86_FALSE!$BUILD_SH4X86_FALSE$ac_delim
2.529 ESOUND_CFLAGS!$ESOUND_CFLAGS$ac_delim
2.530 -ESOUND_LIBS!$ESOUND_LIBS$ac_delim
2.531 -AUDIO_ESOUND_TRUE!$AUDIO_ESOUND_TRUE$ac_delim
2.532 _ACEOF
2.533
2.534 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
2.535 @@ -8523,6 +8698,8 @@
2.536 ac_delim='%!_!# '
2.537 for ac_last_try in false false false false false :; do
2.538 cat >conf$$subs.sed <<_ACEOF
2.539 +ESOUND_LIBS!$ESOUND_LIBS$ac_delim
2.540 +AUDIO_ESOUND_TRUE!$AUDIO_ESOUND_TRUE$ac_delim
2.541 AUDIO_ESOUND_FALSE!$AUDIO_ESOUND_FALSE$ac_delim
2.542 CDROM_LINUX_TRUE!$CDROM_LINUX_TRUE$ac_delim
2.543 CDROM_LINUX_FALSE!$CDROM_LINUX_FALSE$ac_delim
2.544 @@ -8556,7 +8733,7 @@
2.545 LTLIBOBJS!$LTLIBOBJS$ac_delim
2.546 _ACEOF
2.547
2.548 - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 31; then
2.549 + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 33; then
2.550 break
2.551 elif $ac_last_try; then
2.552 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
3.1 --- a/configure.in Tue Nov 20 11:16:09 2007 +0000
3.2 +++ b/configure.in Wed Nov 21 11:40:15 2007 +0000
3.3 @@ -13,22 +13,39 @@
3.4 AC_CANONICAL_HOST
3.5
3.6 dnl ----------- Check for mandatory dependencies --------------
3.7 +dnl Building on MAC?
3.8 +AC_CHECK_HEADER([Carbon/Carbon.h], [
3.9 + HAVE_CARBON='yes'
3.10 + APPLE_BUILD='yes'
3.11 + LIBS="$LIBS -framework OpenGL -framework AGL -framework Carbon"
3.12 + AC_DEFINE(HAVE_CARBON,[1],[Have Carbon framework])
3.13 + AC_DEFINE(APPLE_BUILD,[1],[Building on an apple platform. Things are different...])
3.14 +])
3.15 +
3.16 dnl Check for libpng (required)
3.17 PKG_CHECK_MODULES(LIBPNG, [libpng] )
3.18
3.19 +dnl Implied by libpng, but check explicitly just in case
3.20 +AC_CHECK_LIB(z, uncompress, [], [
3.21 + echo "Zlib (libz.so) could not be found, but is required."
3.22 + exit 1])
3.23 +
3.24 +if test "$APPLE_BUILD" != 'yes'; then
3.25 AC_CHECK_LIB(GL, glXQueryVersion, [], [
3.26 echo "The OpenGL library (libGL.so) could not be found, but is required."
3.27 exit 1])
3.28 AC_CHECK_HEADER([GL/gl.h], [], [
3.29 echo "The OpenGL header files (eg GL/gl.h) could not be found, but are required."
3.30 exit 1])
3.31 -dnl Implied by libpng, but check explicitly just in case
3.32 -AC_CHECK_LIB(z, uncompress, [], [
3.33 - echo "Zlib (libz.so) could not be found, but is required."
3.34 - exit 1])
3.35 +fi
3.36
3.37 dnl Check for GTK (required for unix systems)
3.38 -PKG_CHECK_MODULES(GTK, gtk+-2.0, [HAVE_GTK='yes'])
3.39 +PKG_CHECK_MODULES(GTK, gtk+-2.0, [
3.40 + HAVE_GTK='yes'
3.41 + AC_DEFINE([HAVE_GTK],1,[Have GTK libraries])
3.42 +])
3.43 +
3.44 +AM_CONDITIONAL(GUI_CARBON, [test "$HAVE_CARBON" = 'yes'])
3.45 AM_CONDITIONAL(GUI_GTK, [test "$HAVE_GTK" = 'yes'])
3.46
3.47 dnl Check for a supported cpu target for translation purposes
4.1 --- a/src/Makefile.am Tue Nov 20 11:16:09 2007 +0000
4.2 +++ b/src/Makefile.am Wed Nov 21 11:40:15 2007 +0000
4.3 @@ -41,7 +41,8 @@
4.4 drivers/gl_sl.c drivers/gl_slsrc.c
4.5
4.6 if BUILD_SH4X86
4.7 -lxdream_SOURCES += sh4/sh4x86.c \
4.8 +lxdream_SOURCES += sh4/sh4x86.c sh4/x86op.h \
4.9 + sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h \
4.10 sh4/sh4trans.c sh4/sh4trans.h \
4.11 x86dasm/x86dasm.c x86dasm/x86dasm.h \
4.12 x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
5.1 --- a/src/Makefile.in Tue Nov 20 11:16:09 2007 +0000
5.2 +++ b/src/Makefile.in Wed Nov 21 11:40:15 2007 +0000
5.3 @@ -36,7 +36,8 @@
5.4 PRE_UNINSTALL = :
5.5 POST_UNINSTALL = :
5.6 host_triplet = @host@
5.7 -@BUILD_SH4X86_TRUE@am__append_1 = sh4/sh4x86.c \
5.8 +@BUILD_SH4X86_TRUE@am__append_1 = sh4/sh4x86.c sh4/x86op.h \
5.9 +@BUILD_SH4X86_TRUE@ sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h \
5.10 @BUILD_SH4X86_TRUE@ sh4/sh4trans.c sh4/sh4trans.h \
5.11 @BUILD_SH4X86_TRUE@ x86dasm/x86dasm.c x86dasm/x86dasm.h \
5.12 @BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
5.13 @@ -96,6 +97,8 @@
5.14 GREP = @GREP@
5.15 GTK_CFLAGS = @GTK_CFLAGS@
5.16 GTK_LIBS = @GTK_LIBS@
5.17 +GUI_CARBON_FALSE = @GUI_CARBON_FALSE@
5.18 +GUI_CARBON_TRUE = @GUI_CARBON_TRUE@
5.19 GUI_GTK_FALSE = @GUI_GTK_FALSE@
5.20 GUI_GTK_TRUE = @GUI_GTK_TRUE@
5.21 INSTALL_DATA = @INSTALL_DATA@
5.22 @@ -277,7 +280,8 @@
5.23 maple/controller.h loader.c bootstrap.c util.c display.c \
5.24 display.h drivers/audio_null.c drivers/video_null.c \
5.25 drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \
5.26 - drivers/gl_sl.c drivers/gl_slsrc.c sh4/sh4x86.c sh4/sh4trans.c \
5.27 + drivers/gl_sl.c drivers/gl_slsrc.c sh4/sh4x86.c sh4/x86op.h \
5.28 + sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h sh4/sh4trans.c \
5.29 sh4/sh4trans.h x86dasm/x86dasm.c x86dasm/x86dasm.h \
5.30 x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c \
5.31 gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c \
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/sh4/ia32abi.h Wed Nov 21 11:40:15 2007 +0000
6.3 @@ -0,0 +1,197 @@
6.4 +/**
6.5 + * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $
6.6 + *
6.7 + * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and
6.8 + * calling conventions)
6.9 + *
6.10 + * Copyright (c) 2007 Nathan Keynes.
6.11 + *
6.12 + * This program is free software; you can redistribute it and/or modify
6.13 + * it under the terms of the GNU General Public License as published by
6.14 + * the Free Software Foundation; either version 2 of the License, or
6.15 + * (at your option) any later version.
6.16 + *
6.17 + * This program is distributed in the hope that it will be useful,
6.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.20 + * GNU General Public License for more details.
6.21 + */
6.22 +
6.23 +#ifndef __lxdream_ia32abi_H
6.24 +#define __lxdream_ia32abi_H 1
6.25 +
6.26 +#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );
6.27 +
6.28 +/**
6.29 + * Note: clobbers EAX to make the indirect call - this isn't usually
6.30 + * a problem since the callee will usually clobber it anyway.
6.31 + */
6.32 +#define CALL_FUNC0_SIZE 7
6.33 +static inline void call_func0( void *ptr )
6.34 +{
6.35 + load_imm32(R_EAX, (uint32_t)ptr);
6.36 + CALL_r32(R_EAX);
6.37 +}
6.38 +
6.39 +#define CALL_FUNC1_SIZE 11
6.40 +static inline void call_func1( void *ptr, int arg1 )
6.41 +{
6.42 + PUSH_r32(arg1);
6.43 + call_func0(ptr);
6.44 + ADD_imm8s_r32( 4, R_ESP );
6.45 +}
6.46 +
6.47 +#define CALL_FUNC2_SIZE 12
6.48 +static inline void call_func2( void *ptr, int arg1, int arg2 )
6.49 +{
6.50 + PUSH_r32(arg2);
6.51 + PUSH_r32(arg1);
6.52 + call_func0(ptr);
6.53 + ADD_imm8s_r32( 8, R_ESP );
6.54 +}
6.55 +
6.56 +/**
6.57 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
6.58 + * the second in arg2b
6.59 + * NB: 30 bytes
6.60 + */
6.61 +#define MEM_WRITE_DOUBLE_SIZE 30
6.62 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
6.63 +{
6.64 + ADD_imm8s_r32( 4, addr );
6.65 + PUSH_r32(arg2b);
6.66 + PUSH_r32(addr);
6.67 + ADD_imm8s_r32( -4, addr );
6.68 + PUSH_r32(arg2a);
6.69 + PUSH_r32(addr);
6.70 + call_func0(sh4_write_long);
6.71 + ADD_imm8s_r32( 8, R_ESP );
6.72 + call_func0(sh4_write_long);
6.73 + ADD_imm8s_r32( 8, R_ESP );
6.74 +}
6.75 +
6.76 +/**
6.77 + * Read a double (64-bit) value from memory, writing the first word into arg2a
6.78 + * and the second into arg2b. The addr must not be in EAX
6.79 + * NB: 27 bytes
6.80 + */
6.81 +#define MEM_READ_DOUBLE_SIZE 27
6.82 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
6.83 +{
6.84 + PUSH_r32(addr);
6.85 + call_func0(sh4_read_long);
6.86 + POP_r32(addr);
6.87 + PUSH_r32(R_EAX);
6.88 + ADD_imm8s_r32( 4, addr );
6.89 + PUSH_r32(addr);
6.90 + call_func0(sh4_read_long);
6.91 + ADD_imm8s_r32( 4, R_ESP );
6.92 + MOV_r32_r32( R_EAX, arg2b );
6.93 + POP_r32(arg2a);
6.94 +}
6.95 +
6.96 +#define EXIT_BLOCK_SIZE 29
6.97 +
6.98 +
6.99 +/**
6.100 + * Emit the 'start of block' assembly. Sets up the stack frame and save
6.101 + * SI/DI as required
6.102 + */
6.103 +void sh4_translate_begin_block( sh4addr_t pc )
6.104 +{
6.105 + PUSH_r32(R_EBP);
6.106 + /* mov &sh4r, ebp */
6.107 + load_ptr( R_EBP, &sh4r );
6.108 +
6.109 + sh4_x86.in_delay_slot = FALSE;
6.110 + sh4_x86.priv_checked = FALSE;
6.111 + sh4_x86.fpuen_checked = FALSE;
6.112 + sh4_x86.branch_taken = FALSE;
6.113 + sh4_x86.backpatch_posn = 0;
6.114 + sh4_x86.block_start_pc = pc;
6.115 + sh4_x86.tstate = TSTATE_NONE;
6.116 +#ifdef STACK_ALIGN
6.117 + sh4_x86.stack_posn = 8;
6.118 +#endif
6.119 +}
6.120 +
6.121 +/**
6.122 + * Exit the block with sh4r.pc already written
6.123 + * Bytes: 15
6.124 + */
6.125 +void exit_block_pcset( pc )
6.126 +{
6.127 + load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
6.128 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
6.129 + load_spreg( R_EAX, REG_OFFSET(pc) );
6.130 + call_func1(xlat_get_code,R_EAX);
6.131 + POP_r32(R_EBP);
6.132 + RET();
6.133 +}
6.134 +
6.135 +/**
6.136 + * Exit the block to an absolute PC
6.137 + */
6.138 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
6.139 +{
6.140 + load_imm32( R_ECX, pc ); // 5
6.141 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
6.142 + MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
6.143 + AND_imm8s_r32( 0xFC, R_EAX ); // 3
6.144 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
6.145 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
6.146 + POP_r32(R_EBP);
6.147 + RET();
6.148 +}
6.149 +
6.150 +/**
6.151 + * Write the block trailer (exception handling block)
6.152 + */
6.153 +void sh4_translate_end_block( sh4addr_t pc ) {
6.154 + if( sh4_x86.branch_taken == FALSE ) {
6.155 + // Didn't exit unconditionally already, so write the termination here
6.156 + exit_block( pc, pc );
6.157 + }
6.158 + if( sh4_x86.backpatch_posn != 0 ) {
6.159 + uint8_t *end_ptr = xlat_output;
6.160 + // Exception termination. Jump block for various exception codes:
6.161 + PUSH_imm32( EXC_DATA_ADDR_READ );
6.162 + JMP_rel8( 33, target1 );
6.163 + PUSH_imm32( EXC_DATA_ADDR_WRITE );
6.164 + JMP_rel8( 26, target2 );
6.165 + PUSH_imm32( EXC_ILLEGAL );
6.166 + JMP_rel8( 19, target3 );
6.167 + PUSH_imm32( EXC_SLOT_ILLEGAL );
6.168 + JMP_rel8( 12, target4 );
6.169 + PUSH_imm32( EXC_FPU_DISABLED );
6.170 + JMP_rel8( 5, target5 );
6.171 + PUSH_imm32( EXC_SLOT_FPU_DISABLED );
6.172 + // target
6.173 + JMP_TARGET(target1);
6.174 + JMP_TARGET(target2);
6.175 + JMP_TARGET(target3);
6.176 + JMP_TARGET(target4);
6.177 + JMP_TARGET(target5);
6.178 + // Raise exception
6.179 + load_spreg( R_ECX, REG_OFFSET(pc) );
6.180 + ADD_r32_r32( R_EDX, R_ECX );
6.181 + ADD_r32_r32( R_EDX, R_ECX );
6.182 + store_spreg( R_ECX, REG_OFFSET(pc) );
6.183 + MOV_moff32_EAX( &sh4_cpu_period );
6.184 + MUL_r32( R_EDX );
6.185 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
6.186 +
6.187 + call_func0( sh4_raise_exception );
6.188 + ADD_imm8s_r32( 4, R_ESP );
6.189 + load_spreg( R_EAX, REG_OFFSET(pc) );
6.190 + call_func1(xlat_get_code,R_EAX);
6.191 + POP_r32(R_EBP);
6.192 + RET();
6.193 +
6.194 + sh4_x86_do_backpatch( end_ptr );
6.195 + }
6.196 +}
6.197 +
6.198 +#endif
6.199 +
6.200 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/sh4/ia32mac.h Wed Nov 21 11:40:15 2007 +0000
7.3 @@ -0,0 +1,220 @@
7.4 +/**
7.5 + * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $
7.6 + *
7.7 + * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and
7.8 + * calling conventions)
7.9 + *
7.10 + * Copyright (c) 2007 Nathan Keynes.
7.11 + *
7.12 + * This program is free software; you can redistribute it and/or modify
7.13 + * it under the terms of the GNU General Public License as published by
7.14 + * the Free Software Foundation; either version 2 of the License, or
7.15 + * (at your option) any later version.
7.16 + *
7.17 + * This program is distributed in the hope that it will be useful,
7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.20 + * GNU General Public License for more details.
7.21 + */
7.22 +
7.23 +#ifndef __lxdream_ia32abi_H
7.24 +#define __lxdream_ia32abi_H 1
7.25 +
7.26 +#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );
7.27 +
7.28 +/**
7.29 + * Note: clobbers EAX to make the indirect call - this isn't usually
7.30 + * a problem since the callee will usually clobber it anyway.
7.31 + */
7.32 +#define CALL_FUNC0_SIZE 13
7.33 +static inline void call_func0( void *ptr )
7.34 +{
7.35 + int adj = (-sh4_x86.stack_posn)&0x0F;
7.36 + SUB_imm8s_r32( adj, R_ESP );
7.37 + load_imm32(R_EAX, (uint32_t)ptr);
7.38 + CALL_r32(R_EAX);
7.39 + ADD_imm8s_r32( adj, R_ESP );
7.40 +}
7.41 +
7.42 +#define CALL_FUNC1_SIZE 14
7.43 +static inline void call_func1( void *ptr, int arg1 )
7.44 +{
7.45 + int adj = (-4-sh4_x86.stack_posn)&0x0F;
7.46 + SUB_imm8s_r32( adj, R_ESP );
7.47 + PUSH_r32(arg1);
7.48 + load_imm32(R_EAX, (uint32_t)ptr);
7.49 + CALL_r32(R_EAX);
7.50 + ADD_imm8s_r32( adj+4, R_ESP );
7.51 + sh4_x86.stack_posn -= 4;
7.52 +}
7.53 +
7.54 +#define CALL_FUNC2_SIZE 15
7.55 +static inline void call_func2( void *ptr, int arg1, int arg2 )
7.56 +{
7.57 + int adj = (-8-sh4_x86.stack_posn)&0x0F;
7.58 + SUB_imm8s_r32( adj, R_ESP );
7.59 + PUSH_r32(arg2);
7.60 + PUSH_r32(arg1);
7.61 + load_imm32(R_EAX, (uint32_t)ptr);
7.62 + CALL_r32(R_EAX);
7.63 + ADD_imm8s_r32( adj+8, R_ESP );
7.64 + sh4_x86.stack_posn -= 8;
7.65 +}
7.66 +
7.67 +/**
7.68 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
7.69 + * the second in arg2b
7.70 + * NB: 30 bytes
7.71 + */
7.72 +#define MEM_WRITE_DOUBLE_SIZE 36
7.73 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
7.74 +{
7.75 + int adj = (-8-sh4_x86.stack_posn)&0x0F;
7.76 + SUB_imm8s_r32( adj, R_ESP );
7.77 + ADD_imm8s_r32( 4, addr );
7.78 + PUSH_r32(arg2b);
7.79 + PUSH_r32(addr);
7.80 + ADD_imm8s_r32( -4, addr );
7.81 + SUB_imm8s_r32( 8, R_ESP );
7.82 + PUSH_r32(arg2a);
7.83 + PUSH_r32(addr);
7.84 + load_imm32(R_EAX, (uint32_t)sh4_write_long);
7.85 + CALL_r32(R_EAX);
7.86 + ADD_imm8s_r32( 16, R_ESP );
7.87 + load_imm32(R_EAX, (uint32_t)sh4_write_long);
7.88 + CALL_r32(R_EAX);
7.89 + ADD_imm8s_r32( adj+8, R_ESP );
7.90 + sh4_x86.stack_posn -= 16;
7.91 +}
7.92 +
7.93 +/**
7.94 + * Read a double (64-bit) value from memory, writing the first word into arg2a
7.95 + * and the second into arg2b. The addr must not be in EAX
7.96 + * NB: 27 bytes
7.97 + */
7.98 +#define MEM_READ_DOUBLE_SIZE 36
7.99 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
7.100 +{
7.101 + int adj = (-4-sh4_x86.stack_posn)&0x0F;
7.102 + int adj2 = (-8-sh4_x86.stack_posn)&0x0F;
7.103 + SUB_imm8s_r32( adj, R_ESP );
7.104 + PUSH_r32(addr);
7.105 + load_imm32(R_EAX, (uint32_t)sh4_read_long);
7.106 + CALL_r32(R_EAX);
7.107 + POP_r32(addr);
7.108 + SUB_imm8s_r32( adj2-adj, R_ESP );
7.109 + PUSH_r32(R_EAX);
7.110 + ADD_imm8s_r32( 4, addr );
7.111 + PUSH_r32(addr);
7.112 + load_imm32(R_EAX, (uint32_t)sh4_read_long);
7.113 + CALL_r32(R_EAX);
7.114 + ADD_imm8s_r32( 4, R_ESP );
7.115 + MOV_r32_r32( R_EAX, arg2b );
7.116 + POP_r32(arg2a);
7.117 + ADD_imm8s_r32( adj2, R_ESP );
7.118 + sh4_x86.stack_posn -= 4;
7.119 +}
7.120 +
7.121 +#define EXIT_BLOCK_SIZE 29
7.122 +
7.123 +
7.124 +/**
7.125 + * Emit the 'start of block' assembly. Sets up the stack frame and save
7.126 + * SI/DI as required
7.127 + */
7.128 +void sh4_translate_begin_block( sh4addr_t pc )
7.129 +{
7.130 + PUSH_r32(R_EBP);
7.131 + /* mov &sh4r, ebp */
7.132 + load_ptr( R_EBP, &sh4r );
7.133 +
7.134 + sh4_x86.in_delay_slot = FALSE;
7.135 + sh4_x86.priv_checked = FALSE;
7.136 + sh4_x86.fpuen_checked = FALSE;
7.137 + sh4_x86.branch_taken = FALSE;
7.138 + sh4_x86.backpatch_posn = 0;
7.139 + sh4_x86.block_start_pc = pc;
7.140 + sh4_x86.tstate = TSTATE_NONE;
7.141 + sh4_x86.stack_posn = 8;
7.142 +}
7.143 +
7.144 +/**
7.145 + * Exit the block with sh4r.pc already written
7.146 + * Bytes: 15
7.147 + */
7.148 +void exit_block_pcset( pc )
7.149 +{
7.150 + load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
7.151 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
7.152 + load_spreg( R_EAX, REG_OFFSET(pc) );
7.153 + call_func1(xlat_get_code,R_EAX);
7.154 + POP_r32(R_EBP);
7.155 + RET();
7.156 +}
7.157 +
7.158 +/**
7.159 + * Exit the block to an absolute PC
7.160 + */
7.161 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
7.162 +{
7.163 + load_imm32( R_ECX, pc ); // 5
7.164 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
7.165 + MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
7.166 + AND_imm8s_r32( 0xFC, R_EAX ); // 3
7.167 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
7.168 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
7.169 + POP_r32(R_EBP);
7.170 + RET();
7.171 +}
7.172 +
7.173 +/**
7.174 + * Write the block trailer (exception handling block)
7.175 + */
7.176 +void sh4_translate_end_block( sh4addr_t pc ) {
7.177 + if( sh4_x86.branch_taken == FALSE ) {
7.178 + // Didn't exit unconditionally already, so write the termination here
7.179 + exit_block( pc, pc );
7.180 + }
7.181 + if( sh4_x86.backpatch_posn != 0 ) {
7.182 + uint8_t *end_ptr = xlat_output;
7.183 + // Exception termination. Jump block for various exception codes:
7.184 + PUSH_imm32( EXC_DATA_ADDR_READ );
7.185 + JMP_rel8( 33, target1 );
7.186 + PUSH_imm32( EXC_DATA_ADDR_WRITE );
7.187 + JMP_rel8( 26, target2 );
7.188 + PUSH_imm32( EXC_ILLEGAL );
7.189 + JMP_rel8( 19, target3 );
7.190 + PUSH_imm32( EXC_SLOT_ILLEGAL );
7.191 + JMP_rel8( 12, target4 );
7.192 + PUSH_imm32( EXC_FPU_DISABLED );
7.193 + JMP_rel8( 5, target5 );
7.194 + PUSH_imm32( EXC_SLOT_FPU_DISABLED );
7.195 + // target
7.196 + JMP_TARGET(target1);
7.197 + JMP_TARGET(target2);
7.198 + JMP_TARGET(target3);
7.199 + JMP_TARGET(target4);
7.200 + JMP_TARGET(target5);
7.201 + // Raise exception
7.202 + load_spreg( R_ECX, REG_OFFSET(pc) );
7.203 + ADD_r32_r32( R_EDX, R_ECX );
7.204 + ADD_r32_r32( R_EDX, R_ECX );
7.205 + store_spreg( R_ECX, REG_OFFSET(pc) );
7.206 + MOV_moff32_EAX( &sh4_cpu_period );
7.207 + MUL_r32( R_EDX );
7.208 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
7.209 +
7.210 + POP_r32(R_EDX);
7.211 + call_func1( sh4_raise_exception, R_EDX );
7.212 + load_spreg( R_EAX, REG_OFFSET(pc) );
7.213 + call_func1(xlat_get_code,R_EAX);
7.214 + POP_r32(R_EBP);
7.215 + RET();
7.216 +
7.217 + sh4_x86_do_backpatch( end_ptr );
7.218 + }
7.219 +}
7.220 +
7.221 +#endif
7.222 +
7.223 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/src/sh4/ia64abi.h Wed Nov 21 11:40:15 2007 +0000
8.3 @@ -0,0 +1,185 @@
8.4 +/**
8.5 + * $Id: ia64abi.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $
8.6 + *
8.7 + * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and
8.8 + * calling conventions)
8.9 + *
8.10 + * Copyright (c) 2007 Nathan Keynes.
8.11 + *
8.12 + * This program is free software; you can redistribute it and/or modify
8.13 + * it under the terms of the GNU General Public License as published by
8.14 + * the Free Software Foundation; either version 2 of the License, or
8.15 + * (at your option) any later version.
8.16 + *
8.17 + * This program is distributed in the hope that it will be useful,
8.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.20 + * GNU General Public License for more details.
8.21 + */
8.22 +
8.23 +#ifndef __lxdream_x86_64abi_H
8.24 +#define __lxdream_x86_64abi_H 1
8.25 +
8.26 +
8.27 +#define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );
8.28 +
8.29 +/**
8.30 + * Note: clobbers EAX to make the indirect call - this isn't usually
8.31 + * a problem since the callee will usually clobber it anyway.
8.32 + * Size: 12 bytes
8.33 + */
8.34 +#define CALL_FUNC0_SIZE 12
8.35 +static inline void call_func0( void *ptr )
8.36 +{
8.37 + load_imm64(R_EAX, (uint64_t)ptr);
8.38 + CALL_r32(R_EAX);
8.39 +}
8.40 +
8.41 +#define CALL_FUNC1_SIZE 14
8.42 +static inline void call_func1( void *ptr, int arg1 )
8.43 +{
8.44 + MOV_r32_r32(arg1, R_EDI);
8.45 + call_func0(ptr);
8.46 +}
8.47 +
8.48 +#define CALL_FUNC2_SIZE 16
8.49 +static inline void call_func2( void *ptr, int arg1, int arg2 )
8.50 +{
8.51 + MOV_r32_r32(arg1, R_EDI);
8.52 + MOV_r32_r32(arg2, R_ESI);
8.53 + call_func0(ptr);
8.54 +}
8.55 +
8.56 +#define MEM_WRITE_DOUBLE_SIZE 39
8.57 +/**
8.58 + * Write a double (64-bit) value into memory, with the first word in arg2a, and
8.59 + * the second in arg2b
8.60 + */
8.61 +static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
8.62 +{
8.63 + PUSH_r32(arg2b);
8.64 + PUSH_r32(addr);
8.65 + call_func2(sh4_write_long, addr, arg2a);
8.66 + POP_r32(addr);
8.67 + POP_r32(arg2b);
8.68 + ADD_imm8s_r32(4, addr);
8.69 + call_func2(sh4_write_long, addr, arg2b);
8.70 +}
8.71 +
8.72 +#define MEM_READ_DOUBLE_SIZE 35
8.73 +/**
8.74 + * Read a double (64-bit) value from memory, writing the first word into arg2a
8.75 + * and the second into arg2b. The addr must not be in EAX
8.76 + */
8.77 +static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
8.78 +{
8.79 + PUSH_r32(addr);
8.80 + call_func1(sh4_read_long, addr);
8.81 + POP_r32(R_EDI);
8.82 + PUSH_r32(R_EAX);
8.83 + ADD_imm8s_r32(4, R_EDI);
8.84 + call_func0(sh4_read_long);
8.85 + MOV_r32_r32(R_EAX, arg2b);
8.86 + POP_r32(arg2a);
8.87 +}
8.88 +
8.89 +
8.90 +/**
8.91 + * Emit the 'start of block' assembly. Sets up the stack frame and save
8.92 + * SI/DI as required
8.93 + */
8.94 +void sh4_translate_begin_block( sh4addr_t pc )
8.95 +{
8.96 + PUSH_r32(R_EBP);
8.97 + /* mov &sh4r, ebp */
8.98 + load_ptr( R_EBP, &sh4r );
8.99 +
8.100 + sh4_x86.in_delay_slot = FALSE;
8.101 + sh4_x86.priv_checked = FALSE;
8.102 + sh4_x86.fpuen_checked = FALSE;
8.103 + sh4_x86.branch_taken = FALSE;
8.104 + sh4_x86.backpatch_posn = 0;
8.105 + sh4_x86.block_start_pc = pc;
8.106 + sh4_x86.tstate = TSTATE_NONE;
8.107 + sh4_x86.stack_posn = 0;
8.108 +}
8.109 +
8.110 +/**
8.111 + * Exit the block with sh4r.pc already written
8.112 + * Bytes: 15
8.113 + */
8.114 +void exit_block_pcset( pc )
8.115 +{
8.116 + load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
8.117 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
8.118 + load_spreg( R_EAX, REG_OFFSET(pc) );
8.119 + call_func1(xlat_get_code,R_EAX);
8.120 + POP_r32(R_EBP);
8.121 + RET();
8.122 +}
8.123 +
8.124 +#define EXIT_BLOCK_SIZE 35
8.125 +/**
8.126 + * Exit the block to an absolute PC
8.127 + */
8.128 +void exit_block( sh4addr_t pc, sh4addr_t endpc )
8.129 +{
8.130 + load_imm32( R_ECX, pc ); // 5
8.131 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
8.132 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
8.133 + REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
8.134 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
8.135 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
8.136 + POP_r32(R_EBP);
8.137 + RET();
8.138 +}
8.139 +
8.140 +
8.141 +/**
8.142 + * Write the block trailer (exception handling block)
8.143 + */
8.144 +void sh4_translate_end_block( sh4addr_t pc ) {
8.145 + if( sh4_x86.branch_taken == FALSE ) {
8.146 + // Didn't exit unconditionally already, so write the termination here
8.147 + exit_block( pc, pc );
8.148 + }
8.149 + if( sh4_x86.backpatch_posn != 0 ) {
8.150 + uint8_t *end_ptr = xlat_output;
8.151 + // Exception termination. Jump block for various exception codes:
8.152 + load_imm32( R_EDI, EXC_DATA_ADDR_READ );
8.153 + JMP_rel8( 33, target1 );
8.154 + load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
8.155 + JMP_rel8( 26, target2 );
8.156 + load_imm32( R_EDI, EXC_ILLEGAL );
8.157 + JMP_rel8( 19, target3 );
8.158 + load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
8.159 + JMP_rel8( 12, target4 );
8.160 + load_imm32( R_EDI, EXC_FPU_DISABLED );
8.161 + JMP_rel8( 5, target5 );
8.162 + load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
8.163 + // target
8.164 + JMP_TARGET(target1);
8.165 + JMP_TARGET(target2);
8.166 + JMP_TARGET(target3);
8.167 + JMP_TARGET(target4);
8.168 + JMP_TARGET(target5);
8.169 + // Raise exception
8.170 + load_spreg( R_ECX, REG_OFFSET(pc) );
8.171 + ADD_r32_r32( R_EDX, R_ECX );
8.172 + ADD_r32_r32( R_EDX, R_ECX );
8.173 + store_spreg( R_ECX, REG_OFFSET(pc) );
8.174 + MOV_moff32_EAX( &sh4_cpu_period );
8.175 + MUL_r32( R_EDX );
8.176 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
8.177 +
8.178 + call_func0( sh4_raise_exception );
8.179 + load_spreg( R_EAX, REG_OFFSET(pc) );
8.180 + call_func1(xlat_get_code,R_EAX);
8.181 + POP_r32(R_EBP);
8.182 + RET();
8.183 +
8.184 + sh4_x86_do_backpatch( end_ptr );
8.185 + }
8.186 +}
8.187 +
8.188 +#endif
8.189 \ No newline at end of file
9.1 --- a/src/sh4/sh4x86.c Tue Nov 20 11:16:09 2007 +0000
9.2 +++ b/src/sh4/sh4x86.c Wed Nov 21 11:40:15 2007 +0000
9.3 @@ -45,6 +45,7 @@
9.4 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
9.5 gboolean branch_taken; /* true if we branched unconditionally */
9.6 uint32_t block_start_pc;
9.7 + uint32_t stack_posn; /* Trace stack height for alignment purposes */
9.8 int tstate;
9.9
9.10 /* Allocated memory for the (block-wide) back-patch list */
9.11 @@ -264,287 +265,6 @@
9.12 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
9.13 }
9.14
9.15 -#if SH4_TRANSLATOR == TARGET_X86_64
9.16 -/* X86-64 has different calling conventions... */
9.17 -
9.18 -#define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );
9.19 -
9.20 -/**
9.21 - * Note: clobbers EAX to make the indirect call - this isn't usually
9.22 - * a problem since the callee will usually clobber it anyway.
9.23 - * Size: 12 bytes
9.24 - */
9.25 -#define CALL_FUNC0_SIZE 12
9.26 -static inline void call_func0( void *ptr )
9.27 -{
9.28 - load_imm64(R_EAX, (uint64_t)ptr);
9.29 - CALL_r32(R_EAX);
9.30 -}
9.31 -
9.32 -#define CALL_FUNC1_SIZE 14
9.33 -static inline void call_func1( void *ptr, int arg1 )
9.34 -{
9.35 - MOV_r32_r32(arg1, R_EDI);
9.36 - call_func0(ptr);
9.37 -}
9.38 -
9.39 -#define CALL_FUNC2_SIZE 16
9.40 -static inline void call_func2( void *ptr, int arg1, int arg2 )
9.41 -{
9.42 - MOV_r32_r32(arg1, R_EDI);
9.43 - MOV_r32_r32(arg2, R_ESI);
9.44 - call_func0(ptr);
9.45 -}
9.46 -
9.47 -#define MEM_WRITE_DOUBLE_SIZE 39
9.48 -/**
9.49 - * Write a double (64-bit) value into memory, with the first word in arg2a, and
9.50 - * the second in arg2b
9.51 - */
9.52 -static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
9.53 -{
9.54 -/*
9.55 - MOV_r32_r32( addr, R_EDI );
9.56 - MOV_r32_r32( arg2b, R_ESI );
9.57 - REXW(); SHL_imm8_r32( 32, R_ESI );
9.58 - REXW(); MOVZX_r16_r32( arg2a, arg2a );
9.59 - REXW(); OR_r32_r32( arg2a, R_ESI );
9.60 - call_func0(sh4_write_quad);
9.61 -*/
9.62 - PUSH_r32(arg2b);
9.63 - PUSH_r32(addr);
9.64 - call_func2(sh4_write_long, addr, arg2a);
9.65 - POP_r32(addr);
9.66 - POP_r32(arg2b);
9.67 - ADD_imm8s_r32(4, addr);
9.68 - call_func2(sh4_write_long, addr, arg2b);
9.69 -}
9.70 -
9.71 -#define MEM_READ_DOUBLE_SIZE 35
9.72 -/**
9.73 - * Read a double (64-bit) value from memory, writing the first word into arg2a
9.74 - * and the second into arg2b. The addr must not be in EAX
9.75 - */
9.76 -static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
9.77 -{
9.78 -/*
9.79 - MOV_r32_r32( addr, R_EDI );
9.80 - call_func0(sh4_read_quad);
9.81 - REXW(); MOV_r32_r32( R_EAX, arg2a );
9.82 - REXW(); MOV_r32_r32( R_EAX, arg2b );
9.83 - REXW(); SHR_imm8_r32( 32, arg2b );
9.84 -*/
9.85 - PUSH_r32(addr);
9.86 - call_func1(sh4_read_long, addr);
9.87 - POP_r32(R_EDI);
9.88 - PUSH_r32(R_EAX);
9.89 - ADD_imm8s_r32(4, R_EDI);
9.90 - call_func0(sh4_read_long);
9.91 - MOV_r32_r32(R_EAX, arg2b);
9.92 - POP_r32(arg2a);
9.93 -}
9.94 -
9.95 -#define EXIT_BLOCK_SIZE 35
9.96 -/**
9.97 - * Exit the block to an absolute PC
9.98 - */
9.99 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
9.100 -{
9.101 - load_imm32( R_ECX, pc ); // 5
9.102 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
9.103 - REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
9.104 - REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
9.105 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
9.106 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
9.107 - POP_r32(R_EBP);
9.108 - RET();
9.109 -}
9.110 -
9.111 -
9.112 -/**
9.113 - * Write the block trailer (exception handling block)
9.114 - */
9.115 -void sh4_translate_end_block( sh4addr_t pc ) {
9.116 - if( sh4_x86.branch_taken == FALSE ) {
9.117 - // Didn't exit unconditionally already, so write the termination here
9.118 - exit_block( pc, pc );
9.119 - }
9.120 - if( sh4_x86.backpatch_posn != 0 ) {
9.121 - uint8_t *end_ptr = xlat_output;
9.122 - // Exception termination. Jump block for various exception codes:
9.123 - load_imm32( R_EDI, EXC_DATA_ADDR_READ );
9.124 - JMP_rel8( 33, target1 );
9.125 - load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
9.126 - JMP_rel8( 26, target2 );
9.127 - load_imm32( R_EDI, EXC_ILLEGAL );
9.128 - JMP_rel8( 19, target3 );
9.129 - load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
9.130 - JMP_rel8( 12, target4 );
9.131 - load_imm32( R_EDI, EXC_FPU_DISABLED );
9.132 - JMP_rel8( 5, target5 );
9.133 - load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
9.134 - // target
9.135 - JMP_TARGET(target1);
9.136 - JMP_TARGET(target2);
9.137 - JMP_TARGET(target3);
9.138 - JMP_TARGET(target4);
9.139 - JMP_TARGET(target5);
9.140 - // Raise exception
9.141 - load_spreg( R_ECX, REG_OFFSET(pc) );
9.142 - ADD_r32_r32( R_EDX, R_ECX );
9.143 - ADD_r32_r32( R_EDX, R_ECX );
9.144 - store_spreg( R_ECX, REG_OFFSET(pc) );
9.145 - MOV_moff32_EAX( &sh4_cpu_period );
9.146 - MUL_r32( R_EDX );
9.147 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
9.148 -
9.149 - call_func0( sh4_raise_exception );
9.150 - load_spreg( R_EAX, REG_OFFSET(pc) );
9.151 - call_func1(xlat_get_code,R_EAX);
9.152 - POP_r32(R_EBP);
9.153 - RET();
9.154 -
9.155 - sh4_x86_do_backpatch( end_ptr );
9.156 - }
9.157 -}
9.158 -
9.159 -#else /* SH4_TRANSLATOR == TARGET_X86 */
9.160 -
9.161 -#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );
9.162 -
9.163 -/**
9.164 - * Note: clobbers EAX to make the indirect call - this isn't usually
9.165 - * a problem since the callee will usually clobber it anyway.
9.166 - */
9.167 -#define CALL_FUNC0_SIZE 7
9.168 -static inline void call_func0( void *ptr )
9.169 -{
9.170 - load_imm32(R_EAX, (uint32_t)ptr);
9.171 - CALL_r32(R_EAX);
9.172 -}
9.173 -
9.174 -#define CALL_FUNC1_SIZE 11
9.175 -static inline void call_func1( void *ptr, int arg1 )
9.176 -{
9.177 - PUSH_r32(arg1);
9.178 - call_func0(ptr);
9.179 - ADD_imm8s_r32( 4, R_ESP );
9.180 -}
9.181 -
9.182 -#define CALL_FUNC2_SIZE 12
9.183 -static inline void call_func2( void *ptr, int arg1, int arg2 )
9.184 -{
9.185 - PUSH_r32(arg2);
9.186 - PUSH_r32(arg1);
9.187 - call_func0(ptr);
9.188 - ADD_imm8s_r32( 8, R_ESP );
9.189 -}
9.190 -
9.191 -/**
9.192 - * Write a double (64-bit) value into memory, with the first word in arg2a, and
9.193 - * the second in arg2b
9.194 - * NB: 30 bytes
9.195 - */
9.196 -#define MEM_WRITE_DOUBLE_SIZE 30
9.197 -static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
9.198 -{
9.199 - ADD_imm8s_r32( 4, addr );
9.200 - PUSH_r32(arg2b);
9.201 - PUSH_r32(addr);
9.202 - ADD_imm8s_r32( -4, addr );
9.203 - PUSH_r32(arg2a);
9.204 - PUSH_r32(addr);
9.205 - call_func0(sh4_write_long);
9.206 - ADD_imm8s_r32( 8, R_ESP );
9.207 - call_func0(sh4_write_long);
9.208 - ADD_imm8s_r32( 8, R_ESP );
9.209 -}
9.210 -
9.211 -/**
9.212 - * Read a double (64-bit) value from memory, writing the first word into arg2a
9.213 - * and the second into arg2b. The addr must not be in EAX
9.214 - * NB: 27 bytes
9.215 - */
9.216 -#define MEM_READ_DOUBLE_SIZE 27
9.217 -static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
9.218 -{
9.219 - PUSH_r32(addr);
9.220 - call_func0(sh4_read_long);
9.221 - POP_r32(addr);
9.222 - PUSH_r32(R_EAX);
9.223 - ADD_imm8s_r32( 4, addr );
9.224 - PUSH_r32(addr);
9.225 - call_func0(sh4_read_long);
9.226 - ADD_imm8s_r32( 4, R_ESP );
9.227 - MOV_r32_r32( R_EAX, arg2b );
9.228 - POP_r32(arg2a);
9.229 -}
9.230 -
9.231 -#define EXIT_BLOCK_SIZE 29
9.232 -/**
9.233 - * Exit the block to an absolute PC
9.234 - */
9.235 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
9.236 -{
9.237 - load_imm32( R_ECX, pc ); // 5
9.238 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
9.239 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
9.240 - AND_imm8s_r32( 0xFC, R_EAX ); // 3
9.241 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
9.242 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
9.243 - POP_r32(R_EBP);
9.244 - RET();
9.245 -}
9.246 -
9.247 -/**
9.248 - * Write the block trailer (exception handling block)
9.249 - */
9.250 -void sh4_translate_end_block( sh4addr_t pc ) {
9.251 - if( sh4_x86.branch_taken == FALSE ) {
9.252 - // Didn't exit unconditionally already, so write the termination here
9.253 - exit_block( pc, pc );
9.254 - }
9.255 - if( sh4_x86.backpatch_posn != 0 ) {
9.256 - uint8_t *end_ptr = xlat_output;
9.257 - // Exception termination. Jump block for various exception codes:
9.258 - PUSH_imm32( EXC_DATA_ADDR_READ );
9.259 - JMP_rel8( 33, target1 );
9.260 - PUSH_imm32( EXC_DATA_ADDR_WRITE );
9.261 - JMP_rel8( 26, target2 );
9.262 - PUSH_imm32( EXC_ILLEGAL );
9.263 - JMP_rel8( 19, target3 );
9.264 - PUSH_imm32( EXC_SLOT_ILLEGAL );
9.265 - JMP_rel8( 12, target4 );
9.266 - PUSH_imm32( EXC_FPU_DISABLED );
9.267 - JMP_rel8( 5, target5 );
9.268 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );
9.269 - // target
9.270 - JMP_TARGET(target1);
9.271 - JMP_TARGET(target2);
9.272 - JMP_TARGET(target3);
9.273 - JMP_TARGET(target4);
9.274 - JMP_TARGET(target5);
9.275 - // Raise exception
9.276 - load_spreg( R_ECX, REG_OFFSET(pc) );
9.277 - ADD_r32_r32( R_EDX, R_ECX );
9.278 - ADD_r32_r32( R_EDX, R_ECX );
9.279 - store_spreg( R_ECX, REG_OFFSET(pc) );
9.280 - MOV_moff32_EAX( &sh4_cpu_period );
9.281 - MUL_r32( R_EDX );
9.282 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
9.283 -
9.284 - call_func0( sh4_raise_exception );
9.285 - ADD_imm8s_r32( 4, R_ESP );
9.286 - load_spreg( R_EAX, REG_OFFSET(pc) );
9.287 - call_func1(xlat_get_code,R_EAX);
9.288 - POP_r32(R_EBP);
9.289 - RET();
9.290 -
9.291 - sh4_x86_do_backpatch( end_ptr );
9.292 - }
9.293 -}
9.294 -#endif
9.295 -
9.296 /* Exception checks - Note that all exception checks will clobber EAX */
9.297 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
9.298
9.299 @@ -638,44 +358,21 @@
9.300
9.301 #define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
9.302
9.303 -
9.304 -
9.305 -/**
9.306 - * Emit the 'start of block' assembly. Sets up the stack frame and save
9.307 - * SI/DI as required
9.308 - */
9.309 -void sh4_translate_begin_block( sh4addr_t pc )
9.310 -{
9.311 - PUSH_r32(R_EBP);
9.312 - /* mov &sh4r, ebp */
9.313 - load_ptr( R_EBP, &sh4r );
9.314 -
9.315 - sh4_x86.in_delay_slot = FALSE;
9.316 - sh4_x86.priv_checked = FALSE;
9.317 - sh4_x86.fpuen_checked = FALSE;
9.318 - sh4_x86.branch_taken = FALSE;
9.319 - sh4_x86.backpatch_posn = 0;
9.320 - sh4_x86.block_start_pc = pc;
9.321 - sh4_x86.tstate = TSTATE_NONE;
9.322 -}
9.323 -
9.324 -/**
9.325 - * Exit the block with sh4r.pc already written
9.326 - * Bytes: 15
9.327 - */
9.328 -void exit_block_pcset( pc )
9.329 -{
9.330 - load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
9.331 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
9.332 - load_spreg( R_EAX, REG_OFFSET(pc) );
9.333 - call_func1(xlat_get_code,R_EAX);
9.334 - POP_r32(R_EBP);
9.335 - RET();
9.336 -}
9.337 -
9.338 extern uint16_t *sh4_icache;
9.339 extern uint32_t sh4_icache_addr;
9.340
9.341 +/****** Import appropriate calling conventions ******/
9.342 +#if SH4_TRANSLATOR == TARGET_X86_64
9.343 +#include "sh4/ia64abi.h"
9.344 +#else /* SH4_TRANSLATOR == TARGET_X86 */
9.345 +#ifdef APPLE_BUILD
9.346 +#include "sh4/ia32mac.h"
9.347 +#else
9.348 +#include "sh4/ia32abi.h"
9.349 +#endif
9.350 +#endif
9.351 +
9.352 +
9.353 /**
9.354 * Translate a single instruction. Delayed branches are handled specially
9.355 * by translating both branch and delayed instruction as a single unit (as
10.1 --- a/src/sh4/sh4x86.in Tue Nov 20 11:16:09 2007 +0000
10.2 +++ b/src/sh4/sh4x86.in Wed Nov 21 11:40:15 2007 +0000
10.3 @@ -45,6 +45,7 @@
10.4 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
10.5 gboolean branch_taken; /* true if we branched unconditionally */
10.6 uint32_t block_start_pc;
10.7 + uint32_t stack_posn; /* Trace stack height for alignment purposes */
10.8 int tstate;
10.9
10.10 /* Allocated memory for the (block-wide) back-patch list */
10.11 @@ -264,287 +265,6 @@
10.12 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
10.13 }
10.14
10.15 -#if SH4_TRANSLATOR == TARGET_X86_64
10.16 -/* X86-64 has different calling conventions... */
10.17 -
10.18 -#define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );
10.19 -
10.20 -/**
10.21 - * Note: clobbers EAX to make the indirect call - this isn't usually
10.22 - * a problem since the callee will usually clobber it anyway.
10.23 - * Size: 12 bytes
10.24 - */
10.25 -#define CALL_FUNC0_SIZE 12
10.26 -static inline void call_func0( void *ptr )
10.27 -{
10.28 - load_imm64(R_EAX, (uint64_t)ptr);
10.29 - CALL_r32(R_EAX);
10.30 -}
10.31 -
10.32 -#define CALL_FUNC1_SIZE 14
10.33 -static inline void call_func1( void *ptr, int arg1 )
10.34 -{
10.35 - MOV_r32_r32(arg1, R_EDI);
10.36 - call_func0(ptr);
10.37 -}
10.38 -
10.39 -#define CALL_FUNC2_SIZE 16
10.40 -static inline void call_func2( void *ptr, int arg1, int arg2 )
10.41 -{
10.42 - MOV_r32_r32(arg1, R_EDI);
10.43 - MOV_r32_r32(arg2, R_ESI);
10.44 - call_func0(ptr);
10.45 -}
10.46 -
10.47 -#define MEM_WRITE_DOUBLE_SIZE 39
10.48 -/**
10.49 - * Write a double (64-bit) value into memory, with the first word in arg2a, and
10.50 - * the second in arg2b
10.51 - */
10.52 -static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
10.53 -{
10.54 -/*
10.55 - MOV_r32_r32( addr, R_EDI );
10.56 - MOV_r32_r32( arg2b, R_ESI );
10.57 - REXW(); SHL_imm8_r32( 32, R_ESI );
10.58 - REXW(); MOVZX_r16_r32( arg2a, arg2a );
10.59 - REXW(); OR_r32_r32( arg2a, R_ESI );
10.60 - call_func0(sh4_write_quad);
10.61 -*/
10.62 - PUSH_r32(arg2b);
10.63 - PUSH_r32(addr);
10.64 - call_func2(sh4_write_long, addr, arg2a);
10.65 - POP_r32(addr);
10.66 - POP_r32(arg2b);
10.67 - ADD_imm8s_r32(4, addr);
10.68 - call_func2(sh4_write_long, addr, arg2b);
10.69 -}
10.70 -
10.71 -#define MEM_READ_DOUBLE_SIZE 35
10.72 -/**
10.73 - * Read a double (64-bit) value from memory, writing the first word into arg2a
10.74 - * and the second into arg2b. The addr must not be in EAX
10.75 - */
10.76 -static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
10.77 -{
10.78 -/*
10.79 - MOV_r32_r32( addr, R_EDI );
10.80 - call_func0(sh4_read_quad);
10.81 - REXW(); MOV_r32_r32( R_EAX, arg2a );
10.82 - REXW(); MOV_r32_r32( R_EAX, arg2b );
10.83 - REXW(); SHR_imm8_r32( 32, arg2b );
10.84 -*/
10.85 - PUSH_r32(addr);
10.86 - call_func1(sh4_read_long, addr);
10.87 - POP_r32(R_EDI);
10.88 - PUSH_r32(R_EAX);
10.89 - ADD_imm8s_r32(4, R_EDI);
10.90 - call_func0(sh4_read_long);
10.91 - MOV_r32_r32(R_EAX, arg2b);
10.92 - POP_r32(arg2a);
10.93 -}
10.94 -
10.95 -#define EXIT_BLOCK_SIZE 35
10.96 -/**
10.97 - * Exit the block to an absolute PC
10.98 - */
10.99 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
10.100 -{
10.101 - load_imm32( R_ECX, pc ); // 5
10.102 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
10.103 - REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
10.104 - REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
10.105 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
10.106 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
10.107 - POP_r32(R_EBP);
10.108 - RET();
10.109 -}
10.110 -
10.111 -
10.112 -/**
10.113 - * Write the block trailer (exception handling block)
10.114 - */
10.115 -void sh4_translate_end_block( sh4addr_t pc ) {
10.116 - if( sh4_x86.branch_taken == FALSE ) {
10.117 - // Didn't exit unconditionally already, so write the termination here
10.118 - exit_block( pc, pc );
10.119 - }
10.120 - if( sh4_x86.backpatch_posn != 0 ) {
10.121 - uint8_t *end_ptr = xlat_output;
10.122 - // Exception termination. Jump block for various exception codes:
10.123 - load_imm32( R_EDI, EXC_DATA_ADDR_READ );
10.124 - JMP_rel8( 33, target1 );
10.125 - load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
10.126 - JMP_rel8( 26, target2 );
10.127 - load_imm32( R_EDI, EXC_ILLEGAL );
10.128 - JMP_rel8( 19, target3 );
10.129 - load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
10.130 - JMP_rel8( 12, target4 );
10.131 - load_imm32( R_EDI, EXC_FPU_DISABLED );
10.132 - JMP_rel8( 5, target5 );
10.133 - load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
10.134 - // target
10.135 - JMP_TARGET(target1);
10.136 - JMP_TARGET(target2);
10.137 - JMP_TARGET(target3);
10.138 - JMP_TARGET(target4);
10.139 - JMP_TARGET(target5);
10.140 - // Raise exception
10.141 - load_spreg( R_ECX, REG_OFFSET(pc) );
10.142 - ADD_r32_r32( R_EDX, R_ECX );
10.143 - ADD_r32_r32( R_EDX, R_ECX );
10.144 - store_spreg( R_ECX, REG_OFFSET(pc) );
10.145 - MOV_moff32_EAX( &sh4_cpu_period );
10.146 - MUL_r32( R_EDX );
10.147 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
10.148 -
10.149 - call_func0( sh4_raise_exception );
10.150 - load_spreg( R_EAX, REG_OFFSET(pc) );
10.151 - call_func1(xlat_get_code,R_EAX);
10.152 - POP_r32(R_EBP);
10.153 - RET();
10.154 -
10.155 - sh4_x86_do_backpatch( end_ptr );
10.156 - }
10.157 -}
10.158 -
10.159 -#else /* SH4_TRANSLATOR == TARGET_X86 */
10.160 -
10.161 -#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );
10.162 -
10.163 -/**
10.164 - * Note: clobbers EAX to make the indirect call - this isn't usually
10.165 - * a problem since the callee will usually clobber it anyway.
10.166 - */
10.167 -#define CALL_FUNC0_SIZE 7
10.168 -static inline void call_func0( void *ptr )
10.169 -{
10.170 - load_imm32(R_EAX, (uint32_t)ptr);
10.171 - CALL_r32(R_EAX);
10.172 -}
10.173 -
10.174 -#define CALL_FUNC1_SIZE 11
10.175 -static inline void call_func1( void *ptr, int arg1 )
10.176 -{
10.177 - PUSH_r32(arg1);
10.178 - call_func0(ptr);
10.179 - ADD_imm8s_r32( 4, R_ESP );
10.180 -}
10.181 -
10.182 -#define CALL_FUNC2_SIZE 12
10.183 -static inline void call_func2( void *ptr, int arg1, int arg2 )
10.184 -{
10.185 - PUSH_r32(arg2);
10.186 - PUSH_r32(arg1);
10.187 - call_func0(ptr);
10.188 - ADD_imm8s_r32( 8, R_ESP );
10.189 -}
10.190 -
10.191 -/**
10.192 - * Write a double (64-bit) value into memory, with the first word in arg2a, and
10.193 - * the second in arg2b
10.194 - * NB: 30 bytes
10.195 - */
10.196 -#define MEM_WRITE_DOUBLE_SIZE 30
10.197 -static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
10.198 -{
10.199 - ADD_imm8s_r32( 4, addr );
10.200 - PUSH_r32(arg2b);
10.201 - PUSH_r32(addr);
10.202 - ADD_imm8s_r32( -4, addr );
10.203 - PUSH_r32(arg2a);
10.204 - PUSH_r32(addr);
10.205 - call_func0(sh4_write_long);
10.206 - ADD_imm8s_r32( 8, R_ESP );
10.207 - call_func0(sh4_write_long);
10.208 - ADD_imm8s_r32( 8, R_ESP );
10.209 -}
10.210 -
10.211 -/**
10.212 - * Read a double (64-bit) value from memory, writing the first word into arg2a
10.213 - * and the second into arg2b. The addr must not be in EAX
10.214 - * NB: 27 bytes
10.215 - */
10.216 -#define MEM_READ_DOUBLE_SIZE 27
10.217 -static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
10.218 -{
10.219 - PUSH_r32(addr);
10.220 - call_func0(sh4_read_long);
10.221 - POP_r32(addr);
10.222 - PUSH_r32(R_EAX);
10.223 - ADD_imm8s_r32( 4, addr );
10.224 - PUSH_r32(addr);
10.225 - call_func0(sh4_read_long);
10.226 - ADD_imm8s_r32( 4, R_ESP );
10.227 - MOV_r32_r32( R_EAX, arg2b );
10.228 - POP_r32(arg2a);
10.229 -}
10.230 -
10.231 -#define EXIT_BLOCK_SIZE 29
10.232 -/**
10.233 - * Exit the block to an absolute PC
10.234 - */
10.235 -void exit_block( sh4addr_t pc, sh4addr_t endpc )
10.236 -{
10.237 - load_imm32( R_ECX, pc ); // 5
10.238 - store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
10.239 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
10.240 - AND_imm8s_r32( 0xFC, R_EAX ); // 3
10.241 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
10.242 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
10.243 - POP_r32(R_EBP);
10.244 - RET();
10.245 -}
10.246 -
10.247 -/**
10.248 - * Write the block trailer (exception handling block)
10.249 - */
10.250 -void sh4_translate_end_block( sh4addr_t pc ) {
10.251 - if( sh4_x86.branch_taken == FALSE ) {
10.252 - // Didn't exit unconditionally already, so write the termination here
10.253 - exit_block( pc, pc );
10.254 - }
10.255 - if( sh4_x86.backpatch_posn != 0 ) {
10.256 - uint8_t *end_ptr = xlat_output;
10.257 - // Exception termination. Jump block for various exception codes:
10.258 - PUSH_imm32( EXC_DATA_ADDR_READ );
10.259 - JMP_rel8( 33, target1 );
10.260 - PUSH_imm32( EXC_DATA_ADDR_WRITE );
10.261 - JMP_rel8( 26, target2 );
10.262 - PUSH_imm32( EXC_ILLEGAL );
10.263 - JMP_rel8( 19, target3 );
10.264 - PUSH_imm32( EXC_SLOT_ILLEGAL );
10.265 - JMP_rel8( 12, target4 );
10.266 - PUSH_imm32( EXC_FPU_DISABLED );
10.267 - JMP_rel8( 5, target5 );
10.268 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );
10.269 - // target
10.270 - JMP_TARGET(target1);
10.271 - JMP_TARGET(target2);
10.272 - JMP_TARGET(target3);
10.273 - JMP_TARGET(target4);
10.274 - JMP_TARGET(target5);
10.275 - // Raise exception
10.276 - load_spreg( R_ECX, REG_OFFSET(pc) );
10.277 - ADD_r32_r32( R_EDX, R_ECX );
10.278 - ADD_r32_r32( R_EDX, R_ECX );
10.279 - store_spreg( R_ECX, REG_OFFSET(pc) );
10.280 - MOV_moff32_EAX( &sh4_cpu_period );
10.281 - MUL_r32( R_EDX );
10.282 - ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
10.283 -
10.284 - call_func0( sh4_raise_exception );
10.285 - ADD_imm8s_r32( 4, R_ESP );
10.286 - load_spreg( R_EAX, REG_OFFSET(pc) );
10.287 - call_func1(xlat_get_code,R_EAX);
10.288 - POP_r32(R_EBP);
10.289 - RET();
10.290 -
10.291 - sh4_x86_do_backpatch( end_ptr );
10.292 - }
10.293 -}
10.294 -#endif
10.295 -
10.296 /* Exception checks - Note that all exception checks will clobber EAX */
10.297 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
10.298
10.299 @@ -638,44 +358,21 @@
10.300
10.301 #define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
10.302
10.303 -
10.304 -
10.305 -/**
10.306 - * Emit the 'start of block' assembly. Sets up the stack frame and save
10.307 - * SI/DI as required
10.308 - */
10.309 -void sh4_translate_begin_block( sh4addr_t pc )
10.310 -{
10.311 - PUSH_r32(R_EBP);
10.312 - /* mov &sh4r, ebp */
10.313 - load_ptr( R_EBP, &sh4r );
10.314 -
10.315 - sh4_x86.in_delay_slot = FALSE;
10.316 - sh4_x86.priv_checked = FALSE;
10.317 - sh4_x86.fpuen_checked = FALSE;
10.318 - sh4_x86.branch_taken = FALSE;
10.319 - sh4_x86.backpatch_posn = 0;
10.320 - sh4_x86.block_start_pc = pc;
10.321 - sh4_x86.tstate = TSTATE_NONE;
10.322 -}
10.323 -
10.324 -/**
10.325 - * Exit the block with sh4r.pc already written
10.326 - * Bytes: 15
10.327 - */
10.328 -void exit_block_pcset( pc )
10.329 -{
10.330 - load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
10.331 - ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
10.332 - load_spreg( R_EAX, REG_OFFSET(pc) );
10.333 - call_func1(xlat_get_code,R_EAX);
10.334 - POP_r32(R_EBP);
10.335 - RET();
10.336 -}
10.337 -
10.338 extern uint16_t *sh4_icache;
10.339 extern uint32_t sh4_icache_addr;
10.340
10.341 +/****** Import appropriate calling conventions ******/
10.342 +#if SH4_TRANSLATOR == TARGET_X86_64
10.343 +#include "sh4/ia64abi.h"
10.344 +#else /* SH4_TRANSLATOR == TARGET_X86 */
10.345 +#ifdef APPLE_BUILD
10.346 +#include "sh4/ia32mac.h"
10.347 +#else
10.348 +#include "sh4/ia32abi.h"
10.349 +#endif
10.350 +#endif
10.351 +
10.352 +
10.353 /**
10.354 * Translate a single instruction. Delayed branches are handled specially
10.355 * by translating both branch and delayed instruction as a single unit (as
11.1 --- a/src/sh4/x86op.h Tue Nov 20 11:16:09 2007 +0000
11.2 +++ b/src/sh4/x86op.h Wed Nov 21 11:40:15 2007 +0000
11.3 @@ -55,9 +55,31 @@
11.4 #define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=8
11.5 #if SH4_TRANSLATOR == TARGET_X86_64
11.6 #define OPPTR(x) OP64((uint64_t)(x))
11.7 +#define STACK_ALIGN 16
11.8 +#define POP_r32(r1) OP(0x58 + r1); sh4_x86.stack_posn -= 8;
11.9 +#define PUSH_r32(r1) OP(0x50 + r1); sh4_x86.stack_posn += 8;
11.10 +#define PUSH_imm32(imm) OP(0x68); OP32(imm); sh4_x86.stack_posn += 4;
11.11 +#define PUSH_imm64(imm) REXW(); OP(0x68); OP64(imm); sh4_x86.stack_posn += 8;
11.12 #else
11.13 #define OPPTR(x) OP32((uint32_t)(x))
11.14 +#ifdef APPLE_BUILD
11.15 +#define STACK_ALIGN 16
11.16 +#define POP_r32(r1) OP(0x58 + r1); sh4_x86.stack_posn -= 4;
11.17 +#define PUSH_r32(r1) OP(0x50 + r1); sh4_x86.stack_posn += 4;
11.18 +#define PUSH_imm32(imm) OP(0x68); OP32(imm); sh4_x86.stack_posn += 4;
11.19 +#else
11.20 +#define POP_r32(r1) OP(0x58 + r1)
11.21 +#define PUSH_r32(r1) OP(0x50 + r1)
11.22 +#define PUSH_imm32(imm) OP(0x68); OP32(imm)
11.23 #endif
11.24 +#endif
11.25 +
11.26 +#ifdef STACK_ALIGN
11.27 +#else
11.28 +#define POP_r32(r1) OP(0x58 + r1)
11.29 +#define PUSH_r32(r1) OP(0x50 + r1)
11.30 +#endif
11.31 +
11.32
11.33 /* Offset of a reg relative to the sh4r structure */
11.34 #define REG_OFFSET(reg) (((char *)&sh4r.reg) - ((char *)&sh4r))
11.35 @@ -140,9 +162,6 @@
11.36 #define OR_imm8_r8(imm,r1) OP(0x80); MODRM_rm32_r32(r1,1); OP(imm)
11.37 #define OR_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,1); OP32(imm)
11.38 #define OR_sh4r_r32(disp,r1) OP(0x0B); MODRM_r32_sh4r(r1,disp)
11.39 -#define POP_r32(r1) OP(0x58 + r1)
11.40 -#define PUSH_r32(r1) OP(0x50 + r1)
11.41 -#define PUSH_imm32(imm) OP(0x68); OP32(imm)
11.42 #define RCL1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,2)
11.43 #define RCR1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,3)
11.44 #define RET() OP(0xC3)
11.45 @@ -161,6 +180,7 @@
11.46 #define STC() OP(0xF9)
11.47 #define SUB_r32_r32(r1,r2) OP(0x2B); MODRM_rm32_r32(r1,r2)
11.48 #define SUB_sh4r_r32(disp,r1) OP(0x2B); MODRM_r32_sh4r(r1, disp)
11.49 +#define SUB_imm8s_r32(imm,r1) ADD_imm8s_r32(-(imm),r1)
11.50 #define TEST_r8_r8(r1,r2) OP(0x84); MODRM_r32_rm32(r1,r2)
11.51 #define TEST_r32_r32(r1,r2) OP(0x85); MODRM_rm32_r32(r1,r2)
11.52 #define TEST_imm8_r8(imm8,r1) OP(0xF6); MODRM_rm32_r32(r1,0); OP(imm8)
.