revision 586:2a3ba82cf243
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 586:2a3ba82cf243 |
parent | 553:4e6166258c22 |
child | 587:739a3136f269 |
author | nkeynes |
date | Tue Jan 15 20:50:23 2008 +0000 (16 years ago) |
Merged lxdream-mmu r570:596 to trunk
1.1 --- a/Makefile.in Thu Dec 20 09:56:07 2007 +00001.2 +++ b/Makefile.in Tue Jan 15 20:50:23 2008 +00001.3 @@ -55,9 +55,13 @@1.4 BUILD_SH4X86_TRUE = @BUILD_SH4X86_TRUE@1.5 BUILD_SYSTEST_FALSE = @BUILD_SYSTEST_FALSE@1.6 BUILD_SYSTEST_TRUE = @BUILD_SYSTEST_TRUE@1.7 +BUILD_X86_64_FALSE = @BUILD_X86_64_FALSE@1.8 +BUILD_X86_64_TRUE = @BUILD_X86_64_TRUE@1.9 CATALOGS = @CATALOGS@1.10 CATOBJEXT = @CATOBJEXT@1.11 CC = @CC@1.12 +CCAS = @CCAS@1.13 +CCASFLAGS = @CCASFLAGS@1.14 CCDEPMODE = @CCDEPMODE@1.15 CDROM_LINUX_FALSE = @CDROM_LINUX_FALSE@1.16 CDROM_LINUX_TRUE = @CDROM_LINUX_TRUE@1.17 @@ -81,6 +85,8 @@1.18 GREP = @GREP@1.19 GTK_CFLAGS = @GTK_CFLAGS@1.20 GTK_LIBS = @GTK_LIBS@1.21 +GUI_CARBON_FALSE = @GUI_CARBON_FALSE@1.22 +GUI_CARBON_TRUE = @GUI_CARBON_TRUE@1.23 GUI_GTK_FALSE = @GUI_GTK_FALSE@1.24 GUI_GTK_TRUE = @GUI_GTK_TRUE@1.25 INSTALL_DATA = @INSTALL_DATA@1.26 @@ -101,6 +107,7 @@1.27 MAKEINFO = @MAKEINFO@1.28 MKINSTALLDIRS = @MKINSTALLDIRS@1.29 MSGFMT = @MSGFMT@1.30 +MSGFMT_OPTS = @MSGFMT_OPTS@1.31 OBJEXT = @OBJEXT@1.32 PACKAGE = @PACKAGE@1.33 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
2.1 --- a/aclocal.m4 Thu Dec 20 09:56:07 2007 +00002.2 +++ b/aclocal.m4 Tue Jan 15 20:50:23 2008 +00002.3 @@ -1006,6 +1006,38 @@2.5 AU_DEFUN([fp_PROG_CC_STDC], [AM_PROG_CC_STDC])2.7 +# Figure out how to run the assembler. -*- Autoconf -*-2.8 +2.9 +# serial 22.10 +2.11 +# Copyright 2001 Free Software Foundation, Inc.2.12 +2.13 +# This program is free software; you can redistribute it and/or modify2.14 +# it under the terms of the GNU General Public License as published by2.15 +# the Free Software Foundation; either version 2, or (at your option)2.16 +# any later version.2.17 +2.18 +# This program is distributed in the hope that it will be useful,2.19 +# but WITHOUT ANY WARRANTY; without even the implied warranty of2.20 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the2.21 +# GNU General Public License for more details.2.22 +2.23 +# You should have received a copy of the GNU General Public License2.24 +# along with this program; if not, write to the Free Software2.25 +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA2.26 +# 02111-1307, USA.2.27 +2.28 +# AM_PROG_AS2.29 +# ----------2.30 +AC_DEFUN([AM_PROG_AS],2.31 +[# By default we simply use the C compiler to build assembly code.2.32 +AC_REQUIRE([AC_PROG_CC])2.33 +: ${CCAS='$(CC)'}2.34 +# Set ASFLAGS if not already set.2.35 +: ${CCASFLAGS='$(CFLAGS)'}2.36 +AC_SUBST(CCAS)2.37 +AC_SUBST(CCASFLAGS)])2.38 +2.39 # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-2.40 #2.41 # Copyright © 2004 Scott James Remnant <scott@netsplit.com>.2.42 @@ -1144,7 +1176,8 @@2.44 _PKG_TEXT2.45 ])],2.46 - [$4])2.47 + [AC_MSG_RESULT([no])2.48 + $4])2.49 elif test $pkg_failed = untried; then2.50 ifelse([$4], , [AC_MSG_FAILURE(dnl2.51 [The pkg-config script could not be found or is too old. Make sure it2.52 @@ -1266,7 +1299,8 @@2.53 #-----------------2.54 glib_DEFUN([GLIB_WITH_NLS],2.55 dnl NLS is obligatory2.56 - [USE_NLS=yes2.57 + [AC_REQUIRE([AC_CANONICAL_HOST])dnl2.58 + USE_NLS=yes2.59 AC_SUBST(USE_NLS)2.61 gt_cv_have_gettext=no2.62 @@ -1370,6 +1404,20 @@2.63 glib_save_LIBS="$LIBS"2.64 LIBS="$LIBS $INTLLIBS"2.65 AC_CHECK_FUNCS(dcgettext)2.66 + MSGFMT_OPTS=2.67 + AC_MSG_CHECKING([if msgfmt accepts -c])2.68 + GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[2.69 +msgid ""2.70 +msgstr ""2.71 +"Content-Type: text/plain; charset=UTF-8\n"2.72 +"Project-Id-Version: test 1.0\n"2.73 +"PO-Revision-Date: 2007-02-15 12:01+0100\n"2.74 +"Last-Translator: test <foo@bar.xx>\n"2.75 +"Language-Team: C <LL@li.org>\n"2.76 +"MIME-Version: 1.0\n"2.77 +"Content-Transfer-Encoding: 8bit\n"2.78 +], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])2.79 + AC_SUBST(MSGFMT_OPTS)2.80 AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)2.81 GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,2.82 [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)2.83 @@ -1541,8 +1589,10 @@2.84 [glib_REQUIRE([GLIB_GNU_GETTEXT])dnl2.85 glib_save_prefix="$prefix"2.86 glib_save_exec_prefix="$exec_prefix"2.87 +glib_save_datarootdir="$datarootdir"2.88 test "x$prefix" = xNONE && prefix=$ac_default_prefix2.89 test "x$exec_prefix" = xNONE && exec_prefix=$prefix2.90 +datarootdir=`eval echo "${datarootdir}"`2.91 if test "x$CATOBJEXT" = "x.mo" ; then2.92 localedir=`eval echo "${libdir}/locale"`2.93 else2.94 @@ -1550,6 +1600,7 @@2.95 fi2.96 prefix="$glib_save_prefix"2.97 exec_prefix="$glib_save_exec_prefix"2.98 +datarootdir="$glib_save_datarootdir"2.99 AC_DEFINE_UNQUOTED($1, "$localedir",2.100 [Define the location where the catalogs will be installed])2.101 ])2.102 @@ -1562,3 +1613,20 @@2.103 AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)])2.104 ])dnl2.106 +# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL])2.107 +#2.108 +# Create a temporary file with TEST-FILE as its contents and pass the2.109 +# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with2.110 +# 0 and perform ACTION-IF-FAIL for any other exit status.2.111 +AC_DEFUN([GLIB_RUN_PROG],2.112 +[cat >conftest.foo <<_ACEOF2.113 +$22.114 +_ACEOF2.115 +if AC_RUN_LOG([$1 conftest.foo]); then2.116 + m4_ifval([$3], [$3], [:])2.117 +m4_ifvaln([$4], [else $4])dnl2.118 +echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD2.119 +sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD2.120 +fi])2.121 +2.122 +
3.1 --- a/config.h.in Thu Dec 20 09:56:07 2007 +00003.2 +++ b/config.h.in Tue Jan 15 20:50:23 2008 +00003.3 @@ -13,6 +13,12 @@3.4 /* always defined to indicate that i18n is enabled */3.5 #undef ENABLE_NLS3.7 +/* Enable IO tracing */3.8 +#undef ENABLE_TRACE_IO3.9 +3.10 +/* Enable watchpoints */3.11 +#undef ENABLE_WATCH3.12 +3.13 /* translation domain */3.14 #undef GETTEXT_PACKAGE
4.1 --- a/configure Thu Dec 20 09:56:07 2007 +00004.2 +++ b/configure Tue Jan 15 20:50:23 2008 +00004.3 @@ -687,6 +687,8 @@4.4 CCDEPMODE4.5 am__fastdepCC_TRUE4.6 am__fastdepCC_FALSE4.7 +CCAS4.8 +CCASFLAGS4.9 CPP4.10 GREP4.11 EGREP4.12 @@ -709,6 +711,8 @@4.13 GUI_GTK_FALSE4.14 BUILD_SH4X86_TRUE4.15 BUILD_SH4X86_FALSE4.16 +BUILD_X86_64_TRUE4.17 +BUILD_X86_64_FALSE4.18 ESOUND_CFLAGS4.19 ESOUND_LIBS4.20 AUDIO_ESOUND_TRUE4.21 @@ -728,6 +732,7 @@4.22 GETTEXT_PACKAGE4.23 USE_NLS4.24 MSGFMT4.25 +MSGFMT_OPTS4.26 GMSGFMT4.27 XGETTEXT4.28 CATALOGS4.29 @@ -1341,6 +1346,10 @@4.30 (and sometimes confusing) to the casual installer4.31 --disable-dependency-tracking Speeds up one-time builds4.32 --enable-dependency-tracking Do not reject slow dependency extractors4.33 + --enable-trace Enable generation of IO traces (warning: hurts4.34 + performance)4.35 + --enable-watch Enable watchpoints in the debugger (warning: hurts4.36 + performance)4.38 Some influential environment variables:4.39 CC C compiler command4.40 @@ -4293,6 +4302,13 @@4.41 *) CC="$CC $am_cv_prog_cc_stdc" ;;4.42 esac4.44 +# By default we simply use the C compiler to build assembly code.4.45 +4.46 +: ${CCAS='$(CC)'}4.47 +# Set ASFLAGS if not already set.4.48 +: ${CCASFLAGS='$(CFLAGS)'}4.49 +4.50 +4.51 ac_ext=c4.52 ac_cpp='$CPP $CPPFLAGS'4.53 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'4.54 @@ -4943,6 +4959,27 @@4.55 case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac4.58 +# Check whether --enable-trace was given.4.59 +if test "${enable_trace+set}" = set; then4.60 + enableval=$enable_trace; if test "$enableval" == "yes"; then4.61 +4.62 +cat >>confdefs.h <<\_ACEOF4.63 +#define ENABLE_TRACE_IO 14.64 +_ACEOF4.65 +4.66 + fi4.67 +fi4.68 +4.69 +# Check whether --enable-watch was given.4.70 +if test "${enable_watch+set}" = set; then4.71 + enableval=$enable_watch; if test "$enableval" == "yes"; then4.72 +4.73 +cat >>confdefs.h <<\_ACEOF4.74 +#define ENABLE_WATCH 14.75 +_ACEOF4.76 +4.77 + fi4.78 +fi4.80 # On IRIX 5.3, sys/types and inttypes.h are conflicting.4.82 @@ -5848,6 +5885,16 @@4.86 +if test "$SH4_TRANSLATOR" = "x86_64"; then4.87 + BUILD_X86_64_TRUE=4.88 + BUILD_X86_64_FALSE='#'4.89 +else4.90 + BUILD_X86_64_TRUE='#'4.91 + BUILD_X86_64_FALSE=4.92 +fi4.93 +4.94 +4.95 +4.96 pkg_failed=no4.97 { echo "$as_me:$LINENO: checking for ESOUND" >&54.98 echo $ECHO_N "checking for ESOUND... $ECHO_C" >&6; }4.99 @@ -5906,7 +5953,9 @@4.100 # Put the nasty error message in config.log where it belongs4.101 echo "$ESOUND_PKG_ERRORS" >&54.103 - echo "Warning: esound not found - building without audio support"4.104 + { echo "$as_me:$LINENO: result: no" >&54.105 +echo "${ECHO_T}no" >&6; }4.106 + echo "Warning: esound not found - building without audio support"4.107 elif test $pkg_failed = untried; then4.108 echo "Warning: esound not found - building without audio support"4.109 else4.110 @@ -6562,7 +6611,7 @@4.112 fi4.113 fi4.114 - USE_NLS=yes4.115 + USE_NLS=yes4.118 gt_cv_have_gettext=no4.119 @@ -7517,6 +7566,35 @@4.120 fi4.121 done4.123 + MSGFMT_OPTS=4.124 + { echo "$as_me:$LINENO: checking if msgfmt accepts -c" >&54.125 +echo $ECHO_N "checking if msgfmt accepts -c... $ECHO_C" >&6; }4.126 + cat >conftest.foo <<_ACEOF4.127 +4.128 +msgid ""4.129 +msgstr ""4.130 +"Content-Type: text/plain; charset=UTF-8\n"4.131 +"Project-Id-Version: test 1.0\n"4.132 +"PO-Revision-Date: 2007-02-15 12:01+0100\n"4.133 +"Last-Translator: test <foo@bar.xx>\n"4.134 +"Language-Team: C <LL@li.org>\n"4.135 +"MIME-Version: 1.0\n"4.136 +"Content-Transfer-Encoding: 8bit\n"4.137 +4.138 +_ACEOF4.139 +if { (echo "$as_me:$LINENO: \$MSGFMT -c -o /dev/null conftest.foo") >&54.140 + ($MSGFMT -c -o /dev/null conftest.foo) 2>&54.141 + ac_status=$?4.142 + echo "$as_me:$LINENO: \$? = $ac_status" >&54.143 + (exit $ac_status); }; then4.144 + MSGFMT_OPTS=-c; { echo "$as_me:$LINENO: result: yes" >&54.145 +echo "${ECHO_T}yes" >&6; }4.146 +else { echo "$as_me:$LINENO: result: no" >&54.147 +echo "${ECHO_T}no" >&6; }4.148 +echo "$as_me: failed input was:" >&54.149 +sed 's/^/| /' conftest.foo >&54.150 +fi4.151 +4.152 # Extract the first word of "gmsgfmt", so it can be a program name with args.4.153 set dummy gmsgfmt; ac_word=$24.154 { echo "$as_me:$LINENO: checking for $ac_word" >&54.155 @@ -7996,6 +8074,13 @@4.156 Usually this means the macro was only invoked conditionally." >&2;}4.157 { (exit 1); exit 1; }; }4.158 fi4.159 +if test -z "${BUILD_X86_64_TRUE}" && test -z "${BUILD_X86_64_FALSE}"; then4.160 + { { echo "$as_me:$LINENO: error: conditional \"BUILD_X86_64\" was never defined.4.161 +Usually this means the macro was only invoked conditionally." >&54.162 +echo "$as_me: error: conditional \"BUILD_X86_64\" was never defined.4.163 +Usually this means the macro was only invoked conditionally." >&2;}4.164 + { (exit 1); exit 1; }; }4.165 +fi4.166 if test -z "${AUDIO_ESOUND_TRUE}" && test -z "${AUDIO_ESOUND_FALSE}"; then4.167 { { echo "$as_me:$LINENO: error: conditional \"AUDIO_ESOUND\" was never defined.4.168 Usually this means the macro was only invoked conditionally." >&54.169 @@ -8634,6 +8719,8 @@4.170 CCDEPMODE!$CCDEPMODE$ac_delim4.171 am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim4.172 am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim4.173 +CCAS!$CCAS$ac_delim4.174 +CCASFLAGS!$CCASFLAGS$ac_delim4.175 CPP!$CPP$ac_delim4.176 GREP!$GREP$ac_delim4.177 EGREP!$EGREP$ac_delim4.178 @@ -8655,8 +8742,6 @@4.179 GUI_GTK_TRUE!$GUI_GTK_TRUE$ac_delim4.180 GUI_GTK_FALSE!$GUI_GTK_FALSE$ac_delim4.181 BUILD_SH4X86_TRUE!$BUILD_SH4X86_TRUE$ac_delim4.182 -BUILD_SH4X86_FALSE!$BUILD_SH4X86_FALSE$ac_delim4.183 -ESOUND_CFLAGS!$ESOUND_CFLAGS$ac_delim4.184 _ACEOF4.186 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then4.187 @@ -8698,6 +8783,10 @@4.188 ac_delim='%!_!# '4.189 for ac_last_try in false false false false false :; do4.190 cat >conf$$subs.sed <<_ACEOF4.191 +BUILD_SH4X86_FALSE!$BUILD_SH4X86_FALSE$ac_delim4.192 +BUILD_X86_64_TRUE!$BUILD_X86_64_TRUE$ac_delim4.193 +BUILD_X86_64_FALSE!$BUILD_X86_64_FALSE$ac_delim4.194 +ESOUND_CFLAGS!$ESOUND_CFLAGS$ac_delim4.195 ESOUND_LIBS!$ESOUND_LIBS$ac_delim4.196 AUDIO_ESOUND_TRUE!$AUDIO_ESOUND_TRUE$ac_delim4.197 AUDIO_ESOUND_FALSE!$AUDIO_ESOUND_FALSE$ac_delim4.198 @@ -8716,6 +8805,7 @@4.199 GETTEXT_PACKAGE!$GETTEXT_PACKAGE$ac_delim4.200 USE_NLS!$USE_NLS$ac_delim4.201 MSGFMT!$MSGFMT$ac_delim4.202 +MSGFMT_OPTS!$MSGFMT_OPTS$ac_delim4.203 GMSGFMT!$GMSGFMT$ac_delim4.204 XGETTEXT!$XGETTEXT$ac_delim4.205 CATALOGS!$CATALOGS$ac_delim4.206 @@ -8733,7 +8823,7 @@4.207 LTLIBOBJS!$LTLIBOBJS$ac_delim4.208 _ACEOF4.210 - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 33; then4.211 + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 38; then4.212 break4.213 elif $ac_last_try; then4.214 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
5.1 --- a/configure.in Thu Dec 20 09:56:07 2007 +00005.2 +++ b/configure.in Tue Jan 15 20:50:23 2008 +00005.3 @@ -8,10 +8,20 @@5.4 AC_ISC_POSIX5.5 AC_PROG_CC5.6 AM_PROG_CC_STDC5.7 +AM_PROG_AS5.8 AC_HEADER_STDC5.9 AC_CANONICAL_BUILD5.10 AC_CANONICAL_HOST5.11 -5.12 +AC_ARG_ENABLE( trace,5.13 + AS_HELP_STRING( [--enable-trace], [Enable generation of IO traces (warning: hurts performance)]),5.14 + [if test "$enableval" == "yes"; then5.15 + AC_DEFINE(ENABLE_TRACE_IO, 1, [Enable IO tracing])5.16 + fi] )5.17 +AC_ARG_ENABLE( watch,5.18 + AS_HELP_STRING( [--enable-watch], [Enable watchpoints in the debugger (warning: hurts performance)]),5.19 + [if test "$enableval" == "yes"; then5.20 + AC_DEFINE(ENABLE_WATCH, 1, [Enable watchpoints])5.21 + fi] )5.22 dnl ----------- Check for mandatory dependencies --------------5.23 dnl Building on MAC?5.24 AC_CHECK_HEADER([Carbon/Carbon.h], [5.25 @@ -60,6 +70,7 @@5.26 echo "Warning: No translator available for $host. Building emulation core only";;5.27 esac5.28 AM_CONDITIONAL(BUILD_SH4X86, [test "$SH4_TRANSLATOR" = "x86" -o "$SH4_TRANSLATOR" = "x86_64"])5.29 +AM_CONDITIONAL(BUILD_X86_64, [test "$SH4_TRANSLATOR" = "x86_64"])5.31 dnl ------------------ Optional driver support -------------------5.32 dnl Check for esound
6.1 --- a/src/Makefile.am Thu Dec 20 09:56:07 2007 +00006.2 +++ b/src/Makefile.am Tue Jan 15 20:50:23 2008 +00006.3 @@ -29,7 +29,7 @@6.4 sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \6.5 sh4/mmu.c sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \6.6 sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h \6.7 - sh4/xltcache.c sh4/xltcache.h \6.8 + sh4/xltcache.c sh4/xltcache.h sh4/sh4.h \6.9 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \6.10 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \6.11 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \6.12 @@ -48,17 +48,16 @@6.13 sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h \6.14 sh4/sh4trans.c sh4/sh4trans.h \6.15 x86dasm/x86dasm.c x86dasm/x86dasm.h \6.16 - x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c6.17 + x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c6.19 +test_testsh4x86_LDADD = @GTK_LIBS@6.20 test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \6.21 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \6.22 x86dasm/dis-buf.c \6.23 sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \6.24 - sh4/xltcache.h mem.c util.c6.25 -test_testsh4x86_LDADD = @GTK_LIBS@6.26 + sh4/xltcache.h mem.c util.c sh4/mmu.c6.28 check_PROGRAMS += test/testsh4x866.29 -6.30 endif6.32 if GUI_GTK
7.1 --- a/src/Makefile.in Thu Dec 20 09:56:07 2007 +00007.2 +++ b/src/Makefile.in Tue Jan 15 20:50:23 2008 +00007.3 @@ -40,7 +40,7 @@7.4 @BUILD_SH4X86_TRUE@ sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h \7.5 @BUILD_SH4X86_TRUE@ sh4/sh4trans.c sh4/sh4trans.h \7.6 @BUILD_SH4X86_TRUE@ x86dasm/x86dasm.c x86dasm/x86dasm.h \7.7 -@BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c7.8 +@BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c7.10 @BUILD_SH4X86_TRUE@am__append_2 = test/testsh4x867.11 @GUI_GTK_TRUE@am__append_3 = gtkui/gtkui.c gtkui/gtkui.h \7.12 @@ -72,9 +72,13 @@7.13 BUILD_SH4X86_TRUE = @BUILD_SH4X86_TRUE@7.14 BUILD_SYSTEST_FALSE = @BUILD_SYSTEST_FALSE@7.15 BUILD_SYSTEST_TRUE = @BUILD_SYSTEST_TRUE@7.16 +BUILD_X86_64_FALSE = @BUILD_X86_64_FALSE@7.17 +BUILD_X86_64_TRUE = @BUILD_X86_64_TRUE@7.18 CATALOGS = @CATALOGS@7.19 CATOBJEXT = @CATOBJEXT@7.20 CC = @CC@7.21 +CCAS = @CCAS@7.22 +CCASFLAGS = @CCASFLAGS@7.23 CCDEPMODE = @CCDEPMODE@7.24 CDROM_LINUX_FALSE = @CDROM_LINUX_FALSE@7.25 CDROM_LINUX_TRUE = @CDROM_LINUX_TRUE@7.26 @@ -120,6 +124,7 @@7.27 MAKEINFO = @MAKEINFO@7.28 MKINSTALLDIRS = @MKINSTALLDIRS@7.29 MSGFMT = @MSGFMT@7.30 +MSGFMT_OPTS = @MSGFMT_OPTS@7.31 OBJEXT = @OBJEXT@7.32 PACKAGE = @PACKAGE@7.33 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@7.34 @@ -213,7 +218,7 @@7.35 sh4/sh4.c sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \7.36 sh4/mmu.c sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \7.37 sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c sh4/sh4stat.h \7.38 - sh4/xltcache.c sh4/xltcache.h \7.39 + sh4/xltcache.c sh4/xltcache.h sh4/sh4.h \7.40 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \7.41 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \7.42 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \7.43 @@ -228,13 +233,13 @@7.44 drivers/gl_sl.c drivers/gl_slsrc.c\7.45 $(am__append_1) $(am__append_3) $(am__append_4) $(am__append_5) $(am__append_6)7.47 +@BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @GTK_LIBS@7.48 @BUILD_SH4X86_TRUE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \7.49 @BUILD_SH4X86_TRUE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \7.50 @BUILD_SH4X86_TRUE@ x86dasm/dis-buf.c \7.51 @BUILD_SH4X86_TRUE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \7.52 -@BUILD_SH4X86_TRUE@ sh4/xltcache.h mem.c util.c7.53 +@BUILD_SH4X86_TRUE@ sh4/xltcache.h mem.c util.c sh4/mmu.c7.55 -@BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @GTK_LIBS@7.57 lxdream_LDADD = @GTK_LIBS@ @LIBPNG_LIBS@ @ESOUND_LIBS@ $(INTLLIBS)7.59 @@ -271,25 +276,25 @@7.60 sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c sh4/mmu.c \7.61 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \7.62 sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c sh4/sh4stat.c \7.63 - sh4/sh4stat.h sh4/xltcache.c sh4/xltcache.h aica/armcore.c \7.64 - aica/armcore.h aica/armdasm.c aica/armmem.c aica/aica.c \7.65 - aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c pvr2/pvr2.h \7.66 - pvr2/pvr2mem.c pvr2/tacore.c pvr2/render.c pvr2/rendcore.c \7.67 - pvr2/rendbkg.c pvr2/rendsort.c pvr2/texcache.c pvr2/yuv.c \7.68 - pvr2/rendsave.c maple/maple.c maple/maple.h maple/controller.c \7.69 - maple/controller.h loader.c bootstrap.c util.c display.c \7.70 - display.h drivers/audio_null.c drivers/video_null.c \7.71 - drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \7.72 - drivers/gl_sl.c drivers/gl_slsrc.c sh4/sh4x86.c sh4/x86op.h \7.73 - sh4/ia32abi.h sh4/ia32mac.h sh4/ia64abi.h sh4/sh4trans.c \7.74 - sh4/sh4trans.h x86dasm/x86dasm.c x86dasm/x86dasm.h \7.75 - x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c \7.76 - gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c \7.77 - gtkui/mmio_win.c gtkui/debug_win.c gtkui/dump_win.c \7.78 - gtkui/ctrl_dlg.c gtkui/path_dlg.c gtkui/gdrom_menu.c \7.79 - drivers/video_gtk.c drivers/video_gtk.h drivers/video_glx.c \7.80 - drivers/video_glx.h drivers/cd_linux.c drivers/cd_none.c \7.81 - drivers/audio_esd.c7.82 + sh4/sh4stat.h sh4/xltcache.c sh4/xltcache.h sh4/sh4.h \7.83 + aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \7.84 + aica/aica.c aica/aica.h aica/audio.c aica/audio.h pvr2/pvr2.c \7.85 + pvr2/pvr2.h pvr2/pvr2mem.c pvr2/tacore.c pvr2/render.c \7.86 + pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c pvr2/texcache.c \7.87 + pvr2/yuv.c pvr2/rendsave.c maple/maple.c maple/maple.h \7.88 + maple/controller.c maple/controller.h loader.c bootstrap.c \7.89 + util.c display.c display.h drivers/audio_null.c \7.90 + drivers/video_null.c drivers/gl_common.c drivers/gl_common.h \7.91 + drivers/gl_fbo.c drivers/gl_sl.c drivers/gl_slsrc.c \7.92 + sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h sh4/ia32mac.h \7.93 + sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h x86dasm/x86dasm.c \7.94 + x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \7.95 + x86dasm/dis-buf.c gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c \7.96 + gtkui/gtkcb.c gtkui/mmio_win.c gtkui/debug_win.c \7.97 + gtkui/dump_win.c gtkui/ctrl_dlg.c gtkui/path_dlg.c \7.98 + gtkui/gdrom_menu.c drivers/video_gtk.c drivers/video_gtk.h \7.99 + drivers/video_glx.c drivers/video_glx.h drivers/cd_linux.c \7.100 + drivers/cd_none.c drivers/audio_esd.c7.101 @BUILD_SH4X86_TRUE@am__objects_1 = sh4x86.$(OBJEXT) sh4trans.$(OBJEXT) \7.102 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \7.103 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT)7.104 @@ -327,13 +332,13 @@7.105 am__test_testsh4x86_SOURCES_DIST = test/testsh4x86.c x86dasm/x86dasm.c \7.106 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \7.107 x86dasm/dis-buf.c sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c \7.108 - sh4/xltcache.c sh4/xltcache.h mem.c util.c7.109 + sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/mmu.c7.110 @BUILD_SH4X86_TRUE@am_test_testsh4x86_OBJECTS = testsh4x86.$(OBJEXT) \7.111 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \7.112 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT) \7.113 @BUILD_SH4X86_TRUE@ sh4dasm.$(OBJEXT) sh4trans.$(OBJEXT) \7.114 @BUILD_SH4X86_TRUE@ sh4x86.$(OBJEXT) xltcache.$(OBJEXT) \7.115 -@BUILD_SH4X86_TRUE@ mem.$(OBJEXT) util.$(OBJEXT)7.116 +@BUILD_SH4X86_TRUE@ mem.$(OBJEXT) util.$(OBJEXT) mmu.$(OBJEXT)7.117 test_testsh4x86_OBJECTS = $(am_test_testsh4x86_OBJECTS)7.118 @BUILD_SH4X86_TRUE@test_testsh4x86_DEPENDENCIES =7.119 @BUILD_SH4X86_FALSE@test_testsh4x86_DEPENDENCIES =
8.1 --- a/src/aica/aica.c Thu Dec 20 09:56:07 2007 +00008.2 +++ b/src/aica/aica.c Tue Jan 15 20:50:23 2008 +00008.3 @@ -1,5 +1,5 @@8.4 /**8.5 - * $Id: aica.c,v 1.26 2007-10-31 09:05:13 nkeynes Exp $8.6 + * $Id$8.7 *8.8 * This module implements the AICA's IO interfaces, as well8.9 * as providing the core AICA module to the system.
9.1 --- a/src/aica/aica.h Thu Dec 20 09:56:07 2007 +00009.2 +++ b/src/aica/aica.h Tue Jan 15 20:50:23 2008 +00009.3 @@ -1,5 +1,5 @@9.4 /**9.5 - * $Id: aica.h,v 1.12 2007-10-27 05:47:21 nkeynes Exp $9.6 + * $Id$9.7 *9.8 * MMIO definitions for the AICA sound chip. Note that the regions defined9.9 * here are relative to the SH4 memory map (0x00700000 based), rather than
10.1 --- a/src/aica/armcore.c Thu Dec 20 09:56:07 2007 +000010.2 +++ b/src/aica/armcore.c Tue Jan 15 20:50:23 2008 +000010.3 @@ -1,5 +1,5 @@10.4 /**10.5 - * $Id: armcore.c,v 1.21 2007-10-09 08:11:51 nkeynes Exp $10.6 + * $Id$10.7 *10.8 * ARM7TDMI CPU emulation core.10.9 *10.10 @@ -53,14 +53,14 @@10.11 static struct breakpoint_struct arm_breakpoints[MAX_BREAKPOINTS];10.12 static int arm_breakpoint_count = 0;10.14 -void arm_set_breakpoint( uint32_t pc, int type )10.15 +void arm_set_breakpoint( uint32_t pc, breakpoint_type_t type )10.16 {10.17 arm_breakpoints[arm_breakpoint_count].address = pc;10.18 arm_breakpoints[arm_breakpoint_count].type = type;10.19 arm_breakpoint_count++;10.20 }10.22 -gboolean arm_clear_breakpoint( uint32_t pc, int type )10.23 +gboolean arm_clear_breakpoint( uint32_t pc, breakpoint_type_t type )10.24 {10.25 int i;
11.1 --- a/src/aica/armcore.h Thu Dec 20 09:56:07 2007 +000011.2 +++ b/src/aica/armcore.h Tue Jan 15 20:50:23 2008 +000011.3 @@ -1,5 +1,5 @@11.4 /**11.5 - * $Id: armcore.h,v 1.15 2007-10-09 08:11:51 nkeynes Exp $11.6 + * $Id$11.7 *11.8 * Interface definitions for the ARM CPU emulation core proper.11.9 *11.10 @@ -19,7 +19,8 @@11.11 #ifndef dream_armcore_H11.12 #define dream_armcore_H 111.14 -#include "dream.h"11.15 +#include "lxdream.h"11.16 +#include "mem.h"11.17 #include <stdint.h>11.18 #include <stdio.h>11.20 @@ -88,8 +89,8 @@11.21 void arm_save_state( FILE *f );11.22 int arm_load_state( FILE *f );11.23 gboolean arm_execute_instruction( void );11.24 -void arm_set_breakpoint( uint32_t pc, int type );11.25 -gboolean arm_clear_breakpoint( uint32_t pc, int type );11.26 +void arm_set_breakpoint( uint32_t pc, breakpoint_type_t type );11.27 +gboolean arm_clear_breakpoint( uint32_t pc, breakpoint_type_t type );11.28 int arm_get_breakpoint( uint32_t pc );11.30 /* ARM Memory */
12.1 --- a/src/aica/armdasm.c Thu Dec 20 09:56:07 2007 +000012.2 +++ b/src/aica/armdasm.c Tue Jan 15 20:50:23 2008 +000012.3 @@ -1,5 +1,5 @@12.4 /**12.5 - * $Id: armdasm.c,v 1.13 2007-10-09 08:11:51 nkeynes Exp $12.6 + * $Id$12.7 *12.8 * armdasm.c 21 Aug 2004 - ARM7tdmi (ARMv4) disassembler12.9 *
13.1 --- a/src/aica/armdasm.h Thu Dec 20 09:56:07 2007 +000013.2 +++ b/src/aica/armdasm.h Tue Jan 15 20:50:23 2008 +000013.3 @@ -1,5 +1,5 @@13.4 /**13.5 - * $Id: armdasm.h,v 1.2 2005-12-25 05:57:00 nkeynes Exp $13.6 + * $Id$13.7 *13.8 * ARM CPU definition and disassembly function declarations13.9 *
14.1 --- a/src/aica/armmem.c Thu Dec 20 09:56:07 2007 +000014.2 +++ b/src/aica/armmem.c Tue Jan 15 20:50:23 2008 +000014.3 @@ -1,5 +1,5 @@14.4 /**14.5 - * $Id: armmem.c,v 1.9 2007-11-08 11:54:16 nkeynes Exp $14.6 + * $Id$14.7 *14.8 * Implements the ARM's memory map.14.9 *
15.1 --- a/src/aica/audio.c Thu Dec 20 09:56:07 2007 +000015.2 +++ b/src/aica/audio.c Tue Jan 15 20:50:23 2008 +000015.3 @@ -1,5 +1,5 @@15.4 /**15.5 - * $Id: audio.c,v 1.11 2007-10-27 05:47:21 nkeynes Exp $15.6 + * $Id$15.7 *15.8 * Audio mixer core. Combines all the active streams into a single sound15.9 * buffer for output.
16.1 --- a/src/aica/audio.h Thu Dec 20 09:56:07 2007 +000016.2 +++ b/src/aica/audio.h Tue Jan 15 20:50:23 2008 +000016.3 @@ -1,5 +1,5 @@16.4 /**16.5 - * $Id: audio.h,v 1.10 2007-10-27 05:47:21 nkeynes Exp $16.6 + * $Id$16.7 *16.8 * Audio engine, ie the part that does the actual work.16.9 *
17.1 --- a/src/asic.c Thu Dec 20 09:56:07 2007 +000017.2 +++ b/src/asic.c Tue Jan 15 20:50:23 2008 +000017.3 @@ -1,5 +1,5 @@17.4 /**17.5 - * $Id: asic.c,v 1.30 2007-10-08 12:06:01 nkeynes Exp $17.6 + * $Id$17.7 *17.8 * Support for the miscellaneous ASIC functions (Primarily event multiplexing,17.9 * and DMA).17.10 @@ -25,7 +25,7 @@17.11 #include "mem.h"17.12 #include "sh4/intc.h"17.13 #include "sh4/dmac.h"17.14 -#include "sh4/sh4core.h"17.15 +#include "sh4/sh4.h"17.16 #include "dreamcast.h"17.17 #include "maple/maple.h"17.18 #include "gdrom/ide.h"17.19 @@ -348,7 +348,6 @@17.20 case SYSRESET:17.21 if( val == 0x7611 ) {17.22 dreamcast_reset();17.23 - sh4r.new_pc = sh4r.pc;17.24 } else {17.25 WARN( "Unknown value %08X written to SYSRESET port", val );17.26 }17.27 @@ -387,11 +386,6 @@17.28 {17.29 int32_t val;17.30 switch( reg ) {17.31 - /*17.32 - case 0x89C:17.33 - sh4_stop();17.34 - return 0x000000B;17.35 - */17.36 case PIRQ0:17.37 case PIRQ1:17.38 case PIRQ2:17.39 @@ -531,8 +525,6 @@17.40 case PVRDMA2CTL2:17.41 if( val != 0 ) {17.42 ERROR( "Write to unimplemented DMA control register %08X", reg );17.43 - //dreamcast_stop();17.44 - //sh4_stop();17.45 }17.46 break;17.47 default:
18.1 --- a/src/asic.h Thu Dec 20 09:56:07 2007 +000018.2 +++ b/src/asic.h Tue Jan 15 20:50:23 2008 +000018.3 @@ -1,5 +1,5 @@18.4 /**18.5 - * $Id: asic.h,v 1.19 2007-01-25 10:16:32 nkeynes Exp $18.6 + * $Id$18.7 *18.8 * Support for the miscellaneous ASIC functions (Primarily event multiplexing,18.9 * and DMA). Includes MMIO definitions for the 5f6000 and 5f7000 regions,
19.1 --- a/src/bios.c Thu Dec 20 09:56:07 2007 +000019.2 +++ b/src/bios.c Tue Jan 15 20:50:23 2008 +000019.3 @@ -1,5 +1,5 @@19.4 /**19.5 - * $Id: bios.c,v 1.5 2007-11-08 11:54:16 nkeynes Exp $19.6 + * $Id$19.7 *19.8 * "Fake" BIOS functions, for operation without the actual BIOS.19.9 *19.10 @@ -20,7 +20,7 @@19.11 #include "mem.h"19.12 #include "syscall.h"19.13 #include "dreamcast.h"19.14 -#include "sh4/sh4core.h"19.15 +#include "sh4/sh4.h"19.17 #define COMMAND_QUEUE_LENGTH 16
20.1 --- a/src/bootstrap.c Thu Dec 20 09:56:07 2007 +000020.2 +++ b/src/bootstrap.c Tue Jan 15 20:50:23 2008 +000020.3 @@ -1,5 +1,5 @@20.4 /**20.5 - * $Id: bootstrap.c,v 1.9 2007-11-08 11:54:16 nkeynes Exp $20.6 + * $Id$20.7 *20.8 * CD Bootstrap header parsing. Mostly for informational purposes.20.9 *
21.1 --- a/src/bootstrap.h Thu Dec 20 09:56:07 2007 +000021.2 +++ b/src/bootstrap.h Tue Jan 15 20:50:23 2008 +000021.3 @@ -1,5 +1,5 @@21.4 /**21.5 - * $Id: bootstrap.h,v 1.6 2007-11-08 11:54:16 nkeynes Exp $21.6 + * $Id$21.7 *21.8 * CD Bootstrap header parsing. Mostly for informational purposes.21.9 *
22.1 --- a/src/clock.h Thu Dec 20 09:56:07 2007 +000022.2 +++ b/src/clock.h Tue Jan 15 20:50:23 2008 +000022.3 @@ -1,5 +1,5 @@22.4 /**22.5 - * $Id: clock.h,v 1.5 2007-01-06 04:06:36 nkeynes Exp $22.6 + * $Id$22.7 * External interface to the dreamcast serial port, implemented by22.8 * sh4/scif.c22.9 *
23.1 --- a/src/config.c Thu Dec 20 09:56:07 2007 +000023.2 +++ b/src/config.c Tue Jan 15 20:50:23 2008 +000023.3 @@ -1,5 +1,5 @@23.4 /**23.5 - * $Id: config.c,v 1.7 2007-10-31 11:53:35 nkeynes Exp $23.6 + * $Id$23.7 *23.8 * User configuration support23.9 *
24.1 --- a/src/config.h Thu Dec 20 09:56:07 2007 +000024.2 +++ b/src/config.h Tue Jan 15 20:50:23 2008 +000024.3 @@ -1,5 +1,5 @@24.4 /**24.5 - * $Id: config.h,v 1.5 2007-10-28 08:29:29 nkeynes Exp $24.6 + * $Id$24.7 *24.8 * User configuration support24.9 *
25.1 --- a/src/cpu.h Thu Dec 20 09:56:07 2007 +000025.2 +++ b/src/cpu.h Tue Jan 15 20:50:23 2008 +000025.3 @@ -1,5 +1,5 @@25.4 /**25.5 - * $Id: cpu.h,v 1.9 2007-10-08 11:50:15 nkeynes Exp $25.6 + * $Id$25.7 *25.8 * Generic CPU definitions, primarily for providing information to the GUI.25.9 *25.10 @@ -19,9 +19,8 @@25.11 #ifndef dream_cpu_H25.12 #define dream_cpu_H 125.14 -#include <stdint.h>25.15 -#include <stdlib.h>25.16 -#include <glib/gtypes.h>25.17 +#include "lxdream.h"25.18 +#include "mem.h"25.20 #ifdef __cplusplus25.21 extern "C" {25.22 @@ -58,8 +57,8 @@25.23 disasm_func_t disasm_func; /* Disassembly function */25.24 gboolean (*step_func)(); /* Single step function */25.25 int (*is_valid_page_func)(uint32_t); /* Test for valid memory page */25.26 - void (*set_breakpoint)(uint32_t, int);25.27 - gboolean (*clear_breakpoint)(uint32_t, int);25.28 + void (*set_breakpoint)(uint32_t, breakpoint_type_t);25.29 + gboolean (*clear_breakpoint)(uint32_t, breakpoint_type_t);25.30 int (*get_breakpoint)(uint32_t);25.31 size_t instr_size; /* Size of instruction */25.32 char *regs; /* Pointer to start of registers */
26.1 --- a/src/dcload.c Thu Dec 20 09:56:07 2007 +000026.2 +++ b/src/dcload.c Tue Jan 15 20:50:23 2008 +000026.3 @@ -1,5 +1,5 @@26.4 /**26.5 - * $Id: dcload.c,v 1.8 2007-11-08 11:54:16 nkeynes Exp $26.6 + * $Id$26.7 *26.8 * DC-load syscall implementation.26.9 *26.10 @@ -24,7 +24,7 @@26.11 #include "mem.h"26.12 #include "dreamcast.h"26.13 #include "syscall.h"26.14 -#include "sh4/sh4core.h"26.15 +#include "sh4/sh4.h"26.17 #define SYS_READ 026.18 #define SYS_WRITE 1
27.1 --- a/src/display.c Thu Dec 20 09:56:07 2007 +000027.2 +++ b/src/display.c Tue Jan 15 20:50:23 2008 +000027.3 @@ -1,5 +1,5 @@27.4 /**27.5 - * $Id: display.c,v 1.12 2007-10-31 09:10:23 nkeynes Exp $27.6 + * $Id$27.7 *27.8 * Generic support for keyboard and other input sources. The active display27.9 * driver is expected to deliver events here, where they're translated and
28.1 --- a/src/display.h Thu Dec 20 09:56:07 2007 +000028.2 +++ b/src/display.h Tue Jan 15 20:50:23 2008 +000028.3 @@ -1,5 +1,5 @@28.4 /**28.5 - * $Id: display.h,v 1.12 2007-11-08 11:54:16 nkeynes Exp $28.6 + * $Id$28.7 *28.8 * The PC side of the video support (responsible for actually displaying /28.9 * rendering frames)
29.1 --- a/src/dream.h Thu Dec 20 09:56:07 2007 +000029.2 +++ b/src/dream.h Tue Jan 15 20:50:23 2008 +000029.3 @@ -1,5 +1,5 @@29.4 /**29.5 - * $Id: dream.h,v 1.17 2007-11-07 11:45:53 nkeynes Exp $29.6 + * $Id$29.7 *29.8 * Miscellaneous application-wide declarations (mainly logging atm)29.9 *
30.1 --- a/src/dreamcast.c Thu Dec 20 09:56:07 2007 +000030.2 +++ b/src/dreamcast.c Tue Jan 15 20:50:23 2008 +000030.3 @@ -1,5 +1,5 @@30.4 /**30.5 - * $Id: dreamcast.c,v 1.28 2007-10-31 11:53:35 nkeynes Exp $30.6 + * $Id$30.7 * Central switchboard for the system. This pulls all the individual modules30.8 * together into some kind of coherent structure. This is also where you'd30.9 * add Naomi support, if I ever get a board to play with...30.10 @@ -27,6 +27,7 @@30.11 #include "dreamcast.h"30.12 #include "gdrom/ide.h"30.13 #include "maple/maple.h"30.14 +#include "sh4/sh4trans.h"30.16 /**30.17 * Current state of the DC virtual machine30.18 @@ -131,6 +132,9 @@30.19 void dreamcast_reset( void )30.20 {30.21 int i;30.22 + if( sh4_xlat_is_running() ) {30.23 + sh4_translate_exit( XLAT_EXIT_SYSRESET );30.24 + }30.25 for( i=0; i<num_modules; i++ ) {30.26 if( modules[i]->reset != NULL )30.27 modules[i]->reset();30.28 @@ -201,6 +205,9 @@30.30 void dreamcast_stop( void )30.31 {30.32 + if( sh4_xlat_is_running() ) {30.33 + sh4_translate_exit( XLAT_EXIT_HALT );30.34 + }30.35 if( dreamcast_state == STATE_RUNNING )30.36 dreamcast_state = STATE_STOPPING;30.37 }30.38 @@ -219,9 +226,7 @@30.39 dreamcast_program_name = g_strdup(name);30.40 dreamcast_entry_point = entry_point;30.41 sh4_set_pc(entry_point);30.42 - if( !dreamcast_has_bios ) {30.43 - bios_install();30.44 - }30.45 + bios_install();30.46 dcload_install();30.47 gui_update_state();30.48 }
31.1 --- a/src/dreamcast.h Thu Dec 20 09:56:07 2007 +000031.2 +++ b/src/dreamcast.h Tue Jan 15 20:50:23 2008 +000031.3 @@ -1,5 +1,5 @@31.4 /**31.5 - * $Id: dreamcast.h,v 1.22 2007-11-06 08:35:33 nkeynes Exp $31.6 + * $Id$31.7 *31.8 * Public interface for dreamcast.c -31.9 * Central switchboard for the system. This pulls all the individual modules31.10 @@ -60,7 +60,7 @@31.11 void dreamcast_program_loaded( const gchar *name, sh4addr_t entry_point );31.13 #define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"31.14 -#define DREAMCAST_SAVE_VERSION 0x0001000231.15 +#define DREAMCAST_SAVE_VERSION 0x0001000331.17 int dreamcast_save_state( const gchar *filename );31.18 int dreamcast_load_state( const gchar *filename );
32.1 --- a/src/drivers/audio_esd.c Thu Dec 20 09:56:07 2007 +000032.2 +++ b/src/drivers/audio_esd.c Tue Jan 15 20:50:23 2008 +000032.3 @@ -1,5 +1,5 @@32.4 /**32.5 - * $Id: audio_esd.c,v 1.9 2007-10-07 05:42:25 nkeynes Exp $32.6 + * $Id$32.7 *32.8 * The esd (esound) audio driver32.9 *
33.1 --- a/src/drivers/audio_null.c Thu Dec 20 09:56:07 2007 +000033.2 +++ b/src/drivers/audio_null.c Tue Jan 15 20:50:23 2008 +000033.3 @@ -1,5 +1,5 @@33.4 /**33.5 - * $Id: audio_null.c,v 1.3 2006-03-14 12:45:53 nkeynes Exp $33.6 + * $Id$33.7 *33.8 * The "null" audio driver, which just discards all input without even33.9 * looking at it.
34.1 --- a/src/drivers/cd_linux.c Thu Dec 20 09:56:07 2007 +000034.2 +++ b/src/drivers/cd_linux.c Tue Jan 15 20:50:23 2008 +000034.3 @@ -1,5 +1,5 @@34.4 /**34.5 - * $Id: linux.c,v 1.9 2007-11-04 05:07:49 nkeynes Exp $34.6 + * $Id$34.7 *34.8 * Linux cd-rom device driver.34.9 *
35.1 --- a/src/drivers/cd_none.c Thu Dec 20 09:56:07 2007 +000035.2 +++ b/src/drivers/cd_none.c Tue Jan 15 20:50:23 2008 +000035.3 @@ -1,5 +1,5 @@35.4 /**35.5 - * $Id: cdnone.c,v 1.1 2007-11-04 05:07:49 nkeynes Exp $35.6 + * $Id$35.7 *35.8 * The "null" cdrom device driver. Just provides a couple of empty stubs.35.9 *
36.1 --- a/src/drivers/gl_common.c Thu Dec 20 09:56:07 2007 +000036.2 +++ b/src/drivers/gl_common.c Tue Jan 15 20:50:23 2008 +000036.3 @@ -1,5 +1,5 @@36.4 /**36.5 - * $Id: gl_common.c,v 1.7 2007-10-31 12:05:23 nkeynes Exp $36.6 + * $Id$36.7 *36.8 * Common GL code that doesn't depend on a specific implementation36.9 *36.10 @@ -102,11 +102,11 @@36.11 {36.12 float top, bottom;36.13 if( inverted ) {36.14 - top = ((float)height) - 0.5;36.15 - bottom = 0.5;36.16 + top = ((float)height);36.17 + bottom = 0;36.18 } else {36.19 - top = 0.5;36.20 - bottom = ((float)height) - 0.5;36.21 + top = 0;36.22 + bottom = ((float)height);36.23 }36.25 /* Reset display parameters */36.26 @@ -156,13 +156,13 @@36.27 glEnable( GL_BLEND );36.28 glBlendFunc( GL_ONE, GL_ZERO );36.29 glBegin( GL_QUADS );36.30 - glTexCoord2f( 0.5, top );36.31 + glTexCoord2f( 0, top );36.32 glVertex2f( x1, y1 );36.33 - glTexCoord2f( ((float)width)-0.5, top );36.34 + glTexCoord2f( ((float)width), top );36.35 glVertex2f( x2, y1 );36.36 - glTexCoord2f( ((float)width)-0.5, bottom );36.37 + glTexCoord2f( ((float)width), bottom );36.38 glVertex2f( x2, y2 );36.39 - glTexCoord2f( 0.5, bottom );36.40 + glTexCoord2f( 0, bottom );36.41 glVertex2f( x1, y2 );36.42 glEnd();36.43 glDisable( GL_TEXTURE_RECTANGLE_ARB );
37.1 --- a/src/drivers/gl_common.h Thu Dec 20 09:56:07 2007 +000037.2 +++ b/src/drivers/gl_common.h Tue Jan 15 20:50:23 2008 +000037.3 @@ -1,5 +1,5 @@37.4 /**37.5 - * $Id: gl_common.h,v 1.5 2007-10-31 09:10:23 nkeynes Exp $37.6 + * $Id$37.7 *37.8 * Parent for all X11 display drivers.37.9 *
38.1 --- a/src/drivers/gl_fbo.c Thu Dec 20 09:56:07 2007 +000038.2 +++ b/src/drivers/gl_fbo.c Tue Jan 15 20:50:23 2008 +000038.3 @@ -1,5 +1,5 @@38.4 /**38.5 - * $Id: gl_fbo.c,v 1.7 2007-10-31 09:10:23 nkeynes Exp $38.6 + * $Id$38.7 *38.8 * GL framebuffer-based driver shell. This requires the EXT_framebuffer_object38.9 * extension, but is much nicer/faster/etc than pbuffers when it's available.
39.1 --- a/src/drivers/gl_sl.c Thu Dec 20 09:56:07 2007 +000039.2 +++ b/src/drivers/gl_sl.c Tue Jan 15 20:50:23 2008 +000039.3 @@ -1,5 +1,5 @@39.4 /**39.5 - * $Id: gl_sl.c,v 1.3 2007-10-31 09:10:23 nkeynes Exp $39.6 + * $Id$39.7 *39.8 * GLSL shader loader/unloader. Current version assumes there's exactly39.9 * 1 shader program that's used globally. This may turn out not to be the
40.1 --- a/src/drivers/video_glx.c Thu Dec 20 09:56:07 2007 +000040.2 +++ b/src/drivers/video_glx.c Tue Jan 15 20:50:23 2008 +000040.3 @@ -1,5 +1,5 @@40.4 /**40.5 - * $Id: video_x11.c,v 1.20 2007-10-31 12:05:23 nkeynes Exp $40.6 + * $Id$40.7 *40.8 * Shared functions for all X11-based display drivers.40.9 *40.10 @@ -16,13 +16,12 @@40.11 * GNU General Public License for more details.40.12 */40.14 +#include "display.h"40.15 +#include "pvr2/pvr2.h"40.16 +#include "drivers/gl_common.h"40.17 #include <X11/Xlib.h>40.18 #include <GL/glx.h>40.19 -#include <GL/gl.h>40.20 -#include "dream.h"40.21 -#include "pvr2/pvr2.h"40.22 #include "drivers/video_glx.h"40.23 -#include "drivers/gl_common.h"40.25 /**40.26 * General X11 parameters. The front-end driver is expected to set this up
41.1 --- a/src/drivers/video_glx.h Thu Dec 20 09:56:07 2007 +000041.2 +++ b/src/drivers/video_glx.h Tue Jan 15 20:50:23 2008 +000041.3 @@ -1,5 +1,5 @@41.4 /**41.5 - * $Id: video_glx.h,v 1.5 2007-09-08 04:05:35 nkeynes Exp $41.6 + * $Id$41.7 *41.8 * Parent for all glx-based display drivers.41.9 *
42.1 --- a/src/drivers/video_gtk.c Thu Dec 20 09:56:07 2007 +000042.2 +++ b/src/drivers/video_gtk.c Tue Jan 15 20:50:23 2008 +000042.3 @@ -1,5 +1,5 @@42.4 /**42.5 - * $Id: video_gtk.c,v 1.19 2007-10-31 12:43:51 nkeynes Exp $42.6 + * $Id$42.7 *42.8 * The PC side of the video support (responsible for actually displaying /42.9 * rendering frames)42.10 @@ -24,6 +24,7 @@42.11 #include "display.h"42.12 #include "drivers/video_glx.h"42.13 #include "drivers/gl_common.h"42.14 +#include "pvr2/pvr2.h"42.15 #include "gtkui/gtkui.h"42.17 static GtkWidget *video_win = NULL;
43.1 --- a/src/drivers/video_null.c Thu Dec 20 09:56:07 2007 +000043.2 +++ b/src/drivers/video_null.c Tue Jan 15 20:50:23 2008 +000043.3 @@ -1,5 +1,5 @@43.4 /**43.5 - * $Id: video_null.c,v 1.7 2007-10-31 12:05:23 nkeynes Exp $43.6 + * $Id$43.7 *43.8 * Null video output driver (ie no video output whatsoever)43.9 *
44.1 --- a/src/eventq.c Thu Dec 20 09:56:07 2007 +000044.2 +++ b/src/eventq.c Tue Jan 15 20:50:23 2008 +000044.3 @@ -1,5 +1,5 @@44.4 /**44.5 - * $Id: eventq.c,v 1.2 2007-10-06 08:59:42 nkeynes Exp $44.6 + * $Id$44.7 *44.8 * Simple implementation of one-shot timers. Effectively this allows IO44.9 * devices to wait until a particular time before completing. We expect44.10 @@ -23,7 +23,7 @@44.11 #include "dreamcast.h"44.12 #include "eventq.h"44.13 #include "asic.h"44.14 -#include "sh4core.h"44.15 +#include "sh4.h"44.17 #define LONG_SCAN_PERIOD 1000000000 /* 1 second */
45.1 --- a/src/eventq.h Thu Dec 20 09:56:07 2007 +000045.2 +++ b/src/eventq.h Tue Jan 15 20:50:23 2008 +000045.3 @@ -1,5 +1,5 @@45.4 /**45.5 - * $Id: eventq.h,v 1.1 2007-01-06 04:06:36 nkeynes Exp $45.6 + * $Id$45.7 *45.8 * Simple implementation of one-shot timers. Effectively this allows IO45.9 * devices to wait until a particular time before completing. We expect
46.1 --- a/src/gdrom/cdi.c Thu Dec 20 09:56:07 2007 +000046.2 +++ b/src/gdrom/cdi.c Tue Jan 15 20:50:23 2008 +000046.3 @@ -1,5 +1,5 @@46.4 /**46.5 - * $Id: cdi.c,v 1.10 2007-10-28 07:23:46 nkeynes Exp $46.6 + * $Id$46.7 *46.8 * CDI CD-image file support46.9 *
47.1 --- a/src/gdrom/cdi.h Thu Dec 20 09:56:07 2007 +000047.2 +++ b/src/gdrom/cdi.h Tue Jan 15 20:50:23 2008 +000047.3 @@ -1,5 +1,5 @@47.4 /**47.5 - * $Id: cdi.h,v 1.2 2005-12-25 08:24:11 nkeynes Exp $47.6 + * $Id$47.7 *47.8 * CDI CD-image file support47.9 *
48.1 --- a/src/gdrom/gdi.c Thu Dec 20 09:56:07 2007 +000048.2 +++ b/src/gdrom/gdi.c Tue Jan 15 20:50:23 2008 +000048.3 @@ -1,5 +1,5 @@48.4 /**48.5 - * $Id: gdi.c,v 1.2 2007-11-08 10:48:41 nkeynes Exp $48.6 + * $Id$48.7 *48.8 * NullDC GDI image format48.9 *
49.1 --- a/src/gdrom/gdimage.c Thu Dec 20 09:56:07 2007 +000049.2 +++ b/src/gdrom/gdimage.c Tue Jan 15 20:50:23 2008 +000049.3 @@ -1,5 +1,5 @@49.4 /**49.5 - * $Id: gdimage.c,v 1.7 2007-11-08 10:48:41 nkeynes Exp $49.6 + * $Id$49.7 *49.8 * GD-Rom image-file common functions.49.9 *
50.1 --- a/src/gdrom/gdrom.c Thu Dec 20 09:56:07 2007 +000050.2 +++ b/src/gdrom/gdrom.c Tue Jan 15 20:50:23 2008 +000050.3 @@ -1,6 +1,6 @@50.5 /**50.6 - * $Id: gdrom.c,v 1.19 2007-11-06 08:35:16 nkeynes Exp $50.7 + * $Id$50.8 *50.9 * GD-Rom access functions.50.10 *
51.1 --- a/src/gdrom/gdrom.h Thu Dec 20 09:56:07 2007 +000051.2 +++ b/src/gdrom/gdrom.h Tue Jan 15 20:50:23 2008 +000051.3 @@ -1,5 +1,5 @@51.4 /**51.5 - * $Id: gdrom.h,v 1.16 2007-11-06 08:35:16 nkeynes Exp $51.6 + * $Id$51.7 *51.8 * This file defines the structures and functions used by the GD-Rom51.9 * disc driver. (ie, the modules that supply a CD image to be used by the
52.1 --- a/src/gdrom/ide.c Thu Dec 20 09:56:07 2007 +000052.2 +++ b/src/gdrom/ide.c Tue Jan 15 20:50:23 2008 +000052.3 @@ -1,5 +1,5 @@52.4 /**52.5 - * $Id: ide.c,v 1.27 2007-11-06 08:35:33 nkeynes Exp $52.6 + * $Id$52.7 *52.8 * IDE interface implementation52.9 *
53.1 --- a/src/gdrom/ide.h Thu Dec 20 09:56:07 2007 +000053.2 +++ b/src/gdrom/ide.h Tue Jan 15 20:50:23 2008 +000053.3 @@ -1,5 +1,5 @@53.4 /**53.5 - * $Id: ide.h,v 1.14 2007-11-06 08:35:33 nkeynes Exp $53.6 + * $Id$53.7 *53.8 * This file defines the interface and structures of the dreamcast's IDE53.9 * port. Note that the register definitions are in asic.h, as the registers
54.1 --- a/src/gdrom/nrg.c Thu Dec 20 09:56:07 2007 +000054.2 +++ b/src/gdrom/nrg.c Tue Jan 15 20:50:23 2008 +000054.3 @@ -1,5 +1,5 @@54.4 /**54.5 - * $Id: nrg.c,v 1.7 2007-10-28 07:23:46 nkeynes Exp $54.6 + * $Id$54.7 *54.8 * Nero (NRG) CD file format. File information stolen shamelessly from54.9 * libcdio.
55.1 --- a/src/gdrom/packet.h Thu Dec 20 09:56:07 2007 +000055.2 +++ b/src/gdrom/packet.h Tue Jan 15 20:50:23 2008 +000055.3 @@ -1,5 +1,5 @@55.4 /**55.5 - * $Id: packet.h,v 1.8 2007-11-06 08:35:33 nkeynes Exp $55.6 + * $Id$55.7 *55.8 * This file defines the command codes and any other flags used by the55.9 * GD-Rom ATAPI packet commands.
56.1 --- a/src/gtkui/ctrl_dlg.c Thu Dec 20 09:56:07 2007 +000056.2 +++ b/src/gtkui/ctrl_dlg.c Tue Jan 15 20:50:23 2008 +000056.3 @@ -1,5 +1,5 @@56.4 /**56.5 - * $Id: ctrl_dlg.c,v 1.6 2007-11-10 04:45:29 nkeynes Exp $56.6 + * $Id$56.7 *56.8 * Define the main (emu) GTK window, along with its menubars,56.9 * toolbars, etc.
57.1 --- a/src/gtkui/debug_win.c Thu Dec 20 09:56:07 2007 +000057.2 +++ b/src/gtkui/debug_win.c Tue Jan 15 20:50:23 2008 +000057.3 @@ -1,5 +1,5 @@57.4 /**57.5 - * $Id: debug_win.c,v 1.29 2007-11-10 04:45:29 nkeynes Exp $57.6 + * $Id$57.7 * This file is responsible for the main debugger gui frame.57.8 *57.9 * Copyright (c) 2005 Nathan Keynes.57.10 @@ -70,7 +70,7 @@57.11 GtkWidget *vbox;57.13 data->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);57.14 - gtk_window_set_default_size (GTK_WINDOW (data->window), 640, 480);57.15 + gtk_window_set_default_size (GTK_WINDOW (data->window), 700, 480);57.16 gtk_window_set_title( GTK_WINDOW(data->window), title );57.17 gtk_window_add_accel_group (GTK_WINDOW (data->window), accel_group);57.19 @@ -79,7 +79,7 @@57.20 data->statusbar = gtk_statusbar_new();57.22 GtkWidget *hpaned = gtk_hpaned_new ();57.23 - gtk_paned_set_position (GTK_PANED (hpaned), 800);57.24 + gtk_paned_set_position (GTK_PANED (hpaned), 500);57.26 GtkWidget *disasm_box = gtk_vbox_new(FALSE,0);57.27 gtk_paned_pack1 (GTK_PANED (hpaned), disasm_box, TRUE, TRUE);
58.1 --- a/src/gtkui/dump_win.c Thu Dec 20 09:56:07 2007 +000058.2 +++ b/src/gtkui/dump_win.c Tue Jan 15 20:50:23 2008 +000058.3 @@ -1,5 +1,5 @@58.4 /**58.5 - * $Id: dump_win.c,v 1.7 2007-10-31 12:23:19 nkeynes Exp $58.6 + * $Id$58.7 *58.8 * Implements the memory dump window.58.9 *
59.1 --- a/src/gtkui/gdrom_menu.c Thu Dec 20 09:56:07 2007 +000059.2 +++ b/src/gtkui/gdrom_menu.c Tue Jan 15 20:50:23 2008 +000059.3 @@ -1,5 +1,5 @@59.4 /**59.5 - * $Id: gdrom_menu.c,v 1.5 2007-11-10 04:45:29 nkeynes Exp $59.6 + * $Id$59.7 *59.8 * Creates and manages the GD-Rom attachment menu.59.9 *
60.1 --- a/src/gtkui/gtkcb.c Thu Dec 20 09:56:07 2007 +000060.2 +++ b/src/gtkui/gtkcb.c Tue Jan 15 20:50:23 2008 +000060.3 @@ -1,5 +1,5 @@60.4 /**60.5 - * $Id: gtkcb.c,v 1.9 2007-11-10 04:45:29 nkeynes Exp $60.6 + * $Id$60.7 *60.8 * Action callbacks from the main window60.9 *
61.1 --- a/src/gtkui/gtkui.c Thu Dec 20 09:56:07 2007 +000061.2 +++ b/src/gtkui/gtkui.c Tue Jan 15 20:50:23 2008 +000061.3 @@ -1,5 +1,5 @@61.4 /**61.5 - * $Id: gtkui.c,v 1.12 2007-11-10 04:45:29 nkeynes Exp $61.6 + * $Id$61.7 *61.8 * Core GTK-based user interface61.9 *
62.1 --- a/src/gtkui/gtkui.h Thu Dec 20 09:56:07 2007 +000062.2 +++ b/src/gtkui/gtkui.h Tue Jan 15 20:50:23 2008 +000062.3 @@ -1,5 +1,5 @@62.4 /**62.5 - * $Id: gtkui.h,v 1.12 2007-11-10 04:45:29 nkeynes Exp $62.6 + * $Id$62.7 *62.8 * Core GTK-based user interface62.9 *
63.1 --- a/src/gtkui/main_win.c Thu Dec 20 09:56:07 2007 +000063.2 +++ b/src/gtkui/main_win.c Tue Jan 15 20:50:23 2008 +000063.3 @@ -1,5 +1,5 @@63.4 /**63.5 - * $Id: main_win.c,v 1.10 2007-11-08 10:46:41 nkeynes Exp $63.6 + * $Id$63.7 *63.8 * Define the main (emu) GTK window, along with its menubars,63.9 * toolbars, etc.
64.1 --- a/src/gtkui/mmio_win.c Thu Dec 20 09:56:07 2007 +000064.2 +++ b/src/gtkui/mmio_win.c Tue Jan 15 20:50:23 2008 +000064.3 @@ -1,5 +1,5 @@64.4 /**64.5 - * $Id: mmio_win.c,v 1.11 2007-11-10 04:45:29 nkeynes Exp $64.6 + * $Id$64.7 *64.8 * Implements the MMIO register viewing window64.9 *64.10 @@ -121,6 +121,10 @@64.11 gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(scroll) );64.13 trace_button = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(_("Trace access")));64.14 + if( io_rgn != NULL ) {64.15 + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trace_button),64.16 + io_rgn->trace_flag ? TRUE : FALSE);64.17 + }64.18 gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(trace_button) );64.19 gtk_box_set_child_packing( GTK_BOX(vbox), GTK_WIDGET(trace_button),64.20 FALSE, FALSE, 0, GTK_PACK_START );
65.1 --- a/src/gtkui/path_dlg.c Thu Dec 20 09:56:07 2007 +000065.2 +++ b/src/gtkui/path_dlg.c Tue Jan 15 20:50:23 2008 +000065.3 @@ -1,5 +1,5 @@65.4 /**65.5 - * $Id: path_dlg.c,v 1.5 2007-11-10 04:45:29 nkeynes Exp $65.6 + * $Id$65.7 *65.8 * Define the main (emu) GTK window, along with its menubars,65.9 * toolbars, etc.
66.1 --- a/src/gui.h Thu Dec 20 09:56:07 2007 +000066.2 +++ b/src/gui.h Tue Jan 15 20:50:23 2008 +000066.3 @@ -1,5 +1,5 @@66.4 /**66.5 - * $Id: gui.h,v 1.3 2007-10-31 11:53:35 nkeynes Exp $66.6 + * $Id$66.7 *66.8 * Public GUI declarations (used from elsewhere in the system)66.9 *
67.1 --- a/src/loader.c Thu Dec 20 09:56:07 2007 +000067.2 +++ b/src/loader.c Tue Jan 15 20:50:23 2008 +000067.3 @@ -1,5 +1,5 @@67.4 /**67.5 - * $Id: loader.c,v 1.22 2007-11-08 11:54:16 nkeynes Exp $67.6 + * $Id$67.7 *67.8 * File loading routines, mostly for loading demos without going through the67.9 * whole procedure of making a CD image for them.
68.1 --- a/src/loader.h Thu Dec 20 09:56:07 2007 +000068.2 +++ b/src/loader.h Tue Jan 15 20:50:23 2008 +000068.3 @@ -1,5 +1,5 @@68.4 /**68.5 - * $Id: loader.h,v 1.2 2007-10-07 06:21:14 nkeynes Exp $68.6 + * $Id$68.7 *68.8 * Interface declarations for the binary loader routines (loader.c, elf.c)68.9 *
69.1 --- a/src/lxdream.h Thu Dec 20 09:56:07 2007 +000069.2 +++ b/src/lxdream.h Tue Jan 15 20:50:23 2008 +000069.3 @@ -1,5 +1,5 @@69.4 /**69.5 - * $Id: lxdream.h,v 1.4 2007-11-10 04:44:51 nkeynes Exp $69.6 + * $Id$69.7 *69.8 * Common type definitions and forward declarations69.9 *69.10 @@ -39,9 +39,15 @@69.11 #endif69.13 /**69.14 - * A 32-bit address in SH4 space69.15 + * A 29-bit address in SH4 external address space69.16 */69.17 typedef uint32_t sh4addr_t;69.18 +69.19 +/**69.20 + * A 32-bit address in SH4 virtual address space.69.21 + */69.22 +typedef uint32_t sh4vma_t;69.23 +69.24 /**69.25 * A direct pointer into SH4 memory69.26 */69.27 @@ -67,6 +73,7 @@69.28 #define MODULE_NAME "*****"69.29 #endif69.31 +gboolean set_global_log_level( const gchar *level );69.32 void log_message( void *, int level, const char *source, const char *msg, ... );69.34 #define FATAL( ... ) log_message( NULL, EMIT_FATAL, MODULE_NAME, __VA_ARGS__ )
70.1 --- a/src/main.c Thu Dec 20 09:56:07 2007 +000070.2 +++ b/src/main.c Tue Jan 15 20:50:23 2008 +000070.3 @@ -1,5 +1,5 @@70.4 /**70.5 - * $Id: main.c,v 1.35 2007-11-07 11:45:53 nkeynes Exp $70.6 + * $Id$70.7 *70.8 * Main program, initializes dreamcast and gui, then passes control off to70.9 * the main loop.70.10 @@ -30,18 +30,20 @@70.11 #include "aica/audio.h"70.12 #include "gdrom/gdrom.h"70.13 #include "maple/maple.h"70.14 -#include "sh4/sh4core.h"70.15 +#include "sh4/sh4.h"70.17 #define S3M_PLAYER "s3mplay.bin"70.19 -char *option_list = "a:m:s:A:V:puhbd:c:t:xD";70.20 +char *option_list = "a:m:s:A:V:v:puhbd:c:t:T:xDn";70.21 struct option longopts[1] = { { NULL, 0, 0, 0 } };70.22 char *aica_program = NULL;70.23 char *s3m_file = NULL;70.24 const char *disc_file = NULL;70.25 char *display_driver_name = NULL;70.26 char *audio_driver_name = NULL;70.27 +char *trace_regions = NULL;70.28 gboolean start_immediately = FALSE;70.29 +gboolean no_start = FALSE;70.30 gboolean headless = FALSE;70.31 gboolean without_bios = FALSE;70.32 gboolean use_xlat = TRUE;70.33 @@ -82,6 +84,10 @@70.34 t = strtod(optarg, NULL);70.35 sh4_cpu_multiplier = (int)(1000.0/t);70.36 break;70.37 + case 'n': /* Don't start immediately */70.38 + no_start = TRUE;70.39 + start_immediately = FALSE;70.40 + break;70.41 case 's': /* AICA-only w/ S3M player */70.42 aica_program = S3M_PLAYER;70.43 s3m_file = optarg;70.44 @@ -94,6 +100,7 @@70.45 break;70.46 case 'p': /* Start immediately */70.47 start_immediately = TRUE;70.48 + no_start = FALSE;70.49 break;70.50 case 'u': /* Allow unsafe dcload syscalls */70.51 dcload_set_allow_unsafe(TRUE);70.52 @@ -109,6 +116,14 @@70.53 time_secs = (uint32_t)t;70.54 time_nanos = (int)((t - time_secs) * 1000000000);70.55 break;70.56 + case 'T': /* trace regions */70.57 + trace_regions = optarg;70.58 + break;70.59 + case 'v': /* Log verbosity */70.60 + if( !set_global_log_level(optarg) ) {70.61 + ERROR( "Unrecognized log level '%s'", optarg );70.62 + }70.63 + break;70.64 case 'x': /* Disable translator */70.65 use_xlat = FALSE;70.66 break;70.67 @@ -126,6 +141,7 @@70.68 mem_load_block( s3m_file, 0x00810000, 2048*1024 - 0x10000 );70.69 }70.70 }70.71 + mem_set_trace( trace_regions, TRUE );70.73 if( without_bios ) {70.74 bios_install();70.75 @@ -169,7 +185,9 @@70.76 if( !ok ) {70.77 ERROR( "Unrecognized file '%s'", argv[optind] );70.78 }70.79 - start_immediately = ok;70.80 + if( !no_start ) {70.81 + start_immediately = ok;70.82 + }70.83 }70.85 if( disc_file != NULL ) {
71.1 --- a/src/maple/controller.c Thu Dec 20 09:56:07 2007 +000071.2 +++ b/src/maple/controller.c Tue Jan 15 20:50:23 2008 +000071.3 @@ -1,5 +1,5 @@71.4 /**71.5 - * $Id: controller.c,v 1.10 2007-11-08 11:54:16 nkeynes Exp $71.6 + * $Id$71.7 *71.8 * Implements the standard dreamcast controller71.9 *
72.1 --- a/src/maple/controller.h Thu Dec 20 09:56:07 2007 +000072.2 +++ b/src/maple/controller.h Tue Jan 15 20:50:23 2008 +000072.3 @@ -1,5 +1,5 @@72.4 /**72.5 - * $Id: controller.h,v 1.3 2006-05-20 02:40:51 nkeynes Exp $72.6 + * $Id$72.7 *72.8 * Definitions for the standard controller device72.9 *
73.1 --- a/src/maple/maple.c Thu Dec 20 09:56:07 2007 +000073.2 +++ b/src/maple/maple.c Tue Jan 15 20:50:23 2008 +000073.3 @@ -1,5 +1,5 @@73.4 /**73.5 - * $Id: maple.c,v 1.13 2007-11-06 12:23:25 nkeynes Exp $73.6 + * $Id$73.7 *73.8 * Implements the core Maple bus, including DMA transfers to and from the bus.73.9 *
74.1 --- a/src/maple/maple.h Thu Dec 20 09:56:07 2007 +000074.2 +++ b/src/maple/maple.h Tue Jan 15 20:50:23 2008 +000074.3 @@ -1,5 +1,5 @@74.4 /**74.5 - * $Id: maple.h,v 1.10 2007-11-08 11:54:16 nkeynes Exp $74.6 + * $Id$74.7 *74.8 * Maple bus definitions74.9 *
75.1 --- a/src/mem.c Thu Dec 20 09:56:07 2007 +000075.2 +++ b/src/mem.c Tue Jan 15 20:50:23 2008 +000075.3 @@ -1,5 +1,5 @@75.4 /**75.5 - * $Id: mem.c,v 1.23 2007-11-14 10:21:33 nkeynes Exp $75.6 + * $Id$75.7 * mem.c is responsible for creating and maintaining the overall system memory75.8 * map, as visible from the SH4 processor.75.9 *75.10 @@ -20,6 +20,7 @@75.11 #include <sys/types.h>75.12 #include <sys/mman.h>75.13 #include <sys/stat.h>75.14 +#include <glib/gstrfuncs.h>75.15 #include <assert.h>75.16 #include <stdint.h>75.17 #include <stdlib.h>75.18 @@ -280,7 +281,7 @@75.19 ERROR( "Unable to allocate ROM memory: %s (%s)", file, strerror(errno) );75.20 return FALSE;75.21 }75.22 - mem_map_region( mem, base, size, file, MEM_FLAG_ROM, size, base );75.23 + mem_map_region( mem, base, size, region_name, MEM_FLAG_ROM, size, base );75.24 } else {75.25 mprotect( mem, size, PROT_READ|PROT_WRITE );75.26 }75.27 @@ -377,10 +378,39 @@75.28 }75.29 }75.31 -void mem_set_trace( uint32_t addr, int flag )75.32 +struct mmio_region *mem_get_io_region_by_name( const gchar *name )75.33 {75.34 - struct mmio_region *region = mem_get_io_region(addr);75.35 - if( region != NULL )75.36 - region->trace_flag = flag;75.37 + int i;75.38 + for( i=0; i<num_io_rgns; i++ ) {75.39 + if( strcasecmp(io_rgn[i]->id, name) == 0 ) {75.40 + return io_rgn[i];75.41 + }75.42 + }75.43 + return NULL;75.44 }75.46 +void mem_set_trace( const gchar *tracelist, gboolean flag )75.47 +{75.48 + if( tracelist != NULL ) {75.49 + gchar ** tracev = g_strsplit_set( tracelist, ",:; \t\r\n", 0 );75.50 + int i;75.51 + for( i=0; tracev[i] != NULL; i++ ) {75.52 + // Special case "all" - trace everything75.53 + if( strcasecmp(tracev[i], "all") == 0 ) {75.54 + int j;75.55 + for( j=0; j<num_io_rgns; j++ ) {75.56 + io_rgn[j]->trace_flag = flag ? 1 : 0;75.57 + }75.58 + break;75.59 + }75.60 + struct mmio_region *region = mem_get_io_region_by_name( tracev[i] );75.61 + if( region == NULL ) {75.62 + WARN( "Unknown IO region '%s'", tracev[i] );75.63 + } else {75.64 + region->trace_flag = flag ? 1 : 0;75.65 + }75.66 + }75.67 + g_strfreev( tracev );75.68 + }75.69 +}75.70 +
76.1 --- a/src/mem.h Thu Dec 20 09:56:07 2007 +000076.2 +++ b/src/mem.h Tue Jan 15 20:50:23 2008 +000076.3 @@ -1,5 +1,5 @@76.4 /**76.5 - * $Id: mem.h,v 1.17 2007-11-14 10:21:33 nkeynes Exp $76.6 + * $Id$76.7 *76.8 * mem is responsible for creating and maintaining the overall system memory76.9 * map, as visible from the SH4 processor. (Note the ARM has a different map)76.10 @@ -63,7 +63,7 @@76.11 sh4ptr_t mem_get_page( uint32_t addr );76.12 int mem_load_block( const gchar *filename, uint32_t base, uint32_t size );76.13 int mem_save_block( const gchar *filename, uint32_t base, uint32_t size );76.14 -void mem_set_trace( uint32_t addr, int flag );76.15 +void mem_set_trace( const gchar *tracelist, int flag );76.16 void mem_init( void );76.17 void mem_reset( void );76.18 void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t src, size_t count );76.19 @@ -71,25 +71,23 @@76.21 #define ENABLE_DEBUG_MODE 176.23 +typedef enum { BREAK_NONE=0, BREAK_ONESHOT=1, BREAK_KEEP=2 } breakpoint_type_t;76.24 +76.25 struct breakpoint_struct {76.26 uint32_t address;76.27 - int type;76.28 + breakpoint_type_t type;76.29 };76.31 #define MAX_BREAKPOINTS 3276.32 -#define BREAK_NONE 076.33 -#define BREAK_ONESHOT 176.34 -#define BREAK_KEEP 276.36 -#undef ENABLE_WATCH76.37 +76.38 +#define MEM_FLAG_ROM 4 /* Mem region is ROM-based */76.39 +#define MEM_FLAG_RAM 676.41 #define WATCH_WRITE 176.42 #define WATCH_READ 276.43 #define WATCH_EXEC 3 /* AKA Breakpoint :) */76.45 -#define MEM_FLAG_ROM 4 /* Mem region is ROM-based */76.46 -#define MEM_FLAG_RAM 676.47 -76.48 typedef struct watch_point *watch_point_t;76.50 watch_point_t mem_new_watch( uint32_t start, uint32_t end, int flags );
77.1 --- a/src/mmio.h Thu Dec 20 09:56:07 2007 +000077.2 +++ b/src/mmio.h Tue Jan 15 20:50:23 2008 +000077.3 @@ -1,5 +1,5 @@77.4 /**77.5 - * $Id: mmio.h,v 1.8 2007-11-04 08:49:18 nkeynes Exp $77.6 + * $Id$77.7 *77.8 * mmio.h defines a complicated batch of macros used to build up the77.9 * memory-mapped I/O regions in a reasonably readable fashion.
78.1 --- a/src/pvr2/pvr2.c Thu Dec 20 09:56:07 2007 +000078.2 +++ b/src/pvr2/pvr2.c Tue Jan 15 20:50:23 2008 +000078.3 @@ -1,5 +1,5 @@78.4 /**78.5 - * $Id: pvr2.c,v 1.50 2007-11-14 10:23:28 nkeynes Exp $78.6 + * $Id$78.7 *78.8 * PVR2 (Video) Core module implementation and MMIO registers.78.9 *78.10 @@ -25,7 +25,7 @@78.11 #include "asic.h"78.12 #include "clock.h"78.13 #include "pvr2/pvr2.h"78.14 -#include "sh4/sh4core.h"78.15 +#include "sh4/sh4.h"78.16 #define MMIO_IMPL78.17 #include "pvr2/pvr2mmio.h"
79.1 --- a/src/pvr2/pvr2.h Thu Dec 20 09:56:07 2007 +000079.2 +++ b/src/pvr2/pvr2.h Tue Jan 15 20:50:23 2008 +000079.3 @@ -1,5 +1,5 @@79.4 /**79.5 - * $Id: pvr2.h,v 1.38 2007-10-31 12:05:23 nkeynes Exp $79.6 + * $Id$79.7 *79.8 * PVR2 (video chip) functions and macros.79.9 *
80.1 --- a/src/pvr2/pvr2mem.c Thu Dec 20 09:56:07 2007 +000080.2 +++ b/src/pvr2/pvr2mem.c Tue Jan 15 20:50:23 2008 +000080.3 @@ -1,5 +1,5 @@80.4 /**80.5 - * $Id: pvr2mem.c,v 1.12 2007-11-08 11:54:16 nkeynes Exp $80.6 + * $Id$80.7 *80.8 * PVR2 (Video) VRAM handling routines (mainly for the 64-bit region)80.9 *
81.1 --- a/src/pvr2/pvr2mmio.h Thu Dec 20 09:56:07 2007 +000081.2 +++ b/src/pvr2/pvr2mmio.h Tue Jan 15 20:50:23 2008 +000081.3 @@ -1,5 +1,5 @@81.4 /**81.5 - * $Id: pvr2mmio.h,v 1.9 2007-01-27 06:21:35 nkeynes Exp $81.6 + * $Id$81.7 *81.8 * PVR2 (video chip) MMIO register definitions.81.9 *
82.1 --- a/src/pvr2/rendbkg.c Thu Dec 20 09:56:07 2007 +000082.2 +++ b/src/pvr2/rendbkg.c Tue Jan 15 20:50:23 2008 +000082.3 @@ -1,5 +1,5 @@82.4 /**82.5 - * $Id: rendbkg.c,v 1.7 2007-10-08 11:52:13 nkeynes Exp $82.6 + * $Id$82.7 *82.8 * PVR2 background renderer.82.9 *
83.1 --- a/src/pvr2/rendcore.c Thu Dec 20 09:56:07 2007 +000083.2 +++ b/src/pvr2/rendcore.c Tue Jan 15 20:50:23 2008 +000083.3 @@ -1,5 +1,5 @@83.4 /**83.5 - * $Id: rendcore.c,v 1.21 2007-10-31 09:10:23 nkeynes Exp $83.6 + * $Id$83.7 *83.8 * PVR2 renderer core.83.9 *
84.1 --- a/src/pvr2/render.c Thu Dec 20 09:56:07 2007 +000084.2 +++ b/src/pvr2/render.c Tue Jan 15 20:50:23 2008 +000084.3 @@ -1,5 +1,5 @@84.4 /**84.5 - * $Id: render.c,v 1.26 2007-10-31 09:10:23 nkeynes Exp $84.6 + * $Id$84.7 *84.8 * PVR2 Renderer support. This part is primarily84.9 *
85.1 --- a/src/pvr2/rendsave.c Thu Dec 20 09:56:07 2007 +000085.2 +++ b/src/pvr2/rendsave.c Tue Jan 15 20:50:23 2008 +000085.3 @@ -1,5 +1,5 @@85.4 /**85.5 - * $Id: rendsave.c,v 1.2 2007-10-08 11:52:13 nkeynes Exp $85.6 + * $Id$85.7 *85.8 * Scene-save support. This is mainly for test/debug purposes.85.9 *
86.1 --- a/src/pvr2/rendsort.c Thu Dec 20 09:56:07 2007 +000086.2 +++ b/src/pvr2/rendsort.c Tue Jan 15 20:50:23 2008 +000086.3 @@ -1,5 +1,5 @@86.4 /**86.5 - * $Id: rendsort.c,v 1.6 2007-10-08 11:52:13 nkeynes Exp $86.6 + * $Id$86.7 *86.8 * PVR2 renderer routines for depth sorted polygons86.9 *
87.1 --- a/src/pvr2/tacore.c Thu Dec 20 09:56:07 2007 +000087.2 +++ b/src/pvr2/tacore.c Tue Jan 15 20:50:23 2008 +000087.3 @@ -1,5 +1,5 @@87.4 /**87.5 - * $Id: tacore.c,v 1.12 2007-10-08 11:52:13 nkeynes Exp $87.6 + * $Id$87.7 *87.8 * PVR2 Tile Accelerator implementation87.9 *
88.1 --- a/src/pvr2/texcache.c Thu Dec 20 09:56:07 2007 +000088.2 +++ b/src/pvr2/texcache.c Tue Jan 15 20:50:23 2008 +000088.3 @@ -1,5 +1,5 @@88.4 /**88.5 - * $Id: texcache.c,v 1.29 2007-10-31 09:10:23 nkeynes Exp $88.6 + * $Id$88.7 *88.8 * Texture cache. Responsible for maintaining a working set of OpenGL88.9 * textures.
89.1 --- a/src/pvr2/yuv.c Thu Dec 20 09:56:07 2007 +000089.2 +++ b/src/pvr2/yuv.c Tue Jan 15 20:50:23 2008 +000089.3 @@ -1,5 +1,5 @@89.4 /**89.5 - * $Id: yuv.c,v 1.5 2007-10-08 11:52:13 nkeynes Exp $89.6 + * $Id$89.7 *89.8 * YUV420 and YUV422 decoding89.9 *
90.1 --- a/src/serial.h Thu Dec 20 09:56:07 2007 +000090.2 +++ b/src/serial.h Tue Jan 15 20:50:23 2008 +000090.3 @@ -1,5 +1,5 @@90.4 /**90.5 - * $Id: serial.h,v 1.1 2005-12-22 07:38:06 nkeynes Exp $90.6 + * $Id$90.7 * External interface to the dreamcast serial port, implemented by90.8 * sh4/scif.c90.9 *
91.1 --- a/src/sh4/Makefile Thu Dec 20 09:56:07 2007 +000091.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +000091.3 @@ -1,438 +0,0 @@91.4 -# Makefile.in generated by automake 1.7.9 from Makefile.am.91.5 -# src/sh4/Makefile. Generated from Makefile.in by configure.91.6 -91.7 -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 200391.8 -# Free Software Foundation, Inc.91.9 -# This Makefile.in is free software; the Free Software Foundation91.10 -# gives unlimited permission to copy and/or distribute it,91.11 -# with or without modifications, as long as this notice is preserved.91.12 -91.13 -# This program is distributed in the hope that it will be useful,91.14 -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without91.15 -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A91.16 -# PARTICULAR PURPOSE.91.17 -91.18 -91.19 -91.20 -srcdir = .91.21 -top_srcdir = ../..91.22 -91.23 -pkgdatadir = $(datadir)/DreamOn91.24 -pkglibdir = $(libdir)/DreamOn91.25 -pkgincludedir = $(includedir)/DreamOn91.26 -top_builddir = ../..91.27 -91.28 -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd91.29 -INSTALL = /usr/bin/install -c91.30 -install_sh_DATA = $(install_sh) -c -m 64491.31 -install_sh_PROGRAM = $(install_sh) -c91.32 -install_sh_SCRIPT = $(install_sh) -c91.33 -INSTALL_HEADER = $(INSTALL_DATA)91.34 -transform = $(program_transform_name)91.35 -NORMAL_INSTALL = :91.36 -PRE_INSTALL = :91.37 -POST_INSTALL = :91.38 -NORMAL_UNINSTALL = :91.39 -PRE_UNINSTALL = :91.40 -POST_UNINSTALL = :91.41 -host_triplet = i686-pc-linux-gnu91.42 -ACLOCAL = ${SHELL} /usr/home/nkeynes/src/dream/missing --run aclocal-1.7 -I macros91.43 -ALLOCA =91.44 -AMDEP_FALSE = #91.45 -AMDEP_TRUE =91.46 -AMTAR = ${SHELL} /usr/home/nkeynes/src/dream/missing --run tar91.47 -AUTOCONF = ${SHELL} /usr/home/nkeynes/src/dream/missing --run autoconf91.48 -AUTOHEADER = ${SHELL} /usr/home/nkeynes/src/dream/missing --run autoheader91.49 -AUTOMAKE = ${SHELL} /usr/home/nkeynes/src/dream/missing --run automake-1.791.50 -AWK = gawk91.51 -BUILD_INCLUDED_LIBINTL = no91.52 -CATOBJEXT = .gmo91.53 -CC = gcc91.54 -CCDEPMODE = depmode=gcc391.55 -CFLAGS = -g -O2 -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations91.56 -CPP = gcc -E91.57 -CPPFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include91.58 -CYGPATH_W = echo91.59 -DATADIRNAME = share91.60 -DEFS = -DHAVE_CONFIG_H91.61 -DEPDIR = .deps91.62 -ECHO_C =91.63 -ECHO_N = -n91.64 -ECHO_T =91.65 -EGREP = grep -E91.66 -EXEEXT =91.67 -GENCAT = gencat91.68 -GLIBC21 = yes91.69 -GMSGFMT = /usr/bin/msgfmt91.70 -GNOMEGNORBA_LIBS = -rdynamic -lgnorba -lORBitCosNaming -lORBit -lIIOP -lORBitutil -lgnomeui -lart_lgpl -lgdk_imlib -lSM -lICE -lgtk -lgdk -lgmodule -ldl -lXi -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -ldb-3 -lglib91.71 -GNOMEUI_LIBS = -rdynamic -lgnomeui -lart_lgpl -lgdk_imlib -lSM -lICE -lgtk -lgdk -lgmodule -ldl -lXi -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -ldb-3 -lglib91.72 -GNOME_APPLETS_LIBS =91.73 -GNOME_CAPPLET_LIBS =91.74 -GNOME_CONFIG = /usr/bin/gnome-config91.75 -GNOME_DOCKLETS_LIBS =91.76 -GNOME_INCLUDEDIR = -I/usr/include/gnome-1.0 -DNEED_GNOMESUPPORT_H -I/usr/lib/gnome-libs/include -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/include/orbit-1.0 -I/usr/include/gtk-1.291.77 -GNOME_LIBDIR = -rdynamic -L/usr/lib -L/usr/X11R6/lib91.78 -GNOME_LIBS = -lgnome -lgnomesupport -lesd -laudiofile -lm -ldb-3 -lglib91.79 -GNORBA_CFLAGS = -I/usr/include/gnome-1.0 -DNEED_GNOMESUPPORT_H -I/usr/lib/gnome-libs/include -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/include/orbit-1.0 -I/usr/include/gtk-1.291.80 -GNORBA_LIBS = -rdynamic -L/usr/lib -L/usr/X11R6/lib -lgnorba -lORBitCosNaming -lORBit -lIIOP -lORBitutil -lgnomeui -lart_lgpl -lgdk_imlib -lSM -lICE -lgtk -lgdk -lgmodule -ldl -lXi -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -ldb-3 -lglib91.81 -GTKXMHTML_LIBS = -rdynamic -lgtkxmhtml -lXpm -ljpeg -lpng10 -lz -lSM -lICE -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm91.82 -GTK_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include91.83 -GTK_CONFIG = /usr/bin/gtk-config91.84 -GTK_LIBS = -lSM -lICE -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm91.85 -HAVE_ASPRINTF = 191.86 -HAVE_GNORBA_FALSE = #91.87 -HAVE_GNORBA_TRUE =91.88 -HAVE_ORBIT_FALSE = #91.89 -HAVE_ORBIT_TRUE =91.90 -HAVE_POSIX_PRINTF = 191.91 -HAVE_SNPRINTF = 191.92 -HAVE_WPRINTF = 091.93 -INSIDE_GNOME_COMMON_FALSE =91.94 -INSIDE_GNOME_COMMON_TRUE = #91.95 -INSTALL_DATA = ${INSTALL} -m 64491.96 -INSTALL_PROGRAM = ${INSTALL}91.97 -INSTALL_SCRIPT = ${INSTALL}91.98 -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s91.99 -INSTOBJEXT = .mo91.100 -INTLBISON = bison91.101 -INTLLIBS =91.102 -INTLOBJS =91.103 -INTL_LIBTOOL_SUFFIX_PREFIX =91.104 -LDFLAGS =91.105 -LIBICONV =91.106 -LIBINTL =91.107 -LIBOBJS =91.108 -LIBS =91.109 -LTLIBICONV =91.110 -LTLIBINTL =91.111 -LTLIBOBJS =91.112 -MAKEINFO = ${SHELL} /usr/home/nkeynes/src/dream/missing --run makeinfo91.113 -MKINSTALLDIRS = $(top_builddir)/./mkinstalldirs91.114 -MSGFMT = /usr/bin/msgfmt91.115 -MSGMERGE = /usr/bin/msgmerge91.116 -OBJEXT = o91.117 -ORBIT_CFLAGS = -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/include/orbit-1.091.118 -ORBIT_CONFIG = /usr/bin/orbit-config91.119 -ORBIT_IDL = /usr/bin/orbit-idl91.120 -ORBIT_LIBS = -L/usr/lib -lORBitCosNaming -lORBit -lIIOP -lORBitutil -lglib -lm91.121 -PACKAGE = DreamOn91.122 -PACKAGE_BUGREPORT =91.123 -PACKAGE_NAME =91.124 -PACKAGE_STRING =91.125 -PACKAGE_TARNAME =91.126 -PACKAGE_VERSION =91.127 -PATH_SEPARATOR = :91.128 -POSUB = po91.129 -PTHREAD_LIB = -lpthread91.130 -RANLIB = ranlib91.131 -SET_MAKE =91.132 -SHELL = /bin/sh91.133 -STRIP =91.134 -USE_INCLUDED_LIBINTL = no91.135 -USE_NLS = yes91.136 -VERSION = 0.0191.137 -XGETTEXT = /usr/bin/xgettext91.138 -XPM_LIBS = -lXpm91.139 -ZVT_LIBS = -rdynamic -lzvt -lutil -lSM -lICE -lgdk_imlib -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm91.140 -ac_ct_CC = gcc91.141 -ac_ct_RANLIB = ranlib91.142 -ac_ct_STRIP =91.143 -am__fastdepCC_FALSE = #91.144 -am__fastdepCC_TRUE =91.145 -am__include = include91.146 -am__leading_dot = .91.147 -am__quote =91.148 -bindir = ${exec_prefix}/bin91.149 -build = i686-pc-linux-gnu91.150 -build_alias =91.151 -build_cpu = i68691.152 -build_os = linux-gnu91.153 -build_vendor = pc91.154 -cflags_set = yes91.155 -datadir = ${prefix}/share91.156 -exec_prefix = ${prefix}91.157 -host = i686-pc-linux-gnu91.158 -host_alias =91.159 -host_cpu = i68691.160 -host_os = linux-gnu91.161 -host_vendor = pc91.162 -includedir = ${prefix}/include91.163 -infodir = ${prefix}/info91.164 -install_sh = /usr/home/nkeynes/src/dream/install-sh91.165 -libdir = ${exec_prefix}/lib91.166 -libexecdir = ${exec_prefix}/libexec91.167 -localstatedir = ${prefix}/var91.168 -mandir = ${prefix}/man91.169 -oldincludedir = /usr/include91.170 -prefix = /usr/local91.171 -program_transform_name = s,x,x,91.172 -sbindir = ${exec_prefix}/sbin91.173 -sharedstatedir = ${prefix}/com91.174 -sysconfdir = ${prefix}/etc91.175 -target_alias =91.176 -91.177 -INCLUDES = \91.178 - -I$(top_srcdir)/intl -I$(top_srcdir)/src91.179 -91.180 -91.181 -noinst_LIBRARIES = libsh4.a91.182 -libsh4_a_SOURCES = mem.c mem.h sh4core.c sh4core.h sh4dasm.c sh4dasm.h \91.183 - sh4mmio.c sh4mmio.h mmio.h intc.c intc.h91.184 -91.185 -91.186 -AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE91.187 -subdir = src/sh491.188 -ACLOCAL_M4 = $(top_srcdir)/aclocal.m491.189 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs91.190 -CONFIG_HEADER = $(top_builddir)/config.h91.191 -CONFIG_CLEAN_FILES =91.192 -LIBRARIES = $(noinst_LIBRARIES)91.193 -91.194 -libsh4_a_AR = $(AR) cru91.195 -libsh4_a_LIBADD =91.196 -am_libsh4_a_OBJECTS = mem.$(OBJEXT) sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) \91.197 - sh4mmio.$(OBJEXT) intc.$(OBJEXT)91.198 -libsh4_a_OBJECTS = $(am_libsh4_a_OBJECTS)91.199 -91.200 -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)91.201 -depcomp = $(SHELL) $(top_srcdir)/depcomp91.202 -am__depfiles_maybe = depfiles91.203 -DEP_FILES = ./$(DEPDIR)/intc.Po ./$(DEPDIR)/mem.Po \91.204 - ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \91.205 - ./$(DEPDIR)/sh4mmio.Po91.206 -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \91.207 - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)91.208 -CCLD = $(CC)91.209 -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@91.210 -DIST_SOURCES = $(libsh4_a_SOURCES)91.211 -DIST_COMMON = $(srcdir)/Makefile.in Makefile.am91.212 -SOURCES = $(libsh4_a_SOURCES)91.213 -91.214 -all: all-am91.215 -91.216 -.SUFFIXES:91.217 -.SUFFIXES: .c .o .obj91.218 -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)91.219 - cd $(top_srcdir) && \91.220 - $(AUTOMAKE) --gnu src/sh4/Makefile91.221 -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status91.222 - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)91.223 -91.224 -AR = ar91.225 -91.226 -clean-noinstLIBRARIES:91.227 - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)91.228 -libsh4.a: $(libsh4_a_OBJECTS) $(libsh4_a_DEPENDENCIES)91.229 - -rm -f libsh4.a91.230 - $(libsh4_a_AR) libsh4.a $(libsh4_a_OBJECTS) $(libsh4_a_LIBADD)91.231 - $(RANLIB) libsh4.a91.232 -91.233 -mostlyclean-compile:91.234 - -rm -f *.$(OBJEXT) core *.core91.235 -91.236 -distclean-compile:91.237 - -rm -f *.tab.c91.238 -91.239 -include ./$(DEPDIR)/intc.Po91.240 -include ./$(DEPDIR)/mem.Po91.241 -include ./$(DEPDIR)/sh4core.Po91.242 -include ./$(DEPDIR)/sh4dasm.Po91.243 -include ./$(DEPDIR)/sh4mmio.Po91.244 -91.245 -.c.o:91.246 - if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \91.247 - -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \91.248 - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \91.249 - else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \91.250 - fi91.251 -# source='$<' object='$@' libtool=no \91.252 -# depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \91.253 -# $(CCDEPMODE) $(depcomp) \91.254 -# $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<91.255 -91.256 -.c.obj:91.257 - if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \91.258 - -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \91.259 - then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \91.260 - else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \91.261 - fi91.262 -# source='$<' object='$@' libtool=no \91.263 -# depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \91.264 -# $(CCDEPMODE) $(depcomp) \91.265 -# $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`91.266 -uninstall-info-am:91.267 -91.268 -ETAGS = etags91.269 -ETAGSFLAGS =91.270 -91.271 -CTAGS = ctags91.272 -CTAGSFLAGS =91.273 -91.274 -tags: TAGS91.275 -91.276 -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)91.277 - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \91.278 - unique=`for i in $$list; do \91.279 - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \91.280 - done | \91.281 - $(AWK) ' { files[$$0] = 1; } \91.282 - END { for (i in files) print i; }'`; \91.283 - mkid -fID $$unique91.284 -91.285 -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \91.286 - $(TAGS_FILES) $(LISP)91.287 - tags=; \91.288 - here=`pwd`; \91.289 - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \91.290 - unique=`for i in $$list; do \91.291 - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \91.292 - done | \91.293 - $(AWK) ' { files[$$0] = 1; } \91.294 - END { for (i in files) print i; }'`; \91.295 - test -z "$(ETAGS_ARGS)$$tags$$unique" \91.296 - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \91.297 - $$tags $$unique91.298 -91.299 -ctags: CTAGS91.300 -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \91.301 - $(TAGS_FILES) $(LISP)91.302 - tags=; \91.303 - here=`pwd`; \91.304 - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \91.305 - unique=`for i in $$list; do \91.306 - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \91.307 - done | \91.308 - $(AWK) ' { files[$$0] = 1; } \91.309 - END { for (i in files) print i; }'`; \91.310 - test -z "$(CTAGS_ARGS)$$tags$$unique" \91.311 - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \91.312 - $$tags $$unique91.313 -91.314 -GTAGS:91.315 - here=`$(am__cd) $(top_builddir) && pwd` \91.316 - && cd $(top_srcdir) \91.317 - && gtags -i $(GTAGS_ARGS) $$here91.318 -91.319 -distclean-tags:91.320 - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags91.321 -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)91.322 -91.323 -top_distdir = ../..91.324 -distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)91.325 -91.326 -distdir: $(DISTFILES)91.327 - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \91.328 - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \91.329 - list='$(DISTFILES)'; for file in $$list; do \91.330 - case $$file in \91.331 - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \91.332 - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \91.333 - esac; \91.334 - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \91.335 - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \91.336 - if test "$$dir" != "$$file" && test "$$dir" != "."; then \91.337 - dir="/$$dir"; \91.338 - $(mkinstalldirs) "$(distdir)$$dir"; \91.339 - else \91.340 - dir=''; \91.341 - fi; \91.342 - if test -d $$d/$$file; then \91.343 - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \91.344 - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \91.345 - fi; \91.346 - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \91.347 - else \91.348 - test -f $(distdir)/$$file \91.349 - || cp -p $$d/$$file $(distdir)/$$file \91.350 - || exit 1; \91.351 - fi; \91.352 - done91.353 -check-am: all-am91.354 -check: check-am91.355 -all-am: Makefile $(LIBRARIES)91.356 -91.357 -installdirs:91.358 -install: install-am91.359 -install-exec: install-exec-am91.360 -install-data: install-data-am91.361 -uninstall: uninstall-am91.362 -91.363 -install-am: all-am91.364 - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am91.365 -91.366 -installcheck: installcheck-am91.367 -install-strip:91.368 - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \91.369 - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \91.370 - `test -z '$(STRIP)' || \91.371 - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install91.372 -mostlyclean-generic:91.373 -91.374 -clean-generic:91.375 -91.376 -distclean-generic:91.377 - -rm -f $(CONFIG_CLEAN_FILES)91.378 -91.379 -maintainer-clean-generic:91.380 - @echo "This command is intended for maintainers to use"91.381 - @echo "it deletes files that may require special tools to rebuild."91.382 -clean: clean-am91.383 -91.384 -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am91.385 -91.386 -distclean: distclean-am91.387 - -rm -rf ./$(DEPDIR)91.388 - -rm -f Makefile91.389 -distclean-am: clean-am distclean-compile distclean-generic \91.390 - distclean-tags91.391 -91.392 -dvi: dvi-am91.393 -91.394 -dvi-am:91.395 -91.396 -info: info-am91.397 -91.398 -info-am:91.399 -91.400 -install-data-am:91.401 -91.402 -install-exec-am:91.403 -91.404 -install-info: install-info-am91.405 -91.406 -install-man:91.407 -91.408 -installcheck-am:91.409 -91.410 -maintainer-clean: maintainer-clean-am91.411 - -rm -rf ./$(DEPDIR)91.412 - -rm -f Makefile91.413 -maintainer-clean-am: distclean-am maintainer-clean-generic91.414 -91.415 -mostlyclean: mostlyclean-am91.416 -91.417 -mostlyclean-am: mostlyclean-compile mostlyclean-generic91.418 -91.419 -pdf: pdf-am91.420 -91.421 -pdf-am:91.422 -91.423 -ps: ps-am91.424 -91.425 -ps-am:91.426 -91.427 -uninstall-am: uninstall-info-am91.428 -91.429 -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \91.430 - clean-noinstLIBRARIES ctags distclean distclean-compile \91.431 - distclean-generic distclean-tags distdir dvi dvi-am info \91.432 - info-am install install-am install-data install-data-am \91.433 - install-exec install-exec-am install-info install-info-am \91.434 - install-man install-strip installcheck installcheck-am \91.435 - installdirs maintainer-clean maintainer-clean-generic \91.436 - mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \91.437 - ps ps-am tags uninstall uninstall-am uninstall-info-am91.438 -91.439 -# Tell versions [3.59,3.63) of GNU make to not export all variables.91.440 -# Otherwise a system limit (for SysV at least) may be exceeded.91.441 -.NOEXPORT:
92.1 --- a/src/sh4/dmac.c Thu Dec 20 09:56:07 2007 +000092.2 +++ b/src/sh4/dmac.c Tue Jan 15 20:50:23 2008 +000092.3 @@ -1,5 +1,5 @@92.4 /**92.5 - * $Id: dmac.c,v 1.4 2007-11-08 11:54:16 nkeynes Exp $92.6 + * $Id$92.7 *92.8 * SH4 onboard DMA controller (DMAC) peripheral.92.9 *
93.1 --- a/src/sh4/dmac.h Thu Dec 20 09:56:07 2007 +000093.2 +++ b/src/sh4/dmac.h Tue Jan 15 20:50:23 2008 +000093.3 @@ -1,5 +1,5 @@93.4 /**93.5 - * $Id: dmac.h,v 1.2 2007-10-08 12:06:01 nkeynes Exp $93.6 + * $Id$93.7 *93.8 * SH4 onboard DMA controller (DMAC) definitions.93.9 *
94.1 --- a/src/sh4/ia32abi.h Thu Dec 20 09:56:07 2007 +000094.2 +++ b/src/sh4/ia32abi.h Tue Jan 15 20:50:23 2008 +000094.3 @@ -1,5 +1,5 @@94.4 /**94.5 - * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $94.6 + * $Id$94.7 *94.8 * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and94.9 * calling conventions)94.10 @@ -80,19 +80,16 @@94.11 {94.12 PUSH_r32(addr);94.13 call_func0(sh4_read_long);94.14 - POP_r32(addr);94.15 + POP_r32(R_ECX);94.16 PUSH_r32(R_EAX);94.17 - ADD_imm8s_r32( 4, addr );94.18 - PUSH_r32(addr);94.19 + ADD_imm8s_r32( 4, R_ECX );94.20 + PUSH_r32(R_ECX);94.21 call_func0(sh4_read_long);94.22 ADD_imm8s_r32( 4, R_ESP );94.23 MOV_r32_r32( R_EAX, arg2b );94.24 POP_r32(arg2a);94.25 }94.27 -#define EXIT_BLOCK_SIZE 2994.28 -94.29 -94.30 /**94.31 * Emit the 'start of block' assembly. Sets up the stack frame and save94.32 * SI/DI as required94.33 @@ -108,7 +105,9 @@94.34 sh4_x86.fpuen_checked = FALSE;94.35 sh4_x86.branch_taken = FALSE;94.36 sh4_x86.backpatch_posn = 0;94.37 + sh4_x86.recovery_posn = 0;94.38 sh4_x86.block_start_pc = pc;94.39 + sh4_x86.tlb_on = IS_MMU_ENABLED();94.40 sh4_x86.tstate = TSTATE_NONE;94.41 #ifdef STACK_ALIGN94.42 sh4_x86.stack_posn = 8;94.43 @@ -119,16 +118,23 @@94.44 * Exit the block with sh4r.pc already written94.45 * Bytes: 1594.46 */94.47 -void exit_block_pcset( pc )94.48 +void exit_block_pcset( sh4addr_t pc )94.49 {94.50 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 594.51 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 694.52 load_spreg( R_EAX, REG_OFFSET(pc) );94.53 - call_func1(xlat_get_code,R_EAX);94.54 + if( sh4_x86.tlb_on ) {94.55 + call_func1(xlat_get_code_by_vma,R_EAX);94.56 + } else {94.57 + call_func1(xlat_get_code,R_EAX);94.58 + }94.59 POP_r32(R_EBP);94.60 RET();94.61 }94.63 +#define EXIT_BLOCK_SIZE(pc) (24 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))94.64 +94.65 +94.66 /**94.67 * Exit the block to an absolute PC94.68 */94.69 @@ -136,7 +142,37 @@94.70 {94.71 load_imm32( R_ECX, pc ); // 594.72 store_spreg( R_ECX, REG_OFFSET(pc) ); // 394.73 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 594.74 + if( IS_IN_ICACHE(pc) ) {94.75 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 594.76 + } else if( sh4_x86.tlb_on ) {94.77 + call_func1(xlat_get_code_by_vma,R_ECX);94.78 + } else {94.79 + call_func1(xlat_get_code,R_ECX);94.80 + }94.81 + AND_imm8s_r32( 0xFC, R_EAX ); // 394.82 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 594.83 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 694.84 + POP_r32(R_EBP);94.85 + RET();94.86 +}94.87 +94.88 +#define EXIT_BLOCK_REL_SIZE(pc) (27 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))94.89 +94.90 +/**94.91 + * Exit the block to a relative PC94.92 + */94.93 +void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )94.94 +{94.95 + load_imm32( R_ECX, pc - sh4_x86.block_start_pc ); // 594.96 + ADD_sh4r_r32( R_PC, R_ECX );94.97 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 394.98 + if( IS_IN_ICACHE(pc) ) {94.99 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 594.100 + } else if( sh4_x86.tlb_on ) {94.101 + call_func1(xlat_get_code_by_vma,R_ECX);94.102 + } else {94.103 + call_func1(xlat_get_code,R_ECX);94.104 + }94.105 AND_imm8s_r32( 0xFC, R_EAX ); // 394.106 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 594.107 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 694.108 @@ -150,48 +186,87 @@94.109 void sh4_translate_end_block( sh4addr_t pc ) {94.110 if( sh4_x86.branch_taken == FALSE ) {94.111 // Didn't exit unconditionally already, so write the termination here94.112 - exit_block( pc, pc );94.113 + exit_block_rel( pc, pc );94.114 }94.115 if( sh4_x86.backpatch_posn != 0 ) {94.116 + unsigned int i;94.117 + // Raise exception94.118 uint8_t *end_ptr = xlat_output;94.119 - // Exception termination. Jump block for various exception codes:94.120 - PUSH_imm32( EXC_DATA_ADDR_READ );94.121 - JMP_rel8( 33, target1 );94.122 - PUSH_imm32( EXC_DATA_ADDR_WRITE );94.123 - JMP_rel8( 26, target2 );94.124 - PUSH_imm32( EXC_ILLEGAL );94.125 - JMP_rel8( 19, target3 );94.126 - PUSH_imm32( EXC_SLOT_ILLEGAL );94.127 - JMP_rel8( 12, target4 );94.128 - PUSH_imm32( EXC_FPU_DISABLED );94.129 - JMP_rel8( 5, target5 );94.130 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );94.131 - // target94.132 - JMP_TARGET(target1);94.133 - JMP_TARGET(target2);94.134 - JMP_TARGET(target3);94.135 - JMP_TARGET(target4);94.136 - JMP_TARGET(target5);94.137 - // Raise exception94.138 - load_spreg( R_ECX, REG_OFFSET(pc) );94.139 + MOV_r32_r32( R_EDX, R_ECX );94.140 ADD_r32_r32( R_EDX, R_ECX );94.141 - ADD_r32_r32( R_EDX, R_ECX );94.142 - store_spreg( R_ECX, REG_OFFSET(pc) );94.143 + ADD_r32_sh4r( R_ECX, R_PC );94.144 MOV_moff32_EAX( &sh4_cpu_period );94.145 MUL_r32( R_EDX );94.146 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );94.148 call_func0( sh4_raise_exception );94.149 ADD_imm8s_r32( 4, R_ESP );94.150 - load_spreg( R_EAX, REG_OFFSET(pc) );94.151 - call_func1(xlat_get_code,R_EAX);94.152 + load_spreg( R_EAX, R_PC );94.153 + if( sh4_x86.tlb_on ) {94.154 + call_func1(xlat_get_code_by_vma,R_EAX);94.155 + } else {94.156 + call_func1(xlat_get_code,R_EAX);94.157 + }94.158 POP_r32(R_EBP);94.159 RET();94.161 - sh4_x86_do_backpatch( end_ptr );94.162 + // Exception already raised - just cleanup94.163 + uint8_t *preexc_ptr = xlat_output;94.164 + MOV_r32_r32( R_EDX, R_ECX );94.165 + ADD_r32_r32( R_EDX, R_ECX );94.166 + ADD_r32_sh4r( R_ECX, R_SPC );94.167 + MOV_moff32_EAX( &sh4_cpu_period );94.168 + MUL_r32( R_EDX );94.169 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );94.170 + load_spreg( R_EAX, R_PC );94.171 + if( sh4_x86.tlb_on ) {94.172 + call_func1(xlat_get_code_by_vma,R_EAX);94.173 + } else {94.174 + call_func1(xlat_get_code,R_EAX);94.175 + }94.176 + POP_r32(R_EBP);94.177 + RET();94.178 +94.179 + for( i=0; i< sh4_x86.backpatch_posn; i++ ) {94.180 + *sh4_x86.backpatch_list[i].fixup_addr =94.181 + xlat_output - ((uint8_t *)sh4_x86.backpatch_list[i].fixup_addr) - 4;94.182 + if( sh4_x86.backpatch_list[i].exc_code == -1 ) {94.183 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );94.184 + int rel = preexc_ptr - xlat_output;94.185 + JMP_rel(rel);94.186 + } else {94.187 + PUSH_imm32( sh4_x86.backpatch_list[i].exc_code );94.188 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );94.189 + int rel = end_ptr - xlat_output;94.190 + JMP_rel(rel);94.191 + }94.192 + }94.193 }94.194 }94.196 +void *xlat_get_native_pc()94.197 +{94.198 + void *result = NULL;94.199 + asm(94.200 + "mov %%ebp, %%eax\n\t"94.201 + "mov $0x8, %%ecx\n\t"94.202 + "mov %1, %%edx\n"94.203 +"frame_loop: test %%eax, %%eax\n\t"94.204 + "je frame_not_found\n\t"94.205 + "cmp (%%eax), %%edx\n\t"94.206 + "je frame_found\n\t"94.207 + "sub $0x1, %%ecx\n\t"94.208 + "je frame_not_found\n\t"94.209 + "movl (%%eax), %%eax\n\t"94.210 + "jmp frame_loop\n"94.211 +"frame_found: movl 0x4(%%eax), %0\n"94.212 +"frame_not_found:"94.213 + : "=r" (result)94.214 + : "r" (&sh4r)94.215 + : "eax", "ecx", "edx" );94.216 + return result;94.217 +}94.218 +94.219 #endif
95.1 --- a/src/sh4/ia32mac.h Thu Dec 20 09:56:07 2007 +000095.2 +++ b/src/sh4/ia32mac.h Tue Jan 15 20:50:23 2008 +000095.3 @@ -1,5 +1,5 @@95.4 /**95.5 - * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $95.6 + * $Id$95.7 *95.8 * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and95.9 * calling conventions)95.10 @@ -101,11 +101,11 @@95.11 PUSH_r32(addr);95.12 load_imm32(R_EAX, (uint32_t)sh4_read_long);95.13 CALL_r32(R_EAX);95.14 - POP_r32(addr);95.15 + POP_r32(R_ECX);95.16 SUB_imm8s_r32( adj2-adj, R_ESP );95.17 PUSH_r32(R_EAX);95.18 - ADD_imm8s_r32( 4, addr );95.19 - PUSH_r32(addr);95.20 + ADD_imm8s_r32( 4, R_ECX );95.21 + PUSH_r32(R_ECX);95.22 load_imm32(R_EAX, (uint32_t)sh4_read_long);95.23 CALL_r32(R_EAX);95.24 ADD_imm8s_r32( 4, R_ESP );95.25 @@ -115,9 +115,6 @@95.26 sh4_x86.stack_posn -= 4;95.27 }95.29 -#define EXIT_BLOCK_SIZE 2995.30 -95.31 -95.32 /**95.33 * Emit the 'start of block' assembly. Sets up the stack frame and save95.34 * SI/DI as required95.35 @@ -133,8 +130,10 @@95.36 sh4_x86.fpuen_checked = FALSE;95.37 sh4_x86.branch_taken = FALSE;95.38 sh4_x86.backpatch_posn = 0;95.39 + sh4_x86.recovery_posn = 0;95.40 sh4_x86.block_start_pc = pc;95.41 sh4_x86.tstate = TSTATE_NONE;95.42 + sh4_x86.tlb_on = IS_MMU_ENABLED();95.43 sh4_x86.stack_posn = 8;95.44 }95.46 @@ -142,16 +141,23 @@95.47 * Exit the block with sh4r.pc already written95.48 * Bytes: 1595.49 */95.50 -void exit_block_pcset( pc )95.51 +void exit_block_pcset( sh4addr_t pc )95.52 {95.53 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 595.54 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 695.55 load_spreg( R_EAX, REG_OFFSET(pc) );95.56 - call_func1(xlat_get_code,R_EAX);95.57 + if( sh4_x86.tlb_on ) {95.58 + call_func1(xlat_get_code_by_vma,R_EAX);95.59 + } else {95.60 + call_func1(xlat_get_code,R_EAX);95.61 + }95.62 POP_r32(R_EBP);95.63 RET();95.64 }95.66 +#define EXIT_BLOCK_SIZE(pc) (24 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))95.67 +95.68 +95.69 /**95.70 * Exit the block to an absolute PC95.71 */95.72 @@ -159,7 +165,37 @@95.73 {95.74 load_imm32( R_ECX, pc ); // 595.75 store_spreg( R_ECX, REG_OFFSET(pc) ); // 395.76 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 595.77 + if( IS_IN_ICACHE(pc) ) {95.78 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 595.79 + } else if( sh4_x86.tlb_on ) {95.80 + call_func1(xlat_get_code_by_vma,R_ECX);95.81 + } else {95.82 + call_func1(xlat_get_code,R_ECX);95.83 + }95.84 + AND_imm8s_r32( 0xFC, R_EAX ); // 395.85 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 595.86 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 695.87 + POP_r32(R_EBP);95.88 + RET();95.89 +}95.90 +95.91 +#define EXIT_BLOCK_REL_SIZE(pc) (27 + (IS_IN_ICACHE(pc)?5:CALL_FUNC1_SIZE))95.92 +95.93 +/**95.94 + * Exit the block to a relative PC95.95 + */95.96 +void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )95.97 +{95.98 + load_imm32( R_ECX, pc - sh4_x86.block_start_pc ); // 595.99 + ADD_sh4r_r32( R_PC, R_ECX );95.100 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 395.101 + if( IS_IN_ICACHE(pc) ) {95.102 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 595.103 + } else if( sh4_x86.tlb_on ) {95.104 + call_func1(xlat_get_code_by_vma,R_ECX);95.105 + } else {95.106 + call_func1(xlat_get_code,R_ECX);95.107 + }95.108 AND_imm8s_r32( 0xFC, R_EAX ); // 395.109 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 595.110 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 695.111 @@ -173,48 +209,88 @@95.112 void sh4_translate_end_block( sh4addr_t pc ) {95.113 if( sh4_x86.branch_taken == FALSE ) {95.114 // Didn't exit unconditionally already, so write the termination here95.115 - exit_block( pc, pc );95.116 + exit_block_rel( pc, pc );95.117 }95.118 if( sh4_x86.backpatch_posn != 0 ) {95.119 + unsigned int i;95.120 + // Raise exception95.121 uint8_t *end_ptr = xlat_output;95.122 - // Exception termination. Jump block for various exception codes:95.123 - PUSH_imm32( EXC_DATA_ADDR_READ );95.124 - JMP_rel8( 33, target1 );95.125 - PUSH_imm32( EXC_DATA_ADDR_WRITE );95.126 - JMP_rel8( 26, target2 );95.127 - PUSH_imm32( EXC_ILLEGAL );95.128 - JMP_rel8( 19, target3 );95.129 - PUSH_imm32( EXC_SLOT_ILLEGAL );95.130 - JMP_rel8( 12, target4 );95.131 - PUSH_imm32( EXC_FPU_DISABLED );95.132 - JMP_rel8( 5, target5 );95.133 - PUSH_imm32( EXC_SLOT_FPU_DISABLED );95.134 - // target95.135 - JMP_TARGET(target1);95.136 - JMP_TARGET(target2);95.137 - JMP_TARGET(target3);95.138 - JMP_TARGET(target4);95.139 - JMP_TARGET(target5);95.140 - // Raise exception95.141 - load_spreg( R_ECX, REG_OFFSET(pc) );95.142 + MOV_r32_r32( R_EDX, R_ECX );95.143 ADD_r32_r32( R_EDX, R_ECX );95.144 - ADD_r32_r32( R_EDX, R_ECX );95.145 - store_spreg( R_ECX, REG_OFFSET(pc) );95.146 + ADD_r32_sh4r( R_ECX, R_PC );95.147 MOV_moff32_EAX( &sh4_cpu_period );95.148 MUL_r32( R_EDX );95.149 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );95.151 - POP_r32(R_EDX);95.152 - call_func1( sh4_raise_exception, R_EDX );95.153 - load_spreg( R_EAX, REG_OFFSET(pc) );95.154 - call_func1(xlat_get_code,R_EAX);95.155 + POP_r32(R_EDX);95.156 + call_func1( sh4_raise_exception, R_EDX );95.157 + load_spreg( R_EAX, R_PC );95.158 + if( sh4_x86.tlb_on ) {95.159 + call_func1(xlat_get_code_by_vma,R_EAX);95.160 + } else {95.161 + call_func1(xlat_get_code,R_EAX);95.162 + }95.163 POP_r32(R_EBP);95.164 RET();95.166 - sh4_x86_do_backpatch( end_ptr );95.167 + // Exception already raised - just cleanup95.168 + uint8_t *preexc_ptr = xlat_output;95.169 + MOV_r32_r32( R_EDX, R_ECX );95.170 + ADD_r32_r32( R_EDX, R_ECX );95.171 + ADD_r32_sh4r( R_ECX, R_SPC );95.172 + MOV_moff32_EAX( &sh4_cpu_period );95.173 + MUL_r32( R_EDX );95.174 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );95.175 + load_spreg( R_EAX, R_PC );95.176 + if( sh4_x86.tlb_on ) {95.177 + call_func1(xlat_get_code_by_vma,R_EAX);95.178 + } else {95.179 + call_func1(xlat_get_code,R_EAX);95.180 + }95.181 + POP_r32(R_EBP);95.182 + RET();95.183 +95.184 + for( i=0; i< sh4_x86.backpatch_posn; i++ ) {95.185 + *sh4_x86.backpatch_list[i].fixup_addr =95.186 + xlat_output - ((uint8_t *)sh4_x86.backpatch_list[i].fixup_addr) - 4;95.187 + if( sh4_x86.backpatch_list[i].exc_code == -1 ) {95.188 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );95.189 + int rel = preexc_ptr - xlat_output;95.190 + JMP_rel(rel);95.191 + } else {95.192 + PUSH_imm32( sh4_x86.backpatch_list[i].exc_code );95.193 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );95.194 + int rel = end_ptr - xlat_output;95.195 + JMP_rel(rel);95.196 + }95.197 + }95.198 }95.199 }95.201 +void *xlat_get_native_pc()95.202 +{95.203 + void *result = NULL;95.204 + asm(95.205 + "mov %%ebp, %%eax\n\t"95.206 + "mov $0x8, %%ecx\n\t"95.207 + "mov %1, %%edx\n"95.208 +"frame_loop: test %%eax, %%eax\n\t"95.209 + "je frame_not_found\n\t"95.210 + "cmp (%%eax), %%edx\n\t"95.211 + "je frame_found\n\t"95.212 + "sub $0x1, %%ecx\n\t"95.213 + "je frame_not_found\n\t"95.214 + "movl (%%eax), %%eax\n\t"95.215 + "jmp frame_loop\n"95.216 +"frame_found: movl 0x4(%%eax), %0\n"95.217 +"frame_not_found:"95.218 + : "=r" (result)95.219 + : "r" (&sh4r)95.220 + : "eax", "ecx", "edx" );95.221 + return result;95.222 +}95.223 +95.224 +95.225 #endif
96.1 --- a/src/sh4/ia64abi.h Thu Dec 20 09:56:07 2007 +000096.2 +++ b/src/sh4/ia64abi.h Tue Jan 15 20:50:23 2008 +000096.3 @@ -1,5 +1,5 @@96.4 /**96.5 - * $Id: ia64abi.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $96.6 + * $Id$96.7 *96.8 * Provides the implementation for the ia32 ABI (eg prologue, epilogue, and96.9 * calling conventions)96.10 @@ -20,6 +20,7 @@96.11 #ifndef __lxdream_x86_64abi_H96.12 #define __lxdream_x86_64abi_H 196.14 +#include <unwind.h>96.16 #define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );96.18 @@ -50,7 +51,7 @@96.19 call_func0(ptr);96.20 }96.22 -#define MEM_WRITE_DOUBLE_SIZE 3996.23 +#define MEM_WRITE_DOUBLE_SIZE 3596.24 /**96.25 * Write a double (64-bit) value into memory, with the first word in arg2a, and96.26 * the second in arg2b96.27 @@ -60,10 +61,10 @@96.28 PUSH_r32(arg2b);96.29 PUSH_r32(addr);96.30 call_func2(sh4_write_long, addr, arg2a);96.31 - POP_r32(addr);96.32 - POP_r32(arg2b);96.33 - ADD_imm8s_r32(4, addr);96.34 - call_func2(sh4_write_long, addr, arg2b);96.35 + POP_r32(R_EDI);96.36 + POP_r32(R_ESI);96.37 + ADD_imm8s_r32(4, R_EDI);96.38 + call_func0(sh4_write_long);96.39 }96.41 #define MEM_READ_DOUBLE_SIZE 4396.42 @@ -101,7 +102,9 @@96.43 sh4_x86.fpuen_checked = FALSE;96.44 sh4_x86.branch_taken = FALSE;96.45 sh4_x86.backpatch_posn = 0;96.46 + sh4_x86.recovery_posn = 0;96.47 sh4_x86.block_start_pc = pc;96.48 + sh4_x86.tlb_on = IS_MMU_ENABLED();96.49 sh4_x86.tstate = TSTATE_NONE;96.50 }96.52 @@ -109,17 +112,21 @@96.53 * Exit the block with sh4r.pc already written96.54 * Bytes: 1596.55 */96.56 -void exit_block_pcset( pc )96.57 +void exit_block_pcset( sh4addr_t pc )96.58 {96.59 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 596.60 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 696.61 load_spreg( R_EAX, REG_OFFSET(pc) );96.62 - call_func1(xlat_get_code,R_EAX);96.63 + if( sh4_x86.tlb_on ) {96.64 + call_func1(xlat_get_code_by_vma,R_EAX);96.65 + } else {96.66 + call_func1(xlat_get_code,R_EAX);96.67 + }96.68 POP_r32(R_EBP);96.69 RET();96.70 }96.72 -#define EXIT_BLOCK_SIZE 3596.73 +#define EXIT_BLOCK_SIZE(pc) (25 + (IS_IN_ICACHE(pc)?10:CALL_FUNC1_SIZE))96.74 /**96.75 * Exit the block to an absolute PC96.76 */96.77 @@ -127,8 +134,14 @@96.78 {96.79 load_imm32( R_ECX, pc ); // 596.80 store_spreg( R_ECX, REG_OFFSET(pc) ); // 396.81 - REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );96.82 - REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 396.83 + if( IS_IN_ICACHE(pc) ) {96.84 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );96.85 + } else if( sh4_x86.tlb_on ) {96.86 + call_func1(xlat_get_code_by_vma, R_ECX);96.87 + } else {96.88 + call_func1(xlat_get_code,R_ECX);96.89 + }96.90 + REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 496.91 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 596.92 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 696.93 POP_r32(R_EBP);96.94 @@ -136,51 +149,112 @@96.95 }96.98 +#define EXIT_BLOCK_REL_SIZE(pc) (28 + (IS_IN_ICACHE(pc)?10:CALL_FUNC1_SIZE))96.99 +96.100 +/**96.101 + * Exit the block to a relative PC96.102 + */96.103 +void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )96.104 +{96.105 + load_imm32( R_ECX, pc - sh4_x86.block_start_pc ); // 596.106 + ADD_sh4r_r32( R_PC, R_ECX );96.107 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 396.108 + if( IS_IN_ICACHE(pc) ) {96.109 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 596.110 + } else if( sh4_x86.tlb_on ) {96.111 + call_func1(xlat_get_code_by_vma,R_ECX);96.112 + } else {96.113 + call_func1(xlat_get_code,R_ECX);96.114 + }96.115 + REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 496.116 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 596.117 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 696.118 + POP_r32(R_EBP);96.119 + RET();96.120 +}96.121 +96.122 /**96.123 * Write the block trailer (exception handling block)96.124 */96.125 void sh4_translate_end_block( sh4addr_t pc ) {96.126 if( sh4_x86.branch_taken == FALSE ) {96.127 // Didn't exit unconditionally already, so write the termination here96.128 - exit_block( pc, pc );96.129 + exit_block_rel( pc, pc );96.130 }96.131 if( sh4_x86.backpatch_posn != 0 ) {96.132 + unsigned int i;96.133 + // Raise exception96.134 uint8_t *end_ptr = xlat_output;96.135 - // Exception termination. Jump block for various exception codes:96.136 - load_imm32( R_EDI, EXC_DATA_ADDR_READ );96.137 - JMP_rel8( 33, target1 );96.138 - load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );96.139 - JMP_rel8( 26, target2 );96.140 - load_imm32( R_EDI, EXC_ILLEGAL );96.141 - JMP_rel8( 19, target3 );96.142 - load_imm32( R_EDI, EXC_SLOT_ILLEGAL );96.143 - JMP_rel8( 12, target4 );96.144 - load_imm32( R_EDI, EXC_FPU_DISABLED );96.145 - JMP_rel8( 5, target5 );96.146 - load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );96.147 - // target96.148 - JMP_TARGET(target1);96.149 - JMP_TARGET(target2);96.150 - JMP_TARGET(target3);96.151 - JMP_TARGET(target4);96.152 - JMP_TARGET(target5);96.153 - // Raise exception96.154 - load_spreg( R_ECX, REG_OFFSET(pc) );96.155 + MOV_r32_r32( R_EDX, R_ECX );96.156 ADD_r32_r32( R_EDX, R_ECX );96.157 - ADD_r32_r32( R_EDX, R_ECX );96.158 - store_spreg( R_ECX, REG_OFFSET(pc) );96.159 + ADD_r32_sh4r( R_ECX, R_PC );96.160 MOV_moff32_EAX( &sh4_cpu_period );96.161 MUL_r32( R_EDX );96.162 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );96.164 call_func0( sh4_raise_exception );96.165 - load_spreg( R_EAX, REG_OFFSET(pc) );96.166 - call_func1(xlat_get_code,R_EAX);96.167 + load_spreg( R_EAX, R_PC );96.168 + if( sh4_x86.tlb_on ) {96.169 + call_func1(xlat_get_code_by_vma,R_EAX);96.170 + } else {96.171 + call_func1(xlat_get_code,R_EAX);96.172 + }96.173 POP_r32(R_EBP);96.174 RET();96.176 - sh4_x86_do_backpatch( end_ptr );96.177 + // Exception already raised - just cleanup96.178 + uint8_t *preexc_ptr = xlat_output;96.179 + MOV_r32_r32( R_EDX, R_ECX );96.180 + ADD_r32_r32( R_EDX, R_ECX );96.181 + ADD_r32_sh4r( R_ECX, R_SPC );96.182 + MOV_moff32_EAX( &sh4_cpu_period );96.183 + MUL_r32( R_EDX );96.184 + ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );96.185 + load_spreg( R_EDI, R_PC );96.186 + if( sh4_x86.tlb_on ) {96.187 + call_func0(xlat_get_code_by_vma);96.188 + } else {96.189 + call_func0(xlat_get_code);96.190 + }96.191 + POP_r32(R_EBP);96.192 + RET();96.193 +96.194 + for( i=0; i< sh4_x86.backpatch_posn; i++ ) {96.195 + *sh4_x86.backpatch_list[i].fixup_addr =96.196 + xlat_output - ((uint8_t *)sh4_x86.backpatch_list[i].fixup_addr) - 4;96.197 + if( sh4_x86.backpatch_list[i].exc_code == -1 ) {96.198 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );96.199 + int rel = preexc_ptr - xlat_output;96.200 + JMP_rel(rel);96.201 + } else {96.202 + load_imm32( R_EDI, sh4_x86.backpatch_list[i].exc_code );96.203 + load_imm32( R_EDX, sh4_x86.backpatch_list[i].fixup_icount );96.204 + int rel = end_ptr - xlat_output;96.205 + JMP_rel(rel);96.206 + }96.207 + }96.208 }96.209 }96.211 +_Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )96.212 +{96.213 + void *rbp = (void *)_Unwind_GetGR(context, 6);96.214 + if( rbp == (void *)&sh4r ) {96.215 + void **result = (void **)arg;96.216 + *result = (void *)_Unwind_GetIP(context);96.217 + return _URC_NORMAL_STOP;96.218 + }96.219 +96.220 + return _URC_NO_REASON;96.221 +}96.222 +96.223 +void *xlat_get_native_pc()96.224 +{96.225 + struct _Unwind_Exception exc;96.226 +96.227 + void *result = NULL;96.228 + _Unwind_Backtrace( xlat_check_frame, &result );96.229 + return result;96.230 +}96.231 +96.232 #endif
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000097.2 +++ b/src/sh4/ia64asm.s Tue Jan 15 20:50:23 2008 +000097.3 @@ -0,0 +1,34 @@97.4 +#97.5 +# Scan back through the stack until we hit the currently executing97.6 +# translation block, and find the call return address to that block.97.7 +#97.8 +# Implementation: iterate back through each stack frame until we find97.9 +# a frame that has a saved %ebp == sh4r (setup by the xlat blocks).97.10 +# The return address is then the stack value immediately before the97.11 +# saved %ebp.97.12 +#97.13 +# At most 8 stack frames are checked, to prevent infinite looping on a97.14 +# corrupt stack.97.15 +97.16 +.global xlat_get_native_pc97.17 +xlat_get_native_pc:97.18 + mov %rbp, %rax97.19 + mov $0x8, %ecx97.20 + mov $sh4r, %rdx97.21 +97.22 +frame_loop:97.23 + test %rax, %rax97.24 + je frame_not_found97.25 + cmpq (%rax), %rdx97.26 + je frame_found97.27 + sub $0x1, %ecx97.28 + je frame_not_found97.29 + movq (%rax), %rax97.30 + jmp frame_loop97.31 +97.32 +frame_found:97.33 + movl 0x4(%rax), %rax97.34 + ret97.35 +frame_not_found:97.36 + xor %rax, %rax97.37 + ret
98.1 --- a/src/sh4/intc.c Thu Dec 20 09:56:07 2007 +000098.2 +++ b/src/sh4/intc.c Tue Jan 15 20:50:23 2008 +000098.3 @@ -1,5 +1,5 @@98.4 /**98.5 - * $Id: intc.c,v 1.8 2007-10-06 08:52:08 nkeynes Exp $98.6 + * $Id$98.7 *98.8 * SH4 onboard interrupt controller (INTC) implementation98.9 *
99.1 --- a/src/sh4/intc.h Thu Dec 20 09:56:07 2007 +000099.2 +++ b/src/sh4/intc.h Tue Jan 15 20:50:23 2008 +000099.3 @@ -1,5 +1,5 @@99.4 /**99.5 - * $Id: intc.h,v 1.2 2005-12-25 08:24:11 nkeynes Exp $99.6 + * $Id$99.7 *99.8 * SH4 onboard interrupt controller (INTC) definitions.99.9 *
100.1 --- a/src/sh4/mmu.c Thu Dec 20 09:56:07 2007 +0000100.2 +++ b/src/sh4/mmu.c Tue Jan 15 20:50:23 2008 +0000100.3 @@ -1,5 +1,5 @@100.4 /**100.5 - * $Id: mmu.c,v 1.15 2007-11-08 11:54:16 nkeynes Exp $100.6 + * $Id$100.7 *100.8 * MMU implementation100.9 *100.10 @@ -22,6 +22,41 @@100.11 #include "sh4/sh4core.h"100.12 #include "mem.h"100.14 +#define VMA_TO_EXT_ADDR(vma) ((vma)&0x1FFFFFFF)100.15 +100.16 +/* The MMU (practically unique in the system) is allowed to raise exceptions100.17 + * directly, with a return code indicating that one was raised and the caller100.18 + * had better behave appropriately.100.19 + */100.20 +#define RAISE_TLB_ERROR(code, vpn) \100.21 + MMIO_WRITE(MMU, TEA, vpn); \100.22 + MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00))); \100.23 + sh4_raise_tlb_exception(code);100.24 +100.25 +#define RAISE_MEM_ERROR(code, vpn) \100.26 + MMIO_WRITE(MMU, TEA, vpn); \100.27 + MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00))); \100.28 + sh4_raise_exception(code);100.29 +100.30 +#define RAISE_OTHER_ERROR(code) \100.31 + sh4_raise_exception(code);100.32 +/**100.33 + * Abort with a non-MMU address error. Caused by user-mode code attempting100.34 + * to access privileged regions, or alignment faults.100.35 + */100.36 +#define MMU_READ_ADDR_ERROR() RAISE_OTHER_ERROR(EXC_DATA_ADDR_READ)100.37 +#define MMU_WRITE_ADDR_ERROR() RAISE_OTHER_ERROR(EXC_DATA_ADDR_WRITE)100.38 +100.39 +#define MMU_TLB_READ_MISS_ERROR(vpn) RAISE_TLB_ERROR(EXC_TLB_MISS_READ, vpn)100.40 +#define MMU_TLB_WRITE_MISS_ERROR(vpn) RAISE_TLB_ERROR(EXC_TLB_MISS_WRITE, vpn)100.41 +#define MMU_TLB_INITIAL_WRITE_ERROR(vpn) RAISE_MEM_ERROR(EXC_INIT_PAGE_WRITE, vpn)100.42 +#define MMU_TLB_READ_PROT_ERROR(vpn) RAISE_MEM_ERROR(EXC_TLB_PROT_READ, vpn)100.43 +#define MMU_TLB_WRITE_PROT_ERROR(vpn) RAISE_MEM_ERROR(EXC_TLB_PROT_WRITE, vpn)100.44 +#define MMU_TLB_MULTI_HIT_ERROR(vpn) sh4_raise_reset(EXC_TLB_MULTI_HIT); \100.45 + MMIO_WRITE(MMU, TEA, vpn); \100.46 + MMIO_WRITE(MMU, PTEH, ((MMIO_READ(MMU, PTEH) & 0x000003FF) | (vpn&0xFFFFFC00)));100.47 +100.48 +100.49 #define OCRAM_START (0x1C000000>>PAGE_BITS)100.50 #define OCRAM_END (0x20000000>>PAGE_BITS)100.52 @@ -32,6 +67,7 @@100.53 #define TLB_VALID 0x00000100100.54 #define TLB_USERMODE 0x00000040100.55 #define TLB_WRITABLE 0x00000020100.56 +#define TLB_USERWRITABLE (TLB_WRITABLE|TLB_USERMODE)100.57 #define TLB_SIZE_MASK 0x00000090100.58 #define TLB_SIZE_1K 0x00000000100.59 #define TLB_SIZE_4K 0x00000010100.60 @@ -42,16 +78,22 @@100.61 #define TLB_SHARE 0x00000002100.62 #define TLB_WRITETHRU 0x00000001100.64 +#define MASK_1K 0xFFFFFC00100.65 +#define MASK_4K 0xFFFFF000100.66 +#define MASK_64K 0xFFFF0000100.67 +#define MASK_1M 0xFFF00000100.69 struct itlb_entry {100.70 sh4addr_t vpn; // Virtual Page Number100.71 uint32_t asid; // Process ID100.72 + uint32_t mask;100.73 sh4addr_t ppn; // Physical Page Number100.74 uint32_t flags;100.75 };100.77 struct utlb_entry {100.78 sh4addr_t vpn; // Virtual Page Number100.79 + uint32_t mask; // Page size mask100.80 uint32_t asid; // Process ID100.81 sh4addr_t ppn; // Physical Page Number100.82 uint32_t flags;100.83 @@ -63,12 +105,23 @@100.84 static uint32_t mmu_urc;100.85 static uint32_t mmu_urb;100.86 static uint32_t mmu_lrui;100.87 +static uint32_t mmu_asid; // current asid100.89 static sh4ptr_t cache = NULL;100.91 static void mmu_invalidate_tlb();100.94 +static uint32_t get_mask_for_flags( uint32_t flags )100.95 +{100.96 + switch( flags & TLB_SIZE_MASK ) {100.97 + case TLB_SIZE_1K: return MASK_1K;100.98 + case TLB_SIZE_4K: return MASK_4K;100.99 + case TLB_SIZE_64K: return MASK_64K;100.100 + case TLB_SIZE_1M: return MASK_1M;100.101 + }100.102 +}100.103 +100.104 int32_t mmio_region_MMU_read( uint32_t reg )100.105 {100.106 switch( reg ) {100.107 @@ -81,9 +134,14 @@100.109 void mmio_region_MMU_write( uint32_t reg, uint32_t val )100.110 {100.111 + uint32_t tmp;100.112 switch(reg) {100.113 case PTEH:100.114 val &= 0xFFFFFCFF;100.115 + if( (val & 0xFF) != mmu_asid ) {100.116 + mmu_asid = val&0xFF;100.117 + sh4_icache.page_vma = -1; // invalidate icache as asid has changed100.118 + }100.119 break;100.120 case PTEL:100.121 val &= 0x1FFFFDFF;100.122 @@ -99,6 +157,14 @@100.123 mmu_urb = (val >> 18) & 0x3F;100.124 mmu_lrui = (val >> 26) & 0x3F;100.125 val &= 0x00000301;100.126 + tmp = MMIO_READ( MMU, MMUCR );100.127 + if( ((val ^ tmp) & MMUCR_AT) && sh4_is_using_xlat() ) {100.128 + // AT flag has changed state - flush the xlt cache as all bets100.129 + // are off now. We also need to force an immediate exit from the100.130 + // current block100.131 + MMIO_WRITE( MMU, MMUCR, val );100.132 + sh4_translate_flush_cache();100.133 + }100.134 break;100.135 case CCR:100.136 mmu_set_cache_mode( val & (CCR_OIX|CCR_ORA) );100.137 @@ -118,6 +184,7 @@100.138 void MMU_reset()100.139 {100.140 mmio_region_MMU_write( CCR, 0 );100.141 + mmio_region_MMU_write( MMUCR, 0 );100.142 }100.144 void MMU_save_state( FILE *f )100.145 @@ -125,6 +192,10 @@100.146 fwrite( cache, 4096, 2, f );100.147 fwrite( &mmu_itlb, sizeof(mmu_itlb), 1, f );100.148 fwrite( &mmu_utlb, sizeof(mmu_utlb), 1, f );100.149 + fwrite( &mmu_urc, sizeof(mmu_urc), 1, f );100.150 + fwrite( &mmu_urb, sizeof(mmu_urb), 1, f );100.151 + fwrite( &mmu_lrui, sizeof(mmu_lrui), 1, f );100.152 + fwrite( &mmu_asid, sizeof(mmu_asid), 1, f );100.153 }100.155 int MMU_load_state( FILE *f )100.156 @@ -142,6 +213,18 @@100.157 if( fread( &mmu_utlb, sizeof(mmu_utlb), 1, f ) != 1 ) {100.158 return 1;100.159 }100.160 + if( fread( &mmu_urc, sizeof(mmu_urc), 1, f ) != 1 ) {100.161 + return 1;100.162 + }100.163 + if( fread( &mmu_urc, sizeof(mmu_urb), 1, f ) != 1 ) {100.164 + return 1;100.165 + }100.166 + if( fread( &mmu_lrui, sizeof(mmu_lrui), 1, f ) != 1 ) {100.167 + return 1;100.168 + }100.169 + if( fread( &mmu_asid, sizeof(mmu_asid), 1, f ) != 1 ) {100.170 + return 1;100.171 + }100.172 return 0;100.173 }100.175 @@ -177,41 +260,7 @@100.176 mmu_utlb[mmu_urc].ppn = MMIO_READ(MMU, PTEL) & 0x1FFFFC00;100.177 mmu_utlb[mmu_urc].flags = MMIO_READ(MMU, PTEL) & 0x00001FF;100.178 mmu_utlb[mmu_urc].pcmcia = MMIO_READ(MMU, PTEA);100.179 -}100.180 -100.181 -uint64_t mmu_translate_read( sh4addr_t addr )100.182 -{100.183 - uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.184 - if( IS_SH4_PRIVMODE() ) {100.185 - switch( addr & 0xE0000000 ) {100.186 - case 0x80000000: case 0xA0000000:100.187 - /* Non-translated read P1,P2 */100.188 - break;100.189 - case 0xE0000000:100.190 - /* Non-translated read P4 */100.191 - break;100.192 - default:100.193 - if( mmucr&MMUCR_AT ) {100.194 - } else {100.195 - // direct read100.196 - }100.197 - }100.198 - } else {100.199 - if( addr & 0x80000000 ) {100.200 - if( ((addr&0xFC000000) == 0xE0000000 ) &&100.201 - ((mmucr&MMUCR_SQMD) == 0) ) {100.202 - // Store queue100.203 - return 0;100.204 - }100.205 -// MMU_READ_ADDR_ERROR();100.206 - }100.207 - if( mmucr&MMUCR_AT ) {100.208 - uint32_t vpn = addr & 0xFFFFFC00;100.209 - uint32_t asid = MMIO_READ(MMU,PTEH)&0xFF;100.210 - } else {100.211 - // direct read100.212 - }100.213 - }100.214 + mmu_utlb[mmu_urc].mask = get_mask_for_flags(mmu_utlb[mmu_urc].flags);100.215 }100.217 static void mmu_invalidate_tlb()100.218 @@ -251,6 +300,7 @@100.219 struct itlb_entry *ent = &mmu_itlb[ITLB_ENTRY(addr)];100.220 ent->ppn = val & 0x1FFFFC00;100.221 ent->flags = val & 0x00001DA;100.222 + ent->mask = get_mask_for_flags(val);100.223 }100.225 #define UTLB_ENTRY(addr) ((addr>>8)&0x3F)100.226 @@ -273,9 +323,70 @@100.227 }100.228 }100.230 +/**100.231 + * Find a UTLB entry for the associative TLB write - same as the normal100.232 + * lookup but ignores the valid bit.100.233 + */100.234 +static inline mmu_utlb_lookup_assoc( uint32_t vpn, uint32_t asid )100.235 +{100.236 + int result = -1;100.237 + unsigned int i;100.238 + for( i = 0; i < UTLB_ENTRY_COUNT; i++ ) {100.239 + if( (mmu_utlb[i].flags & TLB_VALID) &&100.240 + ((mmu_utlb[i].flags & TLB_SHARE) || asid == mmu_utlb[i].asid) &&100.241 + ((mmu_utlb[i].vpn ^ vpn) & mmu_utlb[i].mask) == 0 ) {100.242 + if( result != -1 ) {100.243 + fprintf( stderr, "TLB Multi hit: %d %d\n", result, i );100.244 + return -2;100.245 + }100.246 + result = i;100.247 + }100.248 + }100.249 + return result;100.250 +}100.251 +100.252 +/**100.253 + * Find a ITLB entry for the associative TLB write - same as the normal100.254 + * lookup but ignores the valid bit.100.255 + */100.256 +static inline mmu_itlb_lookup_assoc( uint32_t vpn, uint32_t asid )100.257 +{100.258 + int result = -1;100.259 + unsigned int i;100.260 + for( i = 0; i < ITLB_ENTRY_COUNT; i++ ) {100.261 + if( (mmu_itlb[i].flags & TLB_VALID) &&100.262 + ((mmu_itlb[i].flags & TLB_SHARE) || asid == mmu_itlb[i].asid) &&100.263 + ((mmu_itlb[i].vpn ^ vpn) & mmu_itlb[i].mask) == 0 ) {100.264 + if( result != -1 ) {100.265 + return -2;100.266 + }100.267 + result = i;100.268 + }100.269 + }100.270 + return result;100.271 +}100.272 +100.273 void mmu_utlb_addr_write( sh4addr_t addr, uint32_t val )100.274 {100.275 if( UTLB_ASSOC(addr) ) {100.276 + int utlb = mmu_utlb_lookup_assoc( val, mmu_asid );100.277 + if( utlb >= 0 ) {100.278 + struct utlb_entry *ent = &mmu_utlb[utlb];100.279 + ent->flags = ent->flags & ~(TLB_DIRTY|TLB_VALID);100.280 + ent->flags |= (val & TLB_VALID);100.281 + ent->flags |= ((val & 0x200)>>7);100.282 + }100.283 +100.284 + int itlb = mmu_itlb_lookup_assoc( val, mmu_asid );100.285 + if( itlb >= 0 ) {100.286 + struct itlb_entry *ent = &mmu_itlb[itlb];100.287 + ent->flags = (ent->flags & (~TLB_VALID)) | (val & TLB_VALID);100.288 + }100.289 +100.290 + if( itlb == -2 || utlb == -2 ) {100.291 + MMU_TLB_MULTI_HIT_ERROR(addr);100.292 + return;100.293 + }100.294 } else {100.295 struct utlb_entry *ent = &mmu_utlb[UTLB_ENTRY(addr)];100.296 ent->vpn = (val & 0xFFFFFC00);100.297 @@ -294,6 +405,7 @@100.298 } else {100.299 ent->ppn = (val & 0x1FFFFC00);100.300 ent->flags = (val & 0x000001FF);100.301 + ent->mask = get_mask_for_flags(val);100.302 }100.303 }100.305 @@ -331,3 +443,455 @@100.306 void mmu_ocache_data_write( sh4addr_t addr, uint32_t val )100.307 {100.308 }100.309 +100.310 +/******************************************************************************/100.311 +/* MMU TLB address translation */100.312 +/******************************************************************************/100.313 +100.314 +/**100.315 + * The translations are excessively complicated, but unfortunately it's a100.316 + * complicated system. TODO: make this not be painfully slow.100.317 + */100.318 +100.319 +/**100.320 + * Perform the actual utlb lookup w/ asid matching.100.321 + * Possible utcomes are:100.322 + * 0..63 Single match - good, return entry found100.323 + * -1 No match - raise a tlb data miss exception100.324 + * -2 Multiple matches - raise a multi-hit exception (reset)100.325 + * @param vpn virtual address to resolve100.326 + * @return the resultant UTLB entry, or an error.100.327 + */100.328 +static inline int mmu_utlb_lookup_vpn_asid( uint32_t vpn )100.329 +{100.330 + int result = -1;100.331 + unsigned int i;100.332 +100.333 + mmu_urc++;100.334 + if( mmu_urc == mmu_urb || mmu_urc == 0x40 ) {100.335 + mmu_urc = 0;100.336 + }100.337 +100.338 + for( i = 0; i < UTLB_ENTRY_COUNT; i++ ) {100.339 + if( (mmu_utlb[i].flags & TLB_VALID) &&100.340 + ((mmu_utlb[i].flags & TLB_SHARE) || mmu_asid == mmu_utlb[i].asid) &&100.341 + ((mmu_utlb[i].vpn ^ vpn) & mmu_utlb[i].mask) == 0 ) {100.342 + if( result != -1 ) {100.343 + return -2;100.344 + }100.345 + result = i;100.346 + }100.347 + }100.348 + return result;100.349 +}100.350 +100.351 +/**100.352 + * Perform the actual utlb lookup matching on vpn only100.353 + * Possible utcomes are:100.354 + * 0..63 Single match - good, return entry found100.355 + * -1 No match - raise a tlb data miss exception100.356 + * -2 Multiple matches - raise a multi-hit exception (reset)100.357 + * @param vpn virtual address to resolve100.358 + * @return the resultant UTLB entry, or an error.100.359 + */100.360 +static inline int mmu_utlb_lookup_vpn( uint32_t vpn )100.361 +{100.362 + int result = -1;100.363 + unsigned int i;100.364 +100.365 + mmu_urc++;100.366 + if( mmu_urc == mmu_urb || mmu_urc == 0x40 ) {100.367 + mmu_urc = 0;100.368 + }100.369 +100.370 + for( i = 0; i < UTLB_ENTRY_COUNT; i++ ) {100.371 + if( (mmu_utlb[i].flags & TLB_VALID) &&100.372 + ((mmu_utlb[i].vpn ^ vpn) & mmu_utlb[i].mask) == 0 ) {100.373 + if( result != -1 ) {100.374 + return -2;100.375 + }100.376 + result = i;100.377 + }100.378 + }100.379 +100.380 + return result;100.381 +}100.382 +100.383 +/**100.384 + * Update the ITLB by replacing the LRU entry with the specified UTLB entry.100.385 + * @return the number (0-3) of the replaced entry.100.386 + */100.387 +static int inline mmu_itlb_update_from_utlb( int entryNo )100.388 +{100.389 + int replace;100.390 + /* Determine entry to replace based on lrui */100.391 + if( (mmu_lrui & 0x38) == 0x38 ) {100.392 + replace = 0;100.393 + mmu_lrui = mmu_lrui & 0x07;100.394 + } else if( (mmu_lrui & 0x26) == 0x06 ) {100.395 + replace = 1;100.396 + mmu_lrui = (mmu_lrui & 0x19) | 0x20;100.397 + } else if( (mmu_lrui & 0x15) == 0x01 ) {100.398 + replace = 2;100.399 + mmu_lrui = (mmu_lrui & 0x3E) | 0x14;100.400 + } else { // Note - gets invalid entries too100.401 + replace = 3;100.402 + mmu_lrui = (mmu_lrui | 0x0B);100.403 + }100.404 +100.405 + mmu_itlb[replace].vpn = mmu_utlb[entryNo].vpn;100.406 + mmu_itlb[replace].mask = mmu_utlb[entryNo].mask;100.407 + mmu_itlb[replace].ppn = mmu_utlb[entryNo].ppn;100.408 + mmu_itlb[replace].asid = mmu_utlb[entryNo].asid;100.409 + mmu_itlb[replace].flags = mmu_utlb[entryNo].flags & 0x01DA;100.410 + return replace;100.411 +}100.412 +100.413 +/**100.414 + * Perform the actual itlb lookup w/ asid protection100.415 + * Possible utcomes are:100.416 + * 0..63 Single match - good, return entry found100.417 + * -1 No match - raise a tlb data miss exception100.418 + * -2 Multiple matches - raise a multi-hit exception (reset)100.419 + * @param vpn virtual address to resolve100.420 + * @return the resultant ITLB entry, or an error.100.421 + */100.422 +static inline int mmu_itlb_lookup_vpn_asid( uint32_t vpn )100.423 +{100.424 + int result = -1;100.425 + unsigned int i;100.426 +100.427 + for( i = 0; i < ITLB_ENTRY_COUNT; i++ ) {100.428 + if( (mmu_itlb[i].flags & TLB_VALID) &&100.429 + ((mmu_itlb[i].flags & TLB_SHARE) || mmu_asid == mmu_itlb[i].asid) &&100.430 + ((mmu_itlb[i].vpn ^ vpn) & mmu_itlb[i].mask) == 0 ) {100.431 + if( result != -1 ) {100.432 + return -2;100.433 + }100.434 + result = i;100.435 + }100.436 + }100.437 +100.438 + if( result == -1 ) {100.439 + int utlbEntry = mmu_utlb_lookup_vpn_asid( vpn );100.440 + if( utlbEntry < 0 ) {100.441 + return utlbEntry;100.442 + } else {100.443 + return mmu_itlb_update_from_utlb( utlbEntry );100.444 + }100.445 + }100.446 +100.447 + switch( result ) {100.448 + case 0: mmu_lrui = (mmu_lrui & 0x07); break;100.449 + case 1: mmu_lrui = (mmu_lrui & 0x19) | 0x20; break;100.450 + case 2: mmu_lrui = (mmu_lrui & 0x3E) | 0x14; break;100.451 + case 3: mmu_lrui = (mmu_lrui | 0x0B); break;100.452 + }100.453 +100.454 + return result;100.455 +}100.456 +100.457 +/**100.458 + * Perform the actual itlb lookup on vpn only100.459 + * Possible utcomes are:100.460 + * 0..63 Single match - good, return entry found100.461 + * -1 No match - raise a tlb data miss exception100.462 + * -2 Multiple matches - raise a multi-hit exception (reset)100.463 + * @param vpn virtual address to resolve100.464 + * @return the resultant ITLB entry, or an error.100.465 + */100.466 +static inline int mmu_itlb_lookup_vpn( uint32_t vpn )100.467 +{100.468 + int result = -1;100.469 + unsigned int i;100.470 +100.471 + for( i = 0; i < ITLB_ENTRY_COUNT; i++ ) {100.472 + if( (mmu_itlb[i].flags & TLB_VALID) &&100.473 + ((mmu_itlb[i].vpn ^ vpn) & mmu_itlb[i].mask) == 0 ) {100.474 + if( result != -1 ) {100.475 + return -2;100.476 + }100.477 + result = i;100.478 + }100.479 + }100.480 +100.481 + if( result == -1 ) {100.482 + int utlbEntry = mmu_utlb_lookup_vpn( vpn );100.483 + if( utlbEntry < 0 ) {100.484 + return utlbEntry;100.485 + } else {100.486 + return mmu_itlb_update_from_utlb( utlbEntry );100.487 + }100.488 + }100.489 +100.490 + switch( result ) {100.491 + case 0: mmu_lrui = (mmu_lrui & 0x07); break;100.492 + case 1: mmu_lrui = (mmu_lrui & 0x19) | 0x20; break;100.493 + case 2: mmu_lrui = (mmu_lrui & 0x3E) | 0x14; break;100.494 + case 3: mmu_lrui = (mmu_lrui | 0x0B); break;100.495 + }100.496 +100.497 + return result;100.498 +}100.499 +100.500 +sh4addr_t mmu_vma_to_phys_read( sh4vma_t addr )100.501 +{100.502 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.503 + if( addr & 0x80000000 ) {100.504 + if( IS_SH4_PRIVMODE() ) {100.505 + if( addr >= 0xE0000000 ) {100.506 + return addr; /* P4 - passthrough */100.507 + } else if( addr < 0xC0000000 ) {100.508 + /* P1, P2 regions are pass-through (no translation) */100.509 + return VMA_TO_EXT_ADDR(addr);100.510 + }100.511 + } else {100.512 + if( addr >= 0xE0000000 && addr < 0xE4000000 &&100.513 + ((mmucr&MMUCR_SQMD) == 0) ) {100.514 + /* Conditional user-mode access to the store-queue (no translation) */100.515 + return addr;100.516 + }100.517 + MMU_READ_ADDR_ERROR();100.518 + return MMU_VMA_ERROR;100.519 + }100.520 + }100.521 +100.522 + if( (mmucr & MMUCR_AT) == 0 ) {100.523 + return VMA_TO_EXT_ADDR(addr);100.524 + }100.525 +100.526 + /* If we get this far, translation is required */100.527 + int entryNo;100.528 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {100.529 + entryNo = mmu_utlb_lookup_vpn_asid( addr );100.530 + } else {100.531 + entryNo = mmu_utlb_lookup_vpn( addr );100.532 + }100.533 +100.534 + switch(entryNo) {100.535 + case -1:100.536 + MMU_TLB_READ_MISS_ERROR(addr);100.537 + return MMU_VMA_ERROR;100.538 + case -2:100.539 + MMU_TLB_MULTI_HIT_ERROR(addr);100.540 + return MMU_VMA_ERROR;100.541 + default:100.542 + if( (mmu_utlb[entryNo].flags & TLB_USERMODE) == 0 &&100.543 + !IS_SH4_PRIVMODE() ) {100.544 + /* protection violation */100.545 + MMU_TLB_READ_PROT_ERROR(addr);100.546 + return MMU_VMA_ERROR;100.547 + }100.548 +100.549 + /* finally generate the target address */100.550 + return (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |100.551 + (addr & (~mmu_utlb[entryNo].mask));100.552 + }100.553 +}100.554 +100.555 +sh4addr_t mmu_vma_to_phys_write( sh4vma_t addr )100.556 +{100.557 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.558 + if( addr & 0x80000000 ) {100.559 + if( IS_SH4_PRIVMODE() ) {100.560 + if( addr >= 0xE0000000 ) {100.561 + return addr; /* P4 - passthrough */100.562 + } else if( addr < 0xC0000000 ) {100.563 + /* P1, P2 regions are pass-through (no translation) */100.564 + return VMA_TO_EXT_ADDR(addr);100.565 + }100.566 + } else {100.567 + if( addr >= 0xE0000000 && addr < 0xE4000000 &&100.568 + ((mmucr&MMUCR_SQMD) == 0) ) {100.569 + /* Conditional user-mode access to the store-queue (no translation) */100.570 + return addr;100.571 + }100.572 + MMU_WRITE_ADDR_ERROR();100.573 + return MMU_VMA_ERROR;100.574 + }100.575 + }100.576 +100.577 + if( (mmucr & MMUCR_AT) == 0 ) {100.578 + return VMA_TO_EXT_ADDR(addr);100.579 + }100.580 +100.581 + /* If we get this far, translation is required */100.582 + int entryNo;100.583 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {100.584 + entryNo = mmu_utlb_lookup_vpn_asid( addr );100.585 + } else {100.586 + entryNo = mmu_utlb_lookup_vpn( addr );100.587 + }100.588 +100.589 + switch(entryNo) {100.590 + case -1:100.591 + MMU_TLB_WRITE_MISS_ERROR(addr);100.592 + return MMU_VMA_ERROR;100.593 + case -2:100.594 + MMU_TLB_MULTI_HIT_ERROR(addr);100.595 + return MMU_VMA_ERROR;100.596 + default:100.597 + if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)100.598 + : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {100.599 + /* protection violation */100.600 + MMU_TLB_WRITE_PROT_ERROR(addr);100.601 + return MMU_VMA_ERROR;100.602 + }100.603 +100.604 + if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {100.605 + MMU_TLB_INITIAL_WRITE_ERROR(addr);100.606 + return MMU_VMA_ERROR;100.607 + }100.608 +100.609 + /* finally generate the target address */100.610 + return (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |100.611 + (addr & (~mmu_utlb[entryNo].mask));100.612 + }100.613 +}100.614 +100.615 +/**100.616 + * Update the icache for an untranslated address100.617 + */100.618 +void mmu_update_icache_phys( sh4addr_t addr )100.619 +{100.620 + if( (addr & 0x1C000000) == 0x0C000000 ) {100.621 + /* Main ram */100.622 + sh4_icache.page_vma = addr & 0xFF000000;100.623 + sh4_icache.page_ppa = 0x0C000000;100.624 + sh4_icache.mask = 0xFF000000;100.625 + sh4_icache.page = sh4_main_ram;100.626 + } else if( (addr & 0x1FE00000) == 0 ) {100.627 + /* BIOS ROM */100.628 + sh4_icache.page_vma = addr & 0xFFE00000;100.629 + sh4_icache.page_ppa = 0;100.630 + sh4_icache.mask = 0xFFE00000;100.631 + sh4_icache.page = mem_get_region(0);100.632 + } else {100.633 + /* not supported */100.634 + sh4_icache.page_vma = -1;100.635 + }100.636 +}100.637 +100.638 +/**100.639 + * Update the sh4_icache structure to describe the page(s) containing the100.640 + * given vma. If the address does not reference a RAM/ROM region, the icache100.641 + * will be invalidated instead.100.642 + * If AT is on, this method will raise TLB exceptions normally100.643 + * (hence this method should only be used immediately prior to execution of100.644 + * code), and otherwise will set the icache according to the matching TLB entry.100.645 + * If AT is off, this method will set the entire referenced RAM/ROM region in100.646 + * the icache.100.647 + * @return TRUE if the update completed (successfully or otherwise), FALSE100.648 + * if an exception was raised.100.649 + */100.650 +gboolean mmu_update_icache( sh4vma_t addr )100.651 +{100.652 + int entryNo;100.653 + if( IS_SH4_PRIVMODE() ) {100.654 + if( addr & 0x80000000 ) {100.655 + if( addr < 0xC0000000 ) {100.656 + /* P1, P2 and P4 regions are pass-through (no translation) */100.657 + mmu_update_icache_phys(addr);100.658 + return TRUE;100.659 + } else if( addr >= 0xE0000000 && addr < 0xFFFFFF00 ) {100.660 + MMU_READ_ADDR_ERROR();100.661 + return FALSE;100.662 + }100.663 + }100.664 +100.665 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.666 + if( (mmucr & MMUCR_AT) == 0 ) {100.667 + mmu_update_icache_phys(addr);100.668 + return TRUE;100.669 + }100.670 +100.671 + entryNo = mmu_itlb_lookup_vpn( addr );100.672 + } else {100.673 + if( addr & 0x80000000 ) {100.674 + MMU_READ_ADDR_ERROR();100.675 + return FALSE;100.676 + }100.677 +100.678 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.679 + if( (mmucr & MMUCR_AT) == 0 ) {100.680 + mmu_update_icache_phys(addr);100.681 + return TRUE;100.682 + }100.683 +100.684 + if( mmucr & MMUCR_SV ) {100.685 + entryNo = mmu_itlb_lookup_vpn( addr );100.686 + } else {100.687 + entryNo = mmu_itlb_lookup_vpn_asid( addr );100.688 + }100.689 + if( entryNo != -1 && (mmu_itlb[entryNo].flags & TLB_USERMODE) == 0 ) {100.690 + MMU_TLB_READ_PROT_ERROR(addr);100.691 + return FALSE;100.692 + }100.693 + }100.694 +100.695 + switch(entryNo) {100.696 + case -1:100.697 + MMU_TLB_READ_MISS_ERROR(addr);100.698 + return FALSE;100.699 + case -2:100.700 + MMU_TLB_MULTI_HIT_ERROR(addr);100.701 + return FALSE;100.702 + default:100.703 + sh4_icache.page_ppa = mmu_itlb[entryNo].ppn & mmu_itlb[entryNo].mask;100.704 + sh4_icache.page = mem_get_region( sh4_icache.page_ppa );100.705 + if( sh4_icache.page == NULL ) {100.706 + sh4_icache.page_vma = -1;100.707 + } else {100.708 + sh4_icache.page_vma = mmu_itlb[entryNo].vpn & mmu_itlb[entryNo].mask;100.709 + sh4_icache.mask = mmu_itlb[entryNo].mask;100.710 + }100.711 + return TRUE;100.712 + }100.713 +}100.714 +100.715 +gboolean sh4_flush_store_queue( sh4addr_t addr )100.716 +{100.717 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);100.718 + int queue = (addr&0x20)>>2;100.719 + sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];100.720 + sh4addr_t target;100.721 + /* Store queue operation */100.722 + if( mmucr & MMUCR_AT ) {100.723 + int entryNo;100.724 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {100.725 + entryNo = mmu_utlb_lookup_vpn_asid( addr );100.726 + } else {100.727 + entryNo = mmu_utlb_lookup_vpn( addr );100.728 + }100.729 + switch(entryNo) {100.730 + case -1:100.731 + MMU_TLB_WRITE_MISS_ERROR(addr);100.732 + return FALSE;100.733 + case -2:100.734 + MMU_TLB_MULTI_HIT_ERROR(addr);100.735 + return FALSE;100.736 + default:100.737 + if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)100.738 + : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {100.739 + /* protection violation */100.740 + MMU_TLB_WRITE_PROT_ERROR(addr);100.741 + return FALSE;100.742 + }100.743 +100.744 + if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {100.745 + MMU_TLB_INITIAL_WRITE_ERROR(addr);100.746 + return FALSE;100.747 + }100.748 +100.749 + /* finally generate the target address */100.750 + target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |100.751 + (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;100.752 + }100.753 + } else {100.754 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;100.755 + target = (addr&0x03FFFFE0) | hi;100.756 + }100.757 + mem_copy_to_sh4( target, src, 32 );100.758 + return TRUE;100.759 +}100.760 +
101.1 --- a/src/sh4/scif.c Thu Dec 20 09:56:07 2007 +0000101.2 +++ b/src/sh4/scif.c Tue Jan 15 20:50:23 2008 +0000101.3 @@ -1,5 +1,5 @@101.4 /**101.5 - * $Id: scif.c,v 1.9 2007-10-07 06:27:12 nkeynes Exp $101.6 + * $Id$101.7 * SCIF (Serial Communication Interface with FIFO) implementation - part of the101.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs101.9 * external serial port
102.1 --- a/src/sh4/sh4.c Thu Dec 20 09:56:07 2007 +0000102.2 +++ b/src/sh4/sh4.c Tue Jan 15 20:50:23 2008 +0000102.3 @@ -1,5 +1,5 @@102.4 /**102.5 - * $Id: sh4.c,v 1.7 2007-11-08 11:54:16 nkeynes Exp $102.6 + * $Id$102.7 *102.8 * SH4 parent module for all CPU modes and SH4 peripheral102.9 * modules.102.10 @@ -30,10 +30,6 @@102.11 #include "clock.h"102.12 #include "syscall.h"102.14 -#define EXV_EXCEPTION 0x100 /* General exception vector */102.15 -#define EXV_TLBMISS 0x400 /* TLB-miss exception vector */102.16 -#define EXV_INTERRUPT 0x600 /* External interrupt vector */102.17 -102.18 void sh4_init( void );102.19 void sh4_xlat_init( void );102.20 void sh4_reset( void );102.21 @@ -52,8 +48,9 @@102.22 struct sh4_registers sh4r;102.23 struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];102.24 int sh4_breakpoint_count = 0;102.25 -extern sh4ptr_t sh4_main_ram;102.26 +sh4ptr_t sh4_main_ram;102.27 static gboolean sh4_use_translator = FALSE;102.28 +struct sh4_icache_struct sh4_icache = { NULL, -1, -1, 0 };102.30 void sh4_set_use_xlat( gboolean use )102.31 {102.32 @@ -70,6 +67,11 @@102.33 #endif102.34 }102.36 +gboolean sh4_is_using_xlat()102.37 +{102.38 + return sh4_use_translator;102.39 +}102.40 +102.41 void sh4_init(void)102.42 {102.43 register_io_regions( mmio_list_sh4mmio );102.44 @@ -148,14 +150,17 @@102.45 }102.48 -void sh4_set_breakpoint( uint32_t pc, int type )102.49 +void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type )102.50 {102.51 sh4_breakpoints[sh4_breakpoint_count].address = pc;102.52 sh4_breakpoints[sh4_breakpoint_count].type = type;102.53 + if( sh4_use_translator ) {102.54 + xlat_invalidate_word( pc );102.55 + }102.56 sh4_breakpoint_count++;102.57 }102.59 -gboolean sh4_clear_breakpoint( uint32_t pc, int type )102.60 +gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type )102.61 {102.62 int i;102.64 @@ -166,6 +171,9 @@102.65 sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;102.66 sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;102.67 }102.68 + if( sh4_use_translator ) {102.69 + xlat_invalidate_word( pc );102.70 + }102.71 sh4_breakpoint_count--;102.72 return TRUE;102.73 }102.74 @@ -203,7 +211,9 @@102.76 void sh4_write_sr( uint32_t newval )102.77 {102.78 - if( (newval ^ sh4r.sr) & SR_RB )102.79 + int oldbank = (sh4r.sr&SR_MDRB) == SR_MDRB;102.80 + int newbank = (newval&SR_MDRB) == SR_MDRB;102.81 + if( oldbank != newbank )102.82 sh4_switch_banks();102.83 sh4r.sr = newval;102.84 sh4r.t = (newval&SR_T) ? 1 : 0;102.85 @@ -254,10 +264,25 @@102.86 RAISE( code, EXV_EXCEPTION );102.87 }102.89 +/**102.90 + * Raise a CPU reset exception with the specified exception code.102.91 + */102.92 +gboolean sh4_raise_reset( int code )102.93 +{102.94 + // FIXME: reset modules as per "manual reset"102.95 + sh4_reset();102.96 + MMIO_WRITE(MMU,EXPEVT,code);102.97 + sh4r.vbr = 0;102.98 + sh4r.pc = 0xA0000000;102.99 + sh4r.new_pc = sh4r.pc + 2;102.100 + sh4_write_sr( (sh4r.sr|SR_MD|SR_BL|SR_RB|SR_IMASK)102.101 + &(~SR_FD) );102.102 +}102.103 +102.104 gboolean sh4_raise_trap( int trap )102.105 {102.106 MMIO_WRITE( MMU, TRA, trap<<2 );102.107 - return sh4_raise_exception( EXC_TRAP );102.108 + RAISE( EXC_TRAP, EXV_EXCEPTION );102.109 }102.111 gboolean sh4_raise_slot_exception( int normal_code, int slot_code ) {
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000103.2 +++ b/src/sh4/sh4.h Tue Jan 15 20:50:23 2008 +0000103.3 @@ -0,0 +1,124 @@103.4 +/**103.5 + * $Id: sh4.h 577 2008-01-01 05:08:38Z nkeynes $103.6 + *103.7 + * This file defines the public functions and definitions exported by the SH4103.8 + * modules.103.9 + *103.10 + * Copyright (c) 2005 Nathan Keynes.103.11 + *103.12 + * This program is free software; you can redistribute it and/or modify103.13 + * it under the terms of the GNU General Public License as published by103.14 + * the Free Software Foundation; either version 2 of the License, or103.15 + * (at your option) any later version.103.16 + *103.17 + * This program is distributed in the hope that it will be useful,103.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of103.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the103.20 + * GNU General Public License for more details.103.21 + */103.22 +103.23 +#ifndef lxdream_sh4_H103.24 +#define lxdream_sh4_H 1103.25 +103.26 +#include "lxdream.h"103.27 +#include "mem.h"103.28 +103.29 +#ifdef __cplusplus103.30 +extern "C" {103.31 +#endif103.32 +103.33 +103.34 +/**103.35 + * SH4 is running normally103.36 + */103.37 +#define SH4_STATE_RUNNING 1103.38 +/**103.39 + * SH4 is not executing instructions but all peripheral modules are still103.40 + * running103.41 + */103.42 +#define SH4_STATE_SLEEP 2103.43 +/**103.44 + * SH4 is not executing instructions, DMAC is halted, but all other peripheral103.45 + * modules are still running103.46 + */103.47 +#define SH4_STATE_DEEP_SLEEP 3103.48 +/**103.49 + * SH4 is not executing instructions and all peripheral modules are also103.50 + * stopped. As close as you can get to powered-off without actually being103.51 + * off.103.52 + */103.53 +#define SH4_STATE_STANDBY 4103.54 +103.55 +/**103.56 + * sh4r.event_types flag indicating a pending IRQ103.57 + */103.58 +#define PENDING_IRQ 1103.59 +103.60 +/**103.61 + * sh4r.event_types flag indicating a pending event (from the event queue)103.62 + */103.63 +#define PENDING_EVENT 2103.64 +103.65 +/**103.66 + * SH4 register structure103.67 + */103.68 +struct sh4_registers {103.69 + uint32_t r[16];103.70 + uint32_t sr, pr, pc, fpscr;103.71 + uint32_t t, m, q, s; /* really boolean - 0 or 1 */103.72 + int32_t fpul;103.73 + float *fr_bank;103.74 + float fr[2][16];103.75 + uint64_t mac;103.76 + uint32_t gbr, ssr, spc, sgr, dbr, vbr;103.77 +103.78 + uint32_t r_bank[8]; /* hidden banked registers */103.79 + int32_t store_queue[16]; /* technically 2 banks of 32 bytes */103.80 +103.81 + uint32_t new_pc; /* Not a real register, but used to handle delay slots */103.82 + uint32_t event_pending; /* slice cycle time of the next pending event, or FFFFFFFF103.83 + when no events are pending */103.84 + uint32_t event_types; /* bit 0 = IRQ pending, bit 1 = general event pending */103.85 + int in_delay_slot; /* flag to indicate the current instruction is in103.86 + * a delay slot (certain rules apply) */103.87 + uint32_t slice_cycle; /* Current nanosecond within the timeslice */103.88 + int sh4_state; /* Current power-on state (one of the SH4_STATE_* values ) */103.89 +};103.90 +103.91 +extern struct sh4_registers sh4r;103.92 +103.93 +/**103.94 + * Switch between translation and emulation execution modes. Note that this103.95 + * should only be used while the system is stopped. If the system was built103.96 + * without translation support, this method has no effect.103.97 + *103.98 + * @param use TRUE for translation mode, FALSE for emulation mode.103.99 + */103.100 +void sh4_set_use_xlat( gboolean use );103.101 +103.102 +/**103.103 + * Test if system is currently using the translation engine.103.104 + */103.105 +gboolean sh4_is_using_xlat();103.106 +103.107 +/**103.108 + * Explicitly set the SH4 PC to the supplied value - this will be the next103.109 + * instruction executed. This should only be called while the system is stopped.103.110 + */103.111 +void sh4_set_pc( int pc );103.112 +103.113 +/**103.114 + * Execute (using the emulator) a single instruction (in other words, perform a103.115 + * single-step operation).103.116 + */103.117 +gboolean sh4_execute_instruction( void );103.118 +103.119 +/* SH4 breakpoints */103.120 +void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type );103.121 +gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type );103.122 +int sh4_get_breakpoint( uint32_t pc );103.123 +103.124 +#ifdef __cplusplus103.125 +}103.126 +#endif103.127 +#endif /* !lxdream_sh4_H */
104.1 --- a/src/sh4/sh4core.c Thu Dec 20 09:56:07 2007 +0000104.2 +++ b/src/sh4/sh4core.c Tue Jan 15 20:50:23 2008 +0000104.3 @@ -1,5 +1,5 @@104.4 /**104.5 - * $Id: sh4core.in,v 1.10 2007-11-04 08:49:18 nkeynes Exp $104.6 + * $Id$104.7 *104.8 * SH4 emulation core, and parent module for all the SH4 peripheral104.9 * modules.104.10 @@ -18,6 +18,7 @@104.11 */104.13 #define MODULE sh4_module104.14 +#include <assert.h>104.15 #include <math.h>104.16 #include "dream.h"104.17 #include "dreamcast.h"104.18 @@ -38,9 +39,6 @@104.20 /********************** SH4 Module Definition ****************************/104.22 -uint16_t *sh4_icache = NULL;104.23 -uint32_t sh4_icache_addr = 0;104.24 -104.25 uint32_t sh4_run_slice( uint32_t nanosecs )104.26 {104.27 int i;104.28 @@ -164,12 +162,12 @@104.29 #define TRACE_RETURN( source, dest )104.30 #endif104.32 -#define MEM_READ_BYTE( addr ) sh4_read_byte(addr)104.33 -#define MEM_READ_WORD( addr ) sh4_read_word(addr)104.34 -#define MEM_READ_LONG( addr ) sh4_read_long(addr)104.35 -#define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)104.36 -#define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)104.37 -#define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)104.38 +#define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }104.39 +#define MEM_READ_WORD( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_word(memtmp); }104.40 +#define MEM_READ_LONG( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_long(memtmp); }104.41 +#define MEM_WRITE_BYTE( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_byte(memtmp, val); }104.42 +#define MEM_WRITE_WORD( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_word(memtmp, val); }104.43 +#define MEM_WRITE_LONG( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_long(memtmp, val); }104.45 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)104.47 @@ -223,6 +221,7 @@104.48 uint32_t tmp;104.49 float ftmp;104.50 double dtmp;104.51 + int64_t memtmp; // temporary holder for memory reads104.53 #define R0 sh4r.r[0]104.54 pc = sh4r.pc;104.55 @@ -236,22 +235,20 @@104.56 CHECKRALIGN16(pc);104.58 /* Read instruction */104.59 - uint32_t pageaddr = pc >> 12;104.60 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {104.61 - ir = sh4_icache[(pc&0xFFF)>>1];104.62 - } else {104.63 - sh4_icache = (uint16_t *)mem_get_page(pc);104.64 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {104.65 - /* If someone's actually been so daft as to try to execute out of an IO104.66 - * region, fallback on the full-blown memory read104.67 - */104.68 - sh4_icache = NULL;104.69 - ir = MEM_READ_WORD(pc);104.70 - } else {104.71 - sh4_icache_addr = pageaddr;104.72 - ir = sh4_icache[(pc&0xFFF)>>1];104.73 + if( !IS_IN_ICACHE(pc) ) {104.74 + if( !mmu_update_icache(pc) ) {104.75 + // Fault - look for the fault handler104.76 + if( !mmu_update_icache(sh4r.pc) ) {104.77 + // double fault - halt104.78 + ERROR( "Double fault - halting" );104.79 + dreamcast_stop();104.80 + return FALSE;104.81 + }104.82 }104.83 + pc = sh4r.pc;104.84 }104.85 + assert( IS_IN_ICACHE(pc) );104.86 + ir = *(uint16_t *)GET_ICACHE_PTR(sh4r.pc);104.87 switch( (ir&0xF000) >> 12 ) {104.88 case 0x0:104.89 switch( ir&0xF ) {104.90 @@ -551,21 +548,21 @@104.91 case 0xC:104.92 { /* MOV.B @(R0, Rm), Rn */104.93 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.94 - sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] );104.95 + MEM_READ_BYTE( R0 + sh4r.r[Rm], sh4r.r[Rn] );104.96 }104.97 break;104.98 case 0xD:104.99 { /* MOV.W @(R0, Rm), Rn */104.100 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.101 CHECKRALIGN16( R0 + sh4r.r[Rm] );104.102 - sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );104.103 + MEM_READ_WORD( R0 + sh4r.r[Rm], sh4r.r[Rn] );104.104 }104.105 break;104.106 case 0xE:104.107 { /* MOV.L @(R0, Rm), Rn */104.108 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.109 CHECKRALIGN32( R0 + sh4r.r[Rm] );104.110 - sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );104.111 + MEM_READ_LONG( R0 + sh4r.r[Rm], sh4r.r[Rn] );104.112 }104.113 break;104.114 case 0xF:104.115 @@ -573,9 +570,11 @@104.116 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.117 CHECKRALIGN32( sh4r.r[Rm] );104.118 CHECKRALIGN32( sh4r.r[Rn] );104.119 - int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));104.120 + MEM_READ_LONG(sh4r.r[Rn], tmp);104.121 + int64_t tmpl = SIGNEXT32(tmp);104.122 sh4r.r[Rn] += 4;104.123 - tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;104.124 + MEM_READ_LONG(sh4r.r[Rm], tmp);104.125 + tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;104.126 sh4r.r[Rm] += 4;104.127 if( sh4r.s ) {104.128 /* 48-bit Saturation. Yuch */104.129 @@ -1058,8 +1057,9 @@104.130 { /* LDS.L @Rm+, MACH */104.131 uint32_t Rm = ((ir>>8)&0xF);104.132 CHECKRALIGN32( sh4r.r[Rm] );104.133 + MEM_READ_LONG(sh4r.r[Rm], tmp);104.134 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |104.135 - (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);104.136 + (((uint64_t)tmp)<<32);104.137 sh4r.r[Rm] += 4;104.138 }104.139 break;104.140 @@ -1067,8 +1067,9 @@104.141 { /* LDS.L @Rm+, MACL */104.142 uint32_t Rm = ((ir>>8)&0xF);104.143 CHECKRALIGN32( sh4r.r[Rm] );104.144 + MEM_READ_LONG(sh4r.r[Rm], tmp);104.145 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |104.146 - (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));104.147 + (uint64_t)((uint32_t)tmp);104.148 sh4r.r[Rm] += 4;104.149 }104.150 break;104.151 @@ -1076,7 +1077,7 @@104.152 { /* LDS.L @Rm+, PR */104.153 uint32_t Rm = ((ir>>8)&0xF);104.154 CHECKRALIGN32( sh4r.r[Rm] );104.155 - sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );104.156 + MEM_READ_LONG( sh4r.r[Rm], sh4r.pr );104.157 sh4r.r[Rm] += 4;104.158 }104.159 break;104.160 @@ -1085,7 +1086,7 @@104.161 uint32_t Rm = ((ir>>8)&0xF);104.162 CHECKPRIV();104.163 CHECKRALIGN32( sh4r.r[Rm] );104.164 - sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);104.165 + MEM_READ_LONG(sh4r.r[Rm], sh4r.sgr);104.166 sh4r.r[Rm] +=4;104.167 }104.168 break;104.169 @@ -1093,7 +1094,7 @@104.170 { /* LDS.L @Rm+, FPUL */104.171 uint32_t Rm = ((ir>>8)&0xF);104.172 CHECKRALIGN32( sh4r.r[Rm] );104.173 - sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);104.174 + MEM_READ_LONG(sh4r.r[Rm], sh4r.fpul);104.175 sh4r.r[Rm] +=4;104.176 }104.177 break;104.178 @@ -1101,7 +1102,7 @@104.179 { /* LDS.L @Rm+, FPSCR */104.180 uint32_t Rm = ((ir>>8)&0xF);104.181 CHECKRALIGN32( sh4r.r[Rm] );104.182 - sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);104.183 + MEM_READ_LONG(sh4r.r[Rm], sh4r.fpscr);104.184 sh4r.r[Rm] +=4;104.185 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];104.186 }104.187 @@ -1111,7 +1112,7 @@104.188 uint32_t Rm = ((ir>>8)&0xF);104.189 CHECKPRIV();104.190 CHECKRALIGN32( sh4r.r[Rm] );104.191 - sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);104.192 + MEM_READ_LONG(sh4r.r[Rm], sh4r.dbr);104.193 sh4r.r[Rm] +=4;104.194 }104.195 break;104.196 @@ -1130,7 +1131,8 @@104.197 CHECKSLOTILLEGAL();104.198 CHECKPRIV();104.199 CHECKWALIGN32( sh4r.r[Rm] );104.200 - sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );104.201 + MEM_READ_LONG(sh4r.r[Rm], tmp);104.202 + sh4_write_sr( tmp );104.203 sh4r.r[Rm] +=4;104.204 }104.205 break;104.206 @@ -1138,7 +1140,7 @@104.207 { /* LDC.L @Rm+, GBR */104.208 uint32_t Rm = ((ir>>8)&0xF);104.209 CHECKRALIGN32( sh4r.r[Rm] );104.210 - sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);104.211 + MEM_READ_LONG(sh4r.r[Rm], sh4r.gbr);104.212 sh4r.r[Rm] +=4;104.213 }104.214 break;104.215 @@ -1147,7 +1149,7 @@104.216 uint32_t Rm = ((ir>>8)&0xF);104.217 CHECKPRIV();104.218 CHECKRALIGN32( sh4r.r[Rm] );104.219 - sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);104.220 + MEM_READ_LONG(sh4r.r[Rm], sh4r.vbr);104.221 sh4r.r[Rm] +=4;104.222 }104.223 break;104.224 @@ -1156,7 +1158,7 @@104.225 uint32_t Rm = ((ir>>8)&0xF);104.226 CHECKPRIV();104.227 CHECKRALIGN32( sh4r.r[Rm] );104.228 - sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);104.229 + MEM_READ_LONG(sh4r.r[Rm], sh4r.ssr);104.230 sh4r.r[Rm] +=4;104.231 }104.232 break;104.233 @@ -1165,7 +1167,7 @@104.234 uint32_t Rm = ((ir>>8)&0xF);104.235 CHECKPRIV();104.236 CHECKRALIGN32( sh4r.r[Rm] );104.237 - sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);104.238 + MEM_READ_LONG(sh4r.r[Rm], sh4r.spc);104.239 sh4r.r[Rm] +=4;104.240 }104.241 break;104.242 @@ -1179,7 +1181,7 @@104.243 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);104.244 CHECKPRIV();104.245 CHECKRALIGN32( sh4r.r[Rm] );104.246 - sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );104.247 + MEM_READ_LONG( sh4r.r[Rm], sh4r.r_bank[Rn_BANK] );104.248 sh4r.r[Rm] += 4;104.249 }104.250 break;104.251 @@ -1307,7 +1309,7 @@104.252 case 0x1:104.253 { /* TAS.B @Rn */104.254 uint32_t Rn = ((ir>>8)&0xF);104.255 - tmp = MEM_READ_BYTE( sh4r.r[Rn] );104.256 + MEM_READ_BYTE( sh4r.r[Rn], tmp );104.257 sh4r.t = ( tmp == 0 ? 1 : 0 );104.258 MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );104.259 }104.260 @@ -1406,9 +1408,11 @@104.261 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.262 CHECKRALIGN16( sh4r.r[Rn] );104.263 CHECKRALIGN16( sh4r.r[Rm] );104.264 - int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));104.265 + MEM_READ_WORD(sh4r.r[Rn], tmp);104.266 + int32_t stmp = SIGNEXT16(tmp);104.267 sh4r.r[Rn] += 2;104.268 - stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));104.269 + MEM_READ_WORD(sh4r.r[Rm], tmp);104.270 + stmp = stmp * SIGNEXT16(tmp);104.271 sh4r.r[Rm] += 2;104.272 if( sh4r.s ) {104.273 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;104.274 @@ -1432,7 +1436,7 @@104.275 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;104.276 tmp = sh4r.r[Rm] + disp;104.277 CHECKRALIGN32( tmp );104.278 - sh4r.r[Rn] = MEM_READ_LONG( tmp );104.279 + MEM_READ_LONG( tmp, sh4r.r[Rn] );104.280 }104.281 break;104.282 case 0x6:104.283 @@ -1440,19 +1444,19 @@104.284 case 0x0:104.285 { /* MOV.B @Rm, Rn */104.286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.287 - sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] );104.288 + MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] );104.289 }104.290 break;104.291 case 0x1:104.292 { /* MOV.W @Rm, Rn */104.293 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.294 - CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] );104.295 + CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] );104.296 }104.297 break;104.298 case 0x2:104.299 { /* MOV.L @Rm, Rn */104.300 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.301 - CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] );104.302 + CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] );104.303 }104.304 break;104.305 case 0x3:104.306 @@ -1464,19 +1468,19 @@104.307 case 0x4:104.308 { /* MOV.B @Rm+, Rn */104.309 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.310 - sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++;104.311 + MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] ++;104.312 }104.313 break;104.314 case 0x5:104.315 { /* MOV.W @Rm+, Rn */104.316 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.317 - CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2;104.318 + CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 2;104.319 }104.320 break;104.321 case 0x6:104.322 { /* MOV.L @Rm+, Rn */104.323 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);104.324 - CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4;104.325 + CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 4;104.326 }104.327 break;104.328 case 0x7:104.329 @@ -1562,7 +1566,7 @@104.330 case 0x4:104.331 { /* MOV.B @(disp, Rm), R0 */104.332 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);104.333 - R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp );104.334 + MEM_READ_BYTE( sh4r.r[Rm] + disp, R0 );104.335 }104.336 break;104.337 case 0x5:104.338 @@ -1570,7 +1574,7 @@104.339 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;104.340 tmp = sh4r.r[Rm] + disp;104.341 CHECKRALIGN16( tmp );104.342 - R0 = MEM_READ_WORD( tmp );104.343 + MEM_READ_WORD( tmp, R0 );104.344 }104.345 break;104.346 case 0x8:104.347 @@ -1640,7 +1644,7 @@104.348 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;104.349 CHECKSLOTILLEGAL();104.350 tmp = pc + 4 + disp;104.351 - sh4r.r[Rn] = MEM_READ_WORD( tmp );104.352 + MEM_READ_WORD( tmp, sh4r.r[Rn] );104.353 }104.354 break;104.355 case 0xA:104.356 @@ -1695,15 +1699,15 @@104.357 { /* TRAPA #imm */104.358 uint32_t imm = (ir&0xFF);104.359 CHECKSLOTILLEGAL();104.360 - MMIO_WRITE( MMU, TRA, imm<<2 );104.361 sh4r.pc += 2;104.362 - sh4_raise_exception( EXC_TRAP );104.363 + sh4_raise_trap( imm );104.364 + return TRUE;104.365 }104.366 break;104.367 case 0x4:104.368 { /* MOV.B @(disp, GBR), R0 */104.369 uint32_t disp = (ir&0xFF);104.370 - R0 = MEM_READ_BYTE( sh4r.gbr + disp );104.371 + MEM_READ_BYTE( sh4r.gbr + disp, R0 );104.372 }104.373 break;104.374 case 0x5:104.375 @@ -1711,7 +1715,7 @@104.376 uint32_t disp = (ir&0xFF)<<1;104.377 tmp = sh4r.gbr + disp;104.378 CHECKRALIGN16( tmp );104.379 - R0 = MEM_READ_WORD( tmp );104.380 + MEM_READ_WORD( tmp, R0 );104.381 }104.382 break;104.383 case 0x6:104.384 @@ -1719,7 +1723,7 @@104.385 uint32_t disp = (ir&0xFF)<<2;104.386 tmp = sh4r.gbr + disp;104.387 CHECKRALIGN32( tmp );104.388 - R0 = MEM_READ_LONG( tmp );104.389 + MEM_READ_LONG( tmp, R0 );104.390 }104.391 break;104.392 case 0x7:104.393 @@ -1756,25 +1760,25 @@104.394 case 0xC:104.395 { /* TST.B #imm, @(R0, GBR) */104.396 uint32_t imm = (ir&0xFF);104.397 - sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 );104.398 + MEM_READ_BYTE(R0+sh4r.gbr, tmp); sh4r.t = ( tmp & imm ? 0 : 1 );104.399 }104.400 break;104.401 case 0xD:104.402 { /* AND.B #imm, @(R0, GBR) */104.403 uint32_t imm = (ir&0xFF);104.404 - MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) );104.405 + MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & tmp );104.406 }104.407 break;104.408 case 0xE:104.409 { /* XOR.B #imm, @(R0, GBR) */104.410 uint32_t imm = (ir&0xFF);104.411 - MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) );104.412 + MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ tmp );104.413 }104.414 break;104.415 case 0xF:104.416 { /* OR.B #imm, @(R0, GBR) */104.417 uint32_t imm = (ir&0xFF);104.418 - MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) );104.419 + MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | tmp );104.420 }104.421 break;104.422 }104.423 @@ -1784,7 +1788,7 @@104.424 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;104.425 CHECKSLOTILLEGAL();104.426 tmp = (pc&0xFFFFFFFC) + disp + 4;104.427 - sh4r.r[Rn] = MEM_READ_LONG( tmp );104.428 + MEM_READ_LONG( tmp, sh4r.r[Rn] );104.429 }104.430 break;104.431 case 0xE:
105.1 --- a/src/sh4/sh4core.h Thu Dec 20 09:56:07 2007 +0000105.2 +++ b/src/sh4/sh4core.h Tue Jan 15 20:50:23 2008 +0000105.3 @@ -1,5 +1,5 @@105.4 /**105.5 - * $Id: sh4core.h,v 1.26 2007-10-06 09:03:24 nkeynes Exp $105.6 + * $Id$105.7 *105.8 * This file defines the internal functions exported/used by the SH4 core,105.9 * except for disassembly functions defined in sh4dasm.h105.10 @@ -24,96 +24,108 @@105.11 #include <stdint.h>105.12 #include <stdio.h>105.13 #include "mem.h"105.14 +#include "sh4/sh4.h"105.16 #ifdef __cplusplus105.17 extern "C" {105.18 -#if 0105.19 -}105.20 -#endif105.21 #endif105.23 +/* Breakpoint data structure */105.24 +extern struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];105.25 +extern int sh4_breakpoint_count;105.26 +extern sh4ptr_t sh4_main_ram;105.28 /**105.29 - * SH4 is running normally105.30 + * Cached direct pointer to the current instruction page. If AT is on, this105.31 + * is derived from the ITLB, otherwise this will be the entire memory region.105.32 + * This is actually a fairly useful optimization, as we can make a lot of105.33 + * assumptions about the "current page" that we can't make in general for105.34 + * arbitrary virtual addresses.105.35 */105.36 -#define SH4_STATE_RUNNING 1105.37 +struct sh4_icache_struct {105.38 + sh4ptr_t page; // Page pointer (NULL if no page)105.39 + sh4vma_t page_vma; // virtual address of the page.105.40 + sh4addr_t page_ppa; // physical address of the page105.41 + uint32_t mask; // page mask105.42 +};105.43 +extern struct sh4_icache_struct sh4_icache;105.44 +105.45 /**105.46 - * SH4 is not executing instructions but all peripheral modules are still105.47 - * running105.48 + * Test if a given address is contained in the current icache entry105.49 */105.50 -#define SH4_STATE_SLEEP 2105.51 +#define IS_IN_ICACHE(addr) (sh4_icache.page_vma == ((addr) & sh4_icache.mask))105.52 /**105.53 - * SH4 is not executing instructions, DMAC is halted, but all other peripheral105.54 - * modules are still running105.55 + * Return a pointer for the given vma, under the assumption that it is105.56 + * actually contained in the current icache entry.105.57 */105.58 -#define SH4_STATE_DEEP_SLEEP 3105.59 +#define GET_ICACHE_PTR(addr) (sh4_icache.page + ((addr)-sh4_icache.page_vma))105.60 /**105.61 - * SH4 is not executing instructions and all peripheral modules are also105.62 - * stopped. As close as you can get to powered-off without actually being105.63 - * off.105.64 + * Return the physical (external) address for the given vma, assuming that it is105.65 + * actually contained in the current icache entry.105.66 */105.67 -#define SH4_STATE_STANDBY 4105.68 +#define GET_ICACHE_PHYS(addr) (sh4_icache.page_ppa + ((addr)-sh4_icache.page_vma))105.70 -#define PENDING_IRQ 1105.71 -#define PENDING_EVENT 2105.72 -105.73 -struct sh4_registers {105.74 - uint32_t r[16];105.75 - uint32_t sr, pr, pc, fpscr;105.76 - uint32_t t, m, q, s; /* really boolean - 0 or 1 */105.77 - int32_t fpul;105.78 - float *fr_bank;105.79 - float fr[2][16];105.80 - uint64_t mac;105.81 - uint32_t gbr, ssr, spc, sgr, dbr, vbr;105.82 -105.83 - uint32_t r_bank[8]; /* hidden banked registers */105.84 - int32_t store_queue[16]; /* technically 2 banks of 32 bytes */105.85 -105.86 - uint32_t new_pc; /* Not a real register, but used to handle delay slots */105.87 - uint32_t event_pending; /* slice cycle time of the next pending event, or FFFFFFFF105.88 - when no events are pending */105.89 - uint32_t event_types; /* bit 0 = IRQ pending, bit 1 = general event pending */105.90 - int in_delay_slot; /* flag to indicate the current instruction is in105.91 - * a delay slot (certain rules apply) */105.92 - uint32_t slice_cycle; /* Current nanosecond within the timeslice */105.93 - int sh4_state; /* Current power-on state (one of the SH4_STATE_* values ) */105.94 -};105.95 -105.96 -extern struct sh4_registers sh4r;105.97 -extern struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];105.98 -extern int sh4_breakpoint_count;105.99 -105.100 -105.101 -/* Public functions */105.102 -void sh4_set_use_xlat( gboolean use );105.103 +/* SH4 module functions */105.104 void sh4_init( void );105.105 void sh4_reset( void );105.106 void sh4_run( void );105.107 -void sh4_runto( uint32_t pc, uint32_t count );105.108 -void sh4_runfor( uint32_t count );105.109 -int sh4_isrunning( void );105.110 void sh4_stop( void );105.111 -void sh4_set_pc( int );105.112 +105.113 +/* SH4 peripheral module functions */105.114 +void CPG_reset( void );105.115 +void DMAC_reset( void );105.116 +void DMAC_run_slice( uint32_t );105.117 +void DMAC_save_state( FILE * );105.118 +int DMAC_load_state( FILE * );105.119 +void INTC_reset( void );105.120 +void INTC_save_state( FILE *f );105.121 +int INTC_load_state( FILE *f );105.122 +void MMU_init( void );105.123 +void MMU_reset( void );105.124 +void MMU_save_state( FILE *f );105.125 +int MMU_load_state( FILE *f );105.126 +void MMU_ldtlb();105.127 +void SCIF_reset( void );105.128 +void SCIF_run_slice( uint32_t );105.129 +void SCIF_save_state( FILE *f );105.130 +int SCIF_load_state( FILE *f );105.131 +void SCIF_update_line_speed(void);105.132 +void TMU_reset( void );105.133 +void TMU_run_slice( uint32_t );105.134 +void TMU_save_state( FILE * );105.135 +int TMU_load_state( FILE * );105.136 +void TMU_update_clocks( void );105.137 +105.138 +/* SH4 instruction support methods */105.139 void sh4_sleep( void );105.140 void sh4_fsca( uint32_t angle, float *fr );105.141 void sh4_ftrv( float *fv, float *xmtrx );105.142 +uint32_t sh4_read_sr(void);105.143 +void sh4_write_sr(uint32_t val);105.144 void signsat48(void);105.146 -gboolean sh4_execute_instruction( void );105.147 -gboolean sh4_raise_exception( int );105.148 -gboolean sh4_raise_trap( int );105.149 -gboolean sh4_raise_slot_exception( int, int );105.150 -gboolean sh4_raise_tlb_exception( int );105.151 -void sh4_set_breakpoint( uint32_t pc, int type );105.152 -gboolean sh4_clear_breakpoint( uint32_t pc, int type );105.153 -int sh4_get_breakpoint( uint32_t pc );105.154 -void sh4_accept_interrupt( void );105.155 +/* SH4 Memory */105.156 +#define MMU_VMA_ERROR 0x8000000105.157 +/**105.158 + * Update the sh4_icache structure to contain the specified vma. If the vma105.159 + * cannot be resolved, an MMU exception is raised and the function returns105.160 + * FALSE. Otherwise, returns TRUE and updates sh4_icache accordingly.105.161 + * Note: If the vma resolves to a non-memory area, sh4_icache will be105.162 + * invalidated, but the function will still return TRUE.105.163 + * @return FALSE if an MMU exception was raised, otherwise TRUE.105.164 + */105.165 +gboolean mmu_update_icache( sh4vma_t addr );105.167 -#define BREAK_ONESHOT 1105.168 -#define BREAK_PERM 2105.169 +/**105.170 + * Resolve a virtual address through the TLB for a read operation, returning105.171 + * the resultant P4 or external address. If the resolution fails, the105.172 + * appropriate MMU exception is raised and the value MMU_VMA_ERROR is returned.105.173 + * @return An external address (0x00000000-0x1FFFFFFF), a P4 address105.174 + * (0xE0000000 - 0xFFFFFFFF), or MMU_VMA_ERROR.105.175 + */105.176 +sh4addr_t mmu_vma_to_phys_read( sh4vma_t addr );105.177 +sh4addr_t mmu_vma_to_phys_write( sh4vma_t addr );105.179 -/* SH4 Memory */105.180 int64_t sh4_read_quad( sh4addr_t addr );105.181 int32_t sh4_read_long( sh4addr_t addr );105.182 int32_t sh4_read_word( sh4addr_t addr );105.183 @@ -123,36 +135,35 @@105.184 void sh4_write_word( sh4addr_t addr, uint32_t val );105.185 void sh4_write_byte( sh4addr_t addr, uint32_t val );105.186 int32_t sh4_read_phys_word( sh4addr_t addr );105.187 -void sh4_flush_store_queue( sh4addr_t addr );105.188 +gboolean sh4_flush_store_queue( sh4addr_t addr );105.190 -/* SH4 Support methods */105.191 -uint32_t sh4_read_sr(void);105.192 -void sh4_write_sr(uint32_t val);105.193 +/* SH4 Exceptions */105.194 +#define EXC_POWER_RESET 0x000 /* reset vector */105.195 +#define EXC_MANUAL_RESET 0x020 /* reset vector */105.196 +#define EXC_TLB_MISS_READ 0x040 /* TLB vector */105.197 +#define EXC_TLB_MISS_WRITE 0x060 /* TLB vector */105.198 +#define EXC_INIT_PAGE_WRITE 0x080105.199 +#define EXC_TLB_PROT_READ 0x0A0105.200 +#define EXC_TLB_PROT_WRITE 0x0C0105.201 +#define EXC_DATA_ADDR_READ 0x0E0105.202 +#define EXC_DATA_ADDR_WRITE 0x100105.203 +#define EXC_TLB_MULTI_HIT 0x140105.204 +#define EXC_SLOT_ILLEGAL 0x1A0105.205 +#define EXC_ILLEGAL 0x180105.206 +#define EXC_TRAP 0x160105.207 +#define EXC_FPU_DISABLED 0x800105.208 +#define EXC_SLOT_FPU_DISABLED 0x820105.210 -/* Peripheral functions */105.211 -void CPG_reset( void );105.212 -void TMU_run_slice( uint32_t );105.213 -void TMU_update_clocks( void );105.214 -void TMU_reset( void );105.215 -void TMU_save_state( FILE * );105.216 -int TMU_load_state( FILE * );105.217 -void DMAC_reset( void );105.218 -void DMAC_run_slice( uint32_t );105.219 -void DMAC_save_state( FILE * );105.220 -int DMAC_load_state( FILE * );105.221 -void SCIF_reset( void );105.222 -void SCIF_run_slice( uint32_t );105.223 -void SCIF_save_state( FILE *f );105.224 -int SCIF_load_state( FILE *f );105.225 -void INTC_reset( void );105.226 -void INTC_save_state( FILE *f );105.227 -int INTC_load_state( FILE *f );105.228 -void MMU_init( void );105.229 -void MMU_reset( void );105.230 -void MMU_save_state( FILE *f );105.231 -int MMU_load_state( FILE *f );105.232 -void MMU_ldtlb();105.233 -void SCIF_update_line_speed(void);105.234 +#define EXV_EXCEPTION 0x100 /* General exception vector */105.235 +#define EXV_TLBMISS 0x400 /* TLB-miss exception vector */105.236 +#define EXV_INTERRUPT 0x600 /* External interrupt vector */105.237 +105.238 +gboolean sh4_raise_exception( int );105.239 +gboolean sh4_raise_reset( int );105.240 +gboolean sh4_raise_trap( int );105.241 +gboolean sh4_raise_slot_exception( int, int );105.242 +gboolean sh4_raise_tlb_exception( int );105.243 +void sh4_accept_interrupt( void );105.245 #define SIGNEXT4(n) ((((int32_t)(n))<<28)>>28)105.246 #define SIGNEXT8(n) ((int32_t)((int8_t)(n)))105.247 @@ -160,6 +171,7 @@105.248 #define SIGNEXT16(n) ((int32_t)((int16_t)(n)))105.249 #define SIGNEXT32(n) ((int64_t)((int32_t)(n)))105.250 #define SIGNEXT48(n) ((((int64_t)(n))<<16)>>16)105.251 +#define ZEROEXT32(n) ((int64_t)((uint64_t)((uint32_t)(n))))105.253 /* Status Register (SR) bits */105.254 #define SR_MD 0x40000000 /* Processor mode ( User=0, Privileged=1 ) */105.255 @@ -173,6 +185,7 @@105.256 #define SR_T 0x00000001 /* True/false or carry/borrow */105.257 #define SR_MASK 0x700083F3105.258 #define SR_MQSTMASK 0xFFFFFCFC /* Mask to clear the flags we're keeping separately */105.259 +#define SR_MDRB 0x60000000 /* MD+RB mask for convenience */105.261 #define IS_SH4_PRIVMODE() (sh4r.sr&SR_MD)105.262 #define SH4_INTMASK() ((sh4r.sr&SR_IMASK)>>4)105.263 @@ -200,34 +213,6 @@105.264 #define FPULf *((float *)&sh4r.fpul)105.265 #define FPULi (sh4r.fpul)105.267 -/* CPU-generated exception code/vector pairs */105.268 -#define EXC_POWER_RESET 0x000 /* vector special */105.269 -#define EXC_MANUAL_RESET 0x020105.270 -#define EXC_DATA_ADDR_READ 0x0E0105.271 -#define EXC_DATA_ADDR_WRITE 0x100105.272 -#define EXC_SLOT_ILLEGAL 0x1A0105.273 -#define EXC_ILLEGAL 0x180105.274 -#define EXC_TRAP 0x160105.275 -#define EXC_FPU_DISABLED 0x800105.276 -#define EXC_SLOT_FPU_DISABLED 0x820105.277 -105.278 -/* Exceptions (for use with sh4_raise_exception) */105.279 -105.280 -#define EX_ILLEGAL_INSTRUCTION 0x180, 0x100105.281 -#define EX_SLOT_ILLEGAL 0x1A0, 0x100105.282 -#define EX_TLB_MISS_READ 0x040, 0x400105.283 -#define EX_TLB_MISS_WRITE 0x060, 0x400105.284 -#define EX_INIT_PAGE_WRITE 0x080, 0x100105.285 -#define EX_TLB_PROT_READ 0x0A0, 0x100105.286 -#define EX_TLB_PROT_WRITE 0x0C0, 0x100105.287 -#define EX_DATA_ADDR_READ 0x0E0, 0x100105.288 -#define EX_DATA_ADDR_WRITE 0x100, 0x100105.289 -#define EX_FPU_EXCEPTION 0x120, 0x100105.290 -#define EX_TRAPA 0x160, 0x100105.291 -#define EX_BREAKPOINT 0x1E0, 0x100105.292 -#define EX_FPU_DISABLED 0x800, 0x100105.293 -#define EX_SLOT_FPU_DISABLED 0x820, 0x100105.294 -105.295 #define SH4_WRITE_STORE_QUEUE(addr,val) sh4r.store_queue[(addr>>2)&0xF] = val;105.297 #ifdef __cplusplus
106.1 --- a/src/sh4/sh4core.in Thu Dec 20 09:56:07 2007 +0000106.2 +++ b/src/sh4/sh4core.in Tue Jan 15 20:50:23 2008 +0000106.3 @@ -1,5 +1,5 @@106.4 /**106.5 - * $Id: sh4core.in,v 1.10 2007-11-04 08:49:18 nkeynes Exp $106.6 + * $Id$106.7 *106.8 * SH4 emulation core, and parent module for all the SH4 peripheral106.9 * modules.106.10 @@ -18,6 +18,7 @@106.11 */106.13 #define MODULE sh4_module106.14 +#include <assert.h>106.15 #include <math.h>106.16 #include "dream.h"106.17 #include "dreamcast.h"106.18 @@ -38,9 +39,6 @@106.20 /********************** SH4 Module Definition ****************************/106.22 -uint16_t *sh4_icache = NULL;106.23 -uint32_t sh4_icache_addr = 0;106.24 -106.25 uint32_t sh4_run_slice( uint32_t nanosecs )106.26 {106.27 int i;106.28 @@ -164,12 +162,12 @@106.29 #define TRACE_RETURN( source, dest )106.30 #endif106.32 -#define MEM_READ_BYTE( addr ) sh4_read_byte(addr)106.33 -#define MEM_READ_WORD( addr ) sh4_read_word(addr)106.34 -#define MEM_READ_LONG( addr ) sh4_read_long(addr)106.35 -#define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)106.36 -#define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)106.37 -#define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)106.38 +#define MEM_READ_BYTE( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_byte(memtmp); }106.39 +#define MEM_READ_WORD( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_word(memtmp); }106.40 +#define MEM_READ_LONG( addr, val ) memtmp = mmu_vma_to_phys_read(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { val = sh4_read_long(memtmp); }106.41 +#define MEM_WRITE_BYTE( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_byte(memtmp, val); }106.42 +#define MEM_WRITE_WORD( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_word(memtmp, val); }106.43 +#define MEM_WRITE_LONG( addr, val ) memtmp = mmu_vma_to_phys_write(addr); if( memtmp == MMU_VMA_ERROR ) { return TRUE; } else { sh4_write_long(memtmp, val); }106.45 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)106.47 @@ -223,6 +221,7 @@106.48 uint32_t tmp;106.49 float ftmp;106.50 double dtmp;106.51 + int64_t memtmp; // temporary holder for memory reads106.53 #define R0 sh4r.r[0]106.54 pc = sh4r.pc;106.55 @@ -236,41 +235,39 @@106.56 CHECKRALIGN16(pc);106.58 /* Read instruction */106.59 - uint32_t pageaddr = pc >> 12;106.60 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {106.61 - ir = sh4_icache[(pc&0xFFF)>>1];106.62 - } else {106.63 - sh4_icache = (uint16_t *)mem_get_page(pc);106.64 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {106.65 - /* If someone's actually been so daft as to try to execute out of an IO106.66 - * region, fallback on the full-blown memory read106.67 - */106.68 - sh4_icache = NULL;106.69 - ir = MEM_READ_WORD(pc);106.70 - } else {106.71 - sh4_icache_addr = pageaddr;106.72 - ir = sh4_icache[(pc&0xFFF)>>1];106.73 + if( !IS_IN_ICACHE(pc) ) {106.74 + if( !mmu_update_icache(pc) ) {106.75 + // Fault - look for the fault handler106.76 + if( !mmu_update_icache(sh4r.pc) ) {106.77 + // double fault - halt106.78 + ERROR( "Double fault - halting" );106.79 + dreamcast_stop();106.80 + return FALSE;106.81 + }106.82 }106.83 + pc = sh4r.pc;106.84 }106.85 + assert( IS_IN_ICACHE(pc) );106.86 + ir = *(uint16_t *)GET_ICACHE_PTR(sh4r.pc);106.87 %%106.88 AND Rm, Rn {: sh4r.r[Rn] &= sh4r.r[Rm]; :}106.89 AND #imm, R0 {: R0 &= imm; :}106.90 -AND.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) ); :}106.91 + AND.B #imm, @(R0, GBR) {: MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & tmp ); :}106.92 NOT Rm, Rn {: sh4r.r[Rn] = ~sh4r.r[Rm]; :}106.93 OR Rm, Rn {: sh4r.r[Rn] |= sh4r.r[Rm]; :}106.94 OR #imm, R0 {: R0 |= imm; :}106.95 -OR.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) ); :}106.96 + OR.B #imm, @(R0, GBR) {: MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | tmp ); :}106.97 TAS.B @Rn {:106.98 - tmp = MEM_READ_BYTE( sh4r.r[Rn] );106.99 + MEM_READ_BYTE( sh4r.r[Rn], tmp );106.100 sh4r.t = ( tmp == 0 ? 1 : 0 );106.101 MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );106.102 :}106.103 TST Rm, Rn {: sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1); :}106.104 TST #imm, R0 {: sh4r.t = (R0 & imm ? 0 : 1); :}106.105 -TST.B #imm, @(R0, GBR) {: sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 ); :}106.106 + TST.B #imm, @(R0, GBR) {: MEM_READ_BYTE(R0+sh4r.gbr, tmp); sh4r.t = ( tmp & imm ? 0 : 1 ); :}106.107 XOR Rm, Rn {: sh4r.r[Rn] ^= sh4r.r[Rm]; :}106.108 XOR #imm, R0 {: R0 ^= imm; :}106.109 -XOR.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) ); :}106.110 + XOR.B #imm, @(R0, GBR) {: MEM_READ_BYTE(R0+sh4r.gbr, tmp); MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ tmp ); :}106.111 XTRCT Rm, Rn {: sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16); :}106.113 ROTL Rn {:106.114 @@ -365,12 +362,12 @@106.115 CHECKWALIGN32( R0 + sh4r.r[Rn] );106.116 MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );106.117 :}106.118 -MOV.B @(R0, Rm), Rn {: sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] ); :}106.119 +MOV.B @(R0, Rm), Rn {: MEM_READ_BYTE( R0 + sh4r.r[Rm], sh4r.r[Rn] ); :}106.120 MOV.W @(R0, Rm), Rn {: CHECKRALIGN16( R0 + sh4r.r[Rm] );106.121 - sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );106.122 + MEM_READ_WORD( R0 + sh4r.r[Rm], sh4r.r[Rn] );106.123 :}106.124 MOV.L @(R0, Rm), Rn {: CHECKRALIGN32( R0 + sh4r.r[Rm] );106.125 - sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );106.126 + MEM_READ_LONG( R0 + sh4r.r[Rm], sh4r.r[Rn] );106.127 :}106.128 MOV.L Rm, @(disp, Rn) {:106.129 tmp = sh4r.r[Rn] + disp;106.130 @@ -386,19 +383,19 @@106.131 MOV.L @(disp, Rm), Rn {:106.132 tmp = sh4r.r[Rm] + disp;106.133 CHECKRALIGN32( tmp );106.134 - sh4r.r[Rn] = MEM_READ_LONG( tmp );106.135 + MEM_READ_LONG( tmp, sh4r.r[Rn] );106.136 :}106.137 -MOV.B @Rm, Rn {: sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); :}106.138 -MOV.W @Rm, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); :}106.139 -MOV.L @Rm, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); :}106.140 +MOV.B @Rm, Rn {: MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] ); :}106.141 + MOV.W @Rm, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] ); :}106.142 + MOV.L @Rm, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] ); :}106.143 MOV Rm, Rn {: sh4r.r[Rn] = sh4r.r[Rm]; :}106.144 -MOV.B @Rm+, Rn {: sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++; :}106.145 -MOV.W @Rm+, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2; :}106.146 -MOV.L @Rm+, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4; :}106.147 + MOV.B @Rm+, Rn {: MEM_READ_BYTE( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] ++; :}106.148 + MOV.W @Rm+, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); MEM_READ_WORD( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 2; :}106.149 + MOV.L @Rm+, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); MEM_READ_LONG( sh4r.r[Rm], sh4r.r[Rn] ); sh4r.r[Rm] += 4; :}106.150 MOV.L @(disp, PC), Rn {:106.151 CHECKSLOTILLEGAL();106.152 tmp = (pc&0xFFFFFFFC) + disp + 4;106.153 - sh4r.r[Rn] = MEM_READ_LONG( tmp );106.154 + MEM_READ_LONG( tmp, sh4r.r[Rn] );106.155 :}106.156 MOV.B R0, @(disp, GBR) {: MEM_WRITE_BYTE( sh4r.gbr + disp, R0 ); :}106.157 MOV.W R0, @(disp, GBR) {:106.158 @@ -411,16 +408,16 @@106.159 CHECKWALIGN32( tmp );106.160 MEM_WRITE_LONG( tmp, R0 );106.161 :}106.162 -MOV.B @(disp, GBR), R0 {: R0 = MEM_READ_BYTE( sh4r.gbr + disp ); :}106.163 + MOV.B @(disp, GBR), R0 {: MEM_READ_BYTE( sh4r.gbr + disp, R0 ); :}106.164 MOV.W @(disp, GBR), R0 {:106.165 tmp = sh4r.gbr + disp;106.166 CHECKRALIGN16( tmp );106.167 - R0 = MEM_READ_WORD( tmp );106.168 + MEM_READ_WORD( tmp, R0 );106.169 :}106.170 MOV.L @(disp, GBR), R0 {:106.171 tmp = sh4r.gbr + disp;106.172 CHECKRALIGN32( tmp );106.173 - R0 = MEM_READ_LONG( tmp );106.174 + MEM_READ_LONG( tmp, R0 );106.175 :}106.176 MOV.B R0, @(disp, Rn) {: MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 ); :}106.177 MOV.W R0, @(disp, Rn) {:106.178 @@ -428,16 +425,16 @@106.179 CHECKWALIGN16( tmp );106.180 MEM_WRITE_WORD( tmp, R0 );106.181 :}106.182 -MOV.B @(disp, Rm), R0 {: R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp ); :}106.183 + MOV.B @(disp, Rm), R0 {: MEM_READ_BYTE( sh4r.r[Rm] + disp, R0 ); :}106.184 MOV.W @(disp, Rm), R0 {:106.185 tmp = sh4r.r[Rm] + disp;106.186 CHECKRALIGN16( tmp );106.187 - R0 = MEM_READ_WORD( tmp );106.188 + MEM_READ_WORD( tmp, R0 );106.189 :}106.190 MOV.W @(disp, PC), Rn {:106.191 CHECKSLOTILLEGAL();106.192 tmp = pc + 4 + disp;106.193 - sh4r.r[Rn] = MEM_READ_WORD( tmp );106.194 + MEM_READ_WORD( tmp, sh4r.r[Rn] );106.195 :}106.196 MOVA @(disp, PC), R0 {:106.197 CHECKSLOTILLEGAL();106.198 @@ -506,9 +503,11 @@106.199 MAC.W @Rm+, @Rn+ {:106.200 CHECKRALIGN16( sh4r.r[Rn] );106.201 CHECKRALIGN16( sh4r.r[Rm] );106.202 - int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));106.203 + MEM_READ_WORD(sh4r.r[Rn], tmp);106.204 + int32_t stmp = SIGNEXT16(tmp);106.205 sh4r.r[Rn] += 2;106.206 - stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));106.207 + MEM_READ_WORD(sh4r.r[Rm], tmp);106.208 + stmp = stmp * SIGNEXT16(tmp);106.209 sh4r.r[Rm] += 2;106.210 if( sh4r.s ) {106.211 int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;106.212 @@ -527,9 +526,11 @@106.213 MAC.L @Rm+, @Rn+ {:106.214 CHECKRALIGN32( sh4r.r[Rm] );106.215 CHECKRALIGN32( sh4r.r[Rn] );106.216 - int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));106.217 + MEM_READ_LONG(sh4r.r[Rn], tmp);106.218 + int64_t tmpl = SIGNEXT32(tmp);106.219 sh4r.r[Rn] += 4;106.220 - tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;106.221 + MEM_READ_LONG(sh4r.r[Rm], tmp);106.222 + tmpl = tmpl * SIGNEXT32(tmp) + sh4r.mac;106.223 sh4r.r[Rm] += 4;106.224 if( sh4r.s ) {106.225 /* 48-bit Saturation. Yuch */106.226 @@ -640,9 +641,9 @@106.227 :}106.228 TRAPA #imm {:106.229 CHECKSLOTILLEGAL();106.230 - MMIO_WRITE( MMU, TRA, imm<<2 );106.231 sh4r.pc += 2;106.232 - sh4_raise_exception( EXC_TRAP );106.233 + sh4_raise_trap( imm );106.234 + return TRUE;106.235 :}106.236 RTS {:106.237 CHECKSLOTILLEGAL();106.238 @@ -703,15 +704,17 @@106.239 :}106.240 LDS.L @Rm+, MACH {:106.241 CHECKRALIGN32( sh4r.r[Rm] );106.242 + MEM_READ_LONG(sh4r.r[Rm], tmp);106.243 sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |106.244 - (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);106.245 + (((uint64_t)tmp)<<32);106.246 sh4r.r[Rm] += 4;106.247 :}106.248 LDC.L @Rm+, SR {:106.249 CHECKSLOTILLEGAL();106.250 CHECKPRIV();106.251 CHECKWALIGN32( sh4r.r[Rm] );106.252 - sh4_write_sr( MEM_READ_LONG(sh4r.r[Rm]) );106.253 + MEM_READ_LONG(sh4r.r[Rm], tmp);106.254 + sh4_write_sr( tmp );106.255 sh4r.r[Rm] +=4;106.256 :}106.257 LDS Rm, MACH {:106.258 @@ -730,7 +733,7 @@106.259 LDC.L @Rm+, SGR {:106.260 CHECKPRIV();106.261 CHECKRALIGN32( sh4r.r[Rm] );106.262 - sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);106.263 + MEM_READ_LONG(sh4r.r[Rm], sh4r.sgr);106.264 sh4r.r[Rm] +=4;106.265 :}106.266 STS MACL, Rn {: sh4r.r[Rn] = (uint32_t)sh4r.mac; :}106.267 @@ -746,13 +749,14 @@106.268 :}106.269 LDS.L @Rm+, MACL {:106.270 CHECKRALIGN32( sh4r.r[Rm] );106.271 + MEM_READ_LONG(sh4r.r[Rm], tmp);106.272 sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |106.273 - (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));106.274 + (uint64_t)((uint32_t)tmp);106.275 sh4r.r[Rm] += 4;106.276 :}106.277 LDC.L @Rm+, GBR {:106.278 CHECKRALIGN32( sh4r.r[Rm] );106.279 - sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);106.280 + MEM_READ_LONG(sh4r.r[Rm], sh4r.gbr);106.281 sh4r.r[Rm] +=4;106.282 :}106.283 LDS Rm, MACL {:106.284 @@ -774,13 +778,13 @@106.285 :}106.286 LDS.L @Rm+, PR {:106.287 CHECKRALIGN32( sh4r.r[Rm] );106.288 - sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );106.289 + MEM_READ_LONG( sh4r.r[Rm], sh4r.pr );106.290 sh4r.r[Rm] += 4;106.291 :}106.292 LDC.L @Rm+, VBR {:106.293 CHECKPRIV();106.294 CHECKRALIGN32( sh4r.r[Rm] );106.295 - sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);106.296 + MEM_READ_LONG(sh4r.r[Rm], sh4r.vbr);106.297 sh4r.r[Rm] +=4;106.298 :}106.299 LDS Rm, PR {: sh4r.pr = sh4r.r[Rm]; :}106.300 @@ -807,7 +811,7 @@106.301 LDC.L @Rm+, SSR {:106.302 CHECKPRIV();106.303 CHECKRALIGN32( sh4r.r[Rm] );106.304 - sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);106.305 + MEM_READ_LONG(sh4r.r[Rm], sh4r.ssr);106.306 sh4r.r[Rm] +=4;106.307 :}106.308 LDC Rm, SSR {:106.309 @@ -823,7 +827,7 @@106.310 LDC.L @Rm+, SPC {:106.311 CHECKPRIV();106.312 CHECKRALIGN32( sh4r.r[Rm] );106.313 - sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);106.314 + MEM_READ_LONG(sh4r.r[Rm], sh4r.spc);106.315 sh4r.r[Rm] +=4;106.316 :}106.317 LDC Rm, SPC {:106.318 @@ -838,7 +842,7 @@106.319 :}106.320 LDS.L @Rm+, FPUL {:106.321 CHECKRALIGN32( sh4r.r[Rm] );106.322 - sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);106.323 + MEM_READ_LONG(sh4r.r[Rm], sh4r.fpul);106.324 sh4r.r[Rm] +=4;106.325 :}106.326 LDS Rm, FPUL {: sh4r.fpul = sh4r.r[Rm]; :}106.327 @@ -850,7 +854,7 @@106.328 :}106.329 LDS.L @Rm+, FPSCR {:106.330 CHECKRALIGN32( sh4r.r[Rm] );106.331 - sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);106.332 + MEM_READ_LONG(sh4r.r[Rm], sh4r.fpscr);106.333 sh4r.r[Rm] +=4;106.334 sh4r.fr_bank = &sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][0];106.335 :}106.336 @@ -868,7 +872,7 @@106.337 LDC.L @Rm+, DBR {:106.338 CHECKPRIV();106.339 CHECKRALIGN32( sh4r.r[Rm] );106.340 - sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);106.341 + MEM_READ_LONG(sh4r.r[Rm], sh4r.dbr);106.342 sh4r.r[Rm] +=4;106.343 :}106.344 LDC Rm, DBR {:106.345 @@ -884,7 +888,7 @@106.346 LDC.L @Rm+, Rn_BANK {:106.347 CHECKPRIV();106.348 CHECKRALIGN32( sh4r.r[Rm] );106.349 - sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );106.350 + MEM_READ_LONG( sh4r.r[Rm], sh4r.r_bank[Rn_BANK] );106.351 sh4r.r[Rm] += 4;106.352 :}106.353 LDC Rm, Rn_BANK {:
107.1 --- a/src/sh4/sh4dasm.c Thu Dec 20 09:56:07 2007 +0000107.2 +++ b/src/sh4/sh4dasm.c Tue Jan 15 20:50:23 2008 +0000107.3 @@ -1,5 +1,5 @@107.4 /**107.5 - * $Id: sh4dasm.c,v 1.13 2007-11-07 11:46:58 nkeynes Exp $107.6 + * $Id$107.7 *107.8 * SH4 CPU definition and disassembly functions107.9 *107.10 @@ -1550,19 +1550,16 @@107.11 }107.14 -void sh4_disasm_region( const gchar *filename, int from, int to )107.15 +void sh4_disasm_region( FILE *f, int from, int to )107.16 {107.17 int pc;107.18 char buf[80];107.19 char opcode[16];107.20 - FILE *f;107.22 - f = fopen( filename, "w" );107.23 for( pc = from; pc < to; pc+=2 ) {107.24 buf[0] = '\0';107.25 sh4_disasm_instruction( pc,107.26 buf, sizeof(buf), opcode );107.27 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );107.28 }107.29 - fclose(f);107.30 }
108.1 --- a/src/sh4/sh4dasm.h Thu Dec 20 09:56:07 2007 +0000108.2 +++ b/src/sh4/sh4dasm.h Tue Jan 15 20:50:23 2008 +0000108.3 @@ -1,5 +1,5 @@108.4 /**108.5 - * $Id: sh4dasm.h,v 1.6 2006-01-01 08:08:40 nkeynes Exp $108.6 + * $Id$108.7 *108.8 * SH4 CPU definition and disassembly function declarations108.9 *108.10 @@ -28,7 +28,7 @@108.11 #include <stdio.h>108.13 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char * );108.14 -void sh4_disasm_region( const gchar *filename, int from, int to );108.15 +void sh4_disasm_region( FILE *f, int from, int to );108.17 extern const struct cpu_desc_struct sh4_cpu_desc;
109.1 --- a/src/sh4/sh4dasm.in Thu Dec 20 09:56:07 2007 +0000109.2 +++ b/src/sh4/sh4dasm.in Tue Jan 15 20:50:23 2008 +0000109.3 @@ -1,5 +1,5 @@109.4 /**109.5 - * $Id: sh4dasm.in,v 1.3 2007-11-07 11:46:58 nkeynes Exp $109.6 + * $Id$109.7 *109.8 * SH4 CPU definition and disassembly functions109.9 *109.10 @@ -285,19 +285,16 @@109.11 }109.14 -void sh4_disasm_region( const gchar *filename, int from, int to )109.15 +void sh4_disasm_region( FILE *f, int from, int to )109.16 {109.17 int pc;109.18 char buf[80];109.19 char opcode[16];109.20 - FILE *f;109.22 - f = fopen( filename, "w" );109.23 for( pc = from; pc < to; pc+=2 ) {109.24 buf[0] = '\0';109.25 sh4_disasm_instruction( pc,109.26 buf, sizeof(buf), opcode );109.27 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );109.28 }109.29 - fclose(f);109.30 }
110.1 --- a/src/sh4/sh4mem.c Thu Dec 20 09:56:07 2007 +0000110.2 +++ b/src/sh4/sh4mem.c Tue Jan 15 20:50:23 2008 +0000110.3 @@ -1,5 +1,5 @@110.4 /**110.5 - * $Id: sh4mem.c,v 1.31 2007-11-08 12:01:57 nkeynes Exp $110.6 + * $Id$110.7 * sh4mem.c is responsible for the SH4's access to memory (including memory110.8 * mapped I/O), using the page maps created in mem.c110.9 *110.10 @@ -17,7 +17,6 @@110.11 */110.13 #define MODULE sh4_module110.14 -#define ENABLE_TRACE_IO 1110.16 #include <string.h>110.17 #include <zlib.h>110.18 @@ -68,7 +67,6 @@110.20 extern struct mem_region mem_rgn[];110.21 extern struct mmio_region *P4_io[];110.22 -sh4ptr_t sh4_main_ram;110.24 int32_t sh4_read_p4( sh4addr_t addr )110.25 {110.26 @@ -163,9 +161,9 @@110.27 CHECK_READ_WATCH(addr,4);110.29 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */110.30 - return sh4_read_p4( addr );110.31 + return ZEROEXT32(sh4_read_p4( addr ));110.32 } else if( (addr&0x1C000000) == 0x0C000000 ) {110.33 - return *(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF));110.34 + return ZEROEXT32(*(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));110.35 } else if( (addr&0x1F800000) == 0x04000000 ) {110.36 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);110.37 pvr2_render_buffer_invalidate(addr, FALSE);110.38 @@ -182,9 +180,9 @@110.39 }110.40 val = io_rgn[(uintptr_t)page]->io_read(addr&0xFFF);110.41 TRACE_IO( "Long read %08X <= %08X", page, (addr&0xFFF), val, addr );110.42 - return val;110.43 + return ZEROEXT32(val);110.44 } else {110.45 - return *(int32_t *)(page+(addr&0xFFF));110.46 + return ZEROEXT32(*(int32_t *)(page+(addr&0xFFF)));110.47 }110.48 }110.50 @@ -195,9 +193,9 @@110.51 CHECK_READ_WATCH(addr,2);110.53 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */110.54 - return SIGNEXT16(sh4_read_p4( addr ));110.55 + return ZEROEXT32(SIGNEXT16(sh4_read_p4( addr )));110.56 } else if( (addr&0x1C000000) == 0x0C000000 ) {110.57 - return SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF)));110.58 + return ZEROEXT32(SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));110.59 } else if( (addr&0x1F800000) == 0x04000000 ) {110.60 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);110.61 pvr2_render_buffer_invalidate(addr, FALSE);110.62 @@ -214,9 +212,9 @@110.63 }110.64 val = SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));110.65 TRACE_IO( "Word read %04X <= %08X", page, (addr&0xFFF), val&0xFFFF, addr );110.66 - return val;110.67 + return ZEROEXT32(val);110.68 } else {110.69 - return SIGNEXT16(*(int16_t *)(page+(addr&0xFFF)));110.70 + return ZEROEXT32(SIGNEXT16(*(int16_t *)(page+(addr&0xFFF))));110.71 }110.72 }110.74 @@ -227,9 +225,9 @@110.75 CHECK_READ_WATCH(addr,1);110.77 if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */110.78 - return SIGNEXT8(sh4_read_p4( addr ));110.79 + return ZEROEXT32(SIGNEXT8(sh4_read_p4( addr )));110.80 } else if( (addr&0x1C000000) == 0x0C000000 ) {110.81 - return SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF)));110.82 + return ZEROEXT32(SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF))));110.83 } else if( (addr&0x1F800000) == 0x04000000 ) {110.84 addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);110.85 pvr2_render_buffer_invalidate(addr, FALSE);110.86 @@ -247,9 +245,9 @@110.87 }110.88 val = SIGNEXT8(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));110.89 TRACE_IO( "Byte read %02X <= %08X", page, (addr&0xFFF), val&0xFF, addr );110.90 - return val;110.91 + return ZEROEXT32(val);110.92 } else {110.93 - return SIGNEXT8(*(int8_t *)(page+(addr&0xFFF)));110.94 + return ZEROEXT32(SIGNEXT8(*(int8_t *)(page+(addr&0xFFF))));110.95 }110.96 }110.98 @@ -351,7 +349,7 @@110.99 void sh4_write_byte( sh4addr_t addr, uint32_t val )110.100 {110.101 sh4ptr_t page;110.102 -110.103 +110.104 CHECK_WRITE_WATCH(addr,1,val);110.106 if( addr >= 0xE0000000 ) {110.107 @@ -425,12 +423,19 @@110.108 }110.109 }110.111 -void sh4_flush_store_queue( sh4addr_t addr )110.112 +sh4ptr_t sh4_get_region_by_vma( sh4addr_t vma )110.113 {110.114 - /* Store queue operation */110.115 - int queue = (addr&0x20)>>2;110.116 - sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];110.117 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;110.118 - uint32_t target = (addr&0x03FFFFE0) | hi;110.119 - mem_copy_to_sh4( target, src, 32 );110.120 + uint64_t ppa = mmu_vma_to_phys_read(vma);110.121 + if( ppa>>32 ) {110.122 + return 0;110.123 + }110.124 +110.125 + sh4addr_t addr = (sh4addr_t)ppa;110.126 + sh4ptr_t page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];110.127 + if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */110.128 + return NULL;110.129 + } else {110.130 + return page+(addr&0xFFF);110.131 + }110.132 }110.133 +
111.1 --- a/src/sh4/sh4mmio.c Thu Dec 20 09:56:07 2007 +0000111.2 +++ b/src/sh4/sh4mmio.c Tue Jan 15 20:50:23 2008 +0000111.3 @@ -1,5 +1,5 @@111.4 /**111.5 - * $Id: sh4mmio.c,v 1.15 2007-11-08 11:54:16 nkeynes Exp $111.6 + * $Id$111.7 *111.8 * Miscellaneous and not-really-implemented SH4 peripheral modules. Also111.9 * responsible for including the IMPL side of the SH4 MMIO pages.
112.1 --- a/src/sh4/sh4mmio.h Thu Dec 20 09:56:07 2007 +0000112.2 +++ b/src/sh4/sh4mmio.h Tue Jan 15 20:50:23 2008 +0000112.3 @@ -1,5 +1,5 @@112.4 /**112.5 - * $Id: sh4mmio.h,v 1.4 2005-12-25 05:57:00 nkeynes Exp $112.6 + * $Id$112.7 *112.8 * MMIO region and supporting function declarations. Private to the sh4112.9 * module.
113.1 --- a/src/sh4/sh4stat.c Thu Dec 20 09:56:07 2007 +0000113.2 +++ b/src/sh4/sh4stat.c Tue Jan 15 20:50:23 2008 +0000113.3 @@ -1,5 +1,5 @@113.4 /**113.5 - * $Id: sh4stat.c,v 1.2 2007-11-08 11:37:49 nkeynes Exp $113.6 + * $Id$113.7 *113.8 * Support module for collecting instruction stats113.9 *
114.1 --- a/src/sh4/sh4stat.h Thu Dec 20 09:56:07 2007 +0000114.2 +++ b/src/sh4/sh4stat.h Tue Jan 15 20:50:23 2008 +0000114.3 @@ -1,5 +1,5 @@114.4 /**114.5 - * $Id: sh4stat.h,v 1.2 2007-10-06 09:03:24 nkeynes Exp $114.6 + * $Id$114.7 *114.8 * Support module for collecting instruction stats114.9 *
115.1 --- a/src/sh4/sh4stat.in Thu Dec 20 09:56:07 2007 +0000115.2 +++ b/src/sh4/sh4stat.in Tue Jan 15 20:50:23 2008 +0000115.3 @@ -1,5 +1,5 @@115.4 /**115.5 - * $Id: sh4stat.in,v 1.2 2007-11-08 11:37:49 nkeynes Exp $115.6 + * $Id$115.7 *115.8 * Support module for collecting instruction stats115.9 *
116.1 --- a/src/sh4/sh4trans.c Thu Dec 20 09:56:07 2007 +0000116.2 +++ b/src/sh4/sh4trans.c Tue Jan 15 20:50:23 2008 +0000116.3 @@ -1,5 +1,5 @@116.4 /**116.5 - * $Id: sh4trans.c,v 1.8 2007-10-08 12:06:01 nkeynes Exp $116.6 + * $Id$116.7 *116.8 * SH4 translation core module. This part handles the non-target-specific116.9 * section of the translation.116.10 @@ -17,12 +17,23 @@116.11 * GNU General Public License for more details.116.12 */116.13 #include <assert.h>116.14 +#include <setjmp.h>116.15 #include "eventq.h"116.16 #include "syscall.h"116.17 +#include "clock.h"116.18 #include "sh4/sh4core.h"116.19 #include "sh4/sh4trans.h"116.20 #include "sh4/xltcache.h"116.22 +116.23 +static jmp_buf xlat_jmp_buf;116.24 +static gboolean xlat_running = FALSE;116.25 +116.26 +gboolean sh4_xlat_is_running()116.27 +{116.28 + return xlat_running;116.29 +}116.30 +116.31 /**116.32 * Execute a timeslice using translated code only (ie translate/execute loop)116.33 * Note this version does not support breakpoints116.34 @@ -38,6 +49,23 @@116.35 }116.36 }116.38 + switch( setjmp(xlat_jmp_buf) ) {116.39 + case XLAT_EXIT_BREAKPOINT:116.40 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );116.41 + /* fallthrough */116.42 + case XLAT_EXIT_HALT:116.43 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {116.44 + TMU_run_slice( sh4r.slice_cycle );116.45 + SCIF_run_slice( sh4r.slice_cycle );116.46 + dreamcast_stop();116.47 + return sh4r.slice_cycle;116.48 + }116.49 + case XLAT_EXIT_SYSRESET:116.50 + dreamcast_reset();116.51 + break;116.52 + }116.53 +116.54 + xlat_running = TRUE;116.55 void * (*code)() = NULL;116.56 while( sh4r.slice_cycle < nanosecs ) {116.57 if( sh4r.event_pending <= sh4r.slice_cycle ) {116.58 @@ -58,7 +86,7 @@116.59 sh4r.pc = sh4r.pr;116.60 }116.62 - code = xlat_get_code(sh4r.pc);116.63 + code = xlat_get_code_by_vma( sh4r.pc );116.64 if( code == NULL ) {116.65 code = sh4_translate_basic_block( sh4r.pc );116.66 }116.67 @@ -66,6 +94,8 @@116.68 code = code();116.69 }116.71 + xlat_running = FALSE;116.72 +116.73 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {116.74 TMU_run_slice( nanosecs );116.75 SCIF_run_slice( nanosecs );116.76 @@ -74,6 +104,8 @@116.77 }116.79 uint8_t *xlat_output;116.80 +struct xlat_recovery_record xlat_recovery[MAX_RECOVERY_SIZE];116.81 +uint32_t xlat_recovery_posn;116.83 /**116.84 * Translate a linear basic block, ie all instructions from the start address116.85 @@ -86,13 +118,21 @@116.86 {116.87 sh4addr_t pc = start;116.88 sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000;116.89 - int done;116.90 + int done, i;116.91 xlat_cache_block_t block = xlat_start_block( start );116.92 xlat_output = (uint8_t *)block->code;116.93 + xlat_recovery_posn = 0;116.94 uint8_t *eob = xlat_output + block->size;116.95 sh4_translate_begin_block(pc);116.97 do {116.98 + /* check for breakpoints at this pc */116.99 + for( i=0; i<sh4_breakpoint_count; i++ ) {116.100 + if( sh4_breakpoints[i].address == pc ) {116.101 + sh4_translate_emit_breakpoint(pc);116.102 + break;116.103 + }116.104 + }116.105 if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {116.106 uint8_t *oldstart = block->code;116.107 block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE );116.108 @@ -113,32 +153,123 @@116.109 xlat_output = block->code + (xlat_output - oldstart);116.110 }116.111 sh4_translate_end_block(pc);116.112 - xlat_commit_block( xlat_output - block->code, pc-start );116.113 +116.114 + /* Write the recovery records onto the end of the code block */116.115 + uint32_t recovery_size = sizeof(struct xlat_recovery_record)*xlat_recovery_posn;116.116 + uint32_t finalsize = xlat_output - block->code + recovery_size;116.117 + if( finalsize > block->size ) {116.118 + uint8_t *oldstart = block->code;116.119 + block = xlat_extend_block( finalsize );116.120 + xlat_output = block->code + (xlat_output - oldstart);116.121 + }116.122 + memcpy( xlat_output, xlat_recovery, recovery_size);116.123 + block->recover_table = (xlat_recovery_record_t)xlat_output;116.124 + block->recover_table_size = xlat_recovery_posn;116.125 + xlat_commit_block( finalsize, pc-start );116.126 return block->code;116.127 }116.129 /**116.130 - * Translate a linear basic block to a temporary buffer, execute it, and return116.131 - * the result of the execution. The translation is discarded.116.132 + * "Execute" the supplied recovery record. Currently this only updates116.133 + * sh4r.pc and sh4r.slice_cycle according to the currently executing116.134 + * instruction. In future this may be more sophisticated (ie will116.135 + * call into generated code).116.136 */116.137 -void *sh4_translate_and_run( sh4addr_t start )116.138 +void sh4_translate_run_recovery( xlat_recovery_record_t recovery )116.139 {116.140 - unsigned char buf[65536];116.141 + sh4r.slice_cycle += (recovery->sh4_icount * sh4_cpu_period);116.142 + sh4r.pc += (recovery->sh4_icount<<1);116.143 +}116.145 - sh4addr_t pc = start;116.146 - int done;116.147 - xlat_output = buf;116.148 - uint8_t *eob = xlat_output + sizeof(buf);116.149 +void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk )116.150 +{116.151 + void *pc = xlat_get_native_pc();116.153 - sh4_translate_begin_block(pc);116.154 + assert( pc != NULL );116.155 + void *code = xlat_get_code( sh4r.pc );116.156 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);116.157 + if( recover != NULL ) {116.158 + // Can be null if there is no recovery necessary116.159 + sh4_translate_run_recovery(recover);116.160 + }116.161 + if( thunk != NULL ) {116.162 + thunk();116.163 + }116.164 + // finally longjmp back into sh4_xlat_run_slice116.165 + xlat_running = FALSE;116.166 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);116.167 +}116.169 - while( (done = sh4_translate_instruction( pc )) == 0 ) {116.170 - assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );116.171 - pc += 2;116.172 +void sh4_translate_exit( int exit_code )116.173 +{116.174 + void *pc = xlat_get_native_pc();116.175 + if( pc != NULL ) {116.176 + // could be null if we're not actually running inside the translator116.177 + void *code = xlat_get_code( sh4r.pc );116.178 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);116.179 + if( recover != NULL ) {116.180 + // Can be null if there is no recovery necessary116.181 + sh4_translate_run_recovery(recover);116.182 + }116.183 }116.184 - pc+=2;116.185 - sh4_translate_end_block(pc);116.186 + // finally longjmp back into sh4_xlat_run_slice116.187 + xlat_running = FALSE;116.188 + longjmp(xlat_jmp_buf, exit_code);116.189 +}116.191 - void * (*code)() = (void *)buf;116.192 - return code();116.193 +/**116.194 + * Exit the current block at the end of the current instruction, flush the116.195 + * translation cache (completely) and return control to sh4_xlat_run_slice.116.196 + *116.197 + * As a special case, if the current instruction is actually the last116.198 + * instruction in the block (ie it's in a delay slot), this function116.199 + * returns to allow normal completion of the translation block. Otherwise116.200 + * this function never returns.116.201 + *116.202 + * Must only be invoked (indirectly) from within translated code.116.203 + */116.204 +void sh4_translate_flush_cache()116.205 +{116.206 + void *pc = xlat_get_native_pc();116.207 + assert( pc != NULL );116.208 +116.209 + void *code = xlat_get_code( sh4r.pc );116.210 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);116.211 + if( recover != NULL ) {116.212 + // Can be null if there is no recovery necessary116.213 + sh4_translate_run_recovery(recover);116.214 + xlat_flush_cache();116.215 + xlat_running = FALSE;116.216 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);116.217 + } else {116.218 + xlat_flush_cache();116.219 + return;116.220 + }116.221 }116.222 +116.223 +void *xlat_get_code_by_vma( sh4vma_t vma )116.224 +{116.225 + void *result = NULL;116.226 +116.227 + if( !IS_IN_ICACHE(vma) ) {116.228 + if( vma > 0xFFFFFF00 ) {116.229 + // lxdream hook116.230 + return NULL;116.231 + }116.232 + if( !mmu_update_icache(sh4r.pc) ) {116.233 + // fault - off to the fault handler116.234 + if( !mmu_update_icache(sh4r.pc) ) {116.235 + // double fault - halt116.236 + ERROR( "Double fault - halting" );116.237 + dreamcast_stop();116.238 + return NULL;116.239 + }116.240 + }116.241 + }116.242 + if( sh4_icache.page_vma != -1 ) {116.243 + result = xlat_get_code( GET_ICACHE_PHYS(vma) );116.244 + }116.245 +116.246 + return result;116.247 +}116.248 +
117.1 --- a/src/sh4/sh4trans.h Thu Dec 20 09:56:07 2007 +0000117.2 +++ b/src/sh4/sh4trans.h Tue Jan 15 20:50:23 2008 +0000117.3 @@ -1,5 +1,5 @@117.4 /**117.5 - * $Id: sh4trans.h,v 1.4 2007-09-29 11:06:40 nkeynes Exp $117.6 + * $Id$117.7 *117.8 * SH4->x86 translation module117.9 *117.10 @@ -16,6 +16,7 @@117.11 * GNU General Public License for more details.117.12 */117.14 +#include "sh4/xltcache.h"117.15 #include "dream.h"117.16 #include "mem.h"117.18 @@ -27,18 +28,53 @@117.19 * allows a little room117.20 */117.21 #define EPILOGUE_SIZE 128117.22 +117.23 +/** Maximum number of recovery records for a translated block (2048 based on117.24 + * 1 record per SH4 instruction in a 4K page).117.25 + */117.26 +#define MAX_RECOVERY_SIZE 2048117.27 +117.28 /**117.29 + * Translation flag - exit the current block but continue (eg exception handling)117.30 + */117.31 +#define XLAT_EXIT_CONTINUE 1117.33 +/**117.34 + * Translation flag - exit the current block and halt immediately (eg fatal error)117.35 + */117.36 +#define XLAT_EXIT_HALT 2117.37 +117.38 +/**117.39 + * Translation flag - exit the current block and halt immediately for a system117.40 + * breakpoint.117.41 + */117.42 +#define XLAT_EXIT_BREAKPOINT 3117.43 +117.44 +/**117.45 + * Translation flag - exit the current block and continue after performing a full117.46 + * system reset (dreamcast_reset())117.47 + */117.48 +#define XLAT_EXIT_SYSRESET 4117.49 +117.50 +/**117.51 */117.52 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );117.54 /**117.55 + * Return true if translated code is currently running117.56 + */117.57 +gboolean sh4_xlat_is_running();117.58 +117.59 +/**117.60 * Translate the specified block of code starting from the specified start117.61 * address until the first branch/jump instruction.117.62 */117.63 void *sh4_translate_basic_block( sh4addr_t start );117.65 +117.66 extern uint8_t *xlat_output;117.67 +extern struct xlat_recovery_record xlat_recovery[MAX_RECOVERY_SIZE];117.68 +extern uint32_t xlat_recovery_posn;117.70 /******************************************************************************117.71 * Code generation - these methods must be provided by the117.72 @@ -51,3 +87,28 @@117.73 void sh4_translate_begin_block( sh4addr_t pc );117.74 uint32_t sh4_translate_instruction( sh4addr_t pc );117.75 void sh4_translate_end_block( sh4addr_t pc );117.76 +117.77 +typedef void (*unwind_thunk_t)(void);117.78 +117.79 +/**117.80 + * From within the translator, (typically called from MMU exception handling routines)117.81 + * immediately exit the current translation block (performing cleanup as necessary) and117.82 + * return to sh4_xlat_run_slice(). Effectively a fast longjmp w/ xlat recovery.117.83 + *117.84 + * Note: The correct working of this method depends on the translator anticipating the117.85 + * exception and generating the appropriate recovery block(s) - currently this means117.86 + * that it should ONLY be called from within the context of a memory read or write.117.87 + *117.88 + * @param is_completion If TRUE, exit after completing the current instruction (effectively),117.89 + * otherwise abort the current instruction with no effect.117.90 + * @param thunk A function to execute after perform xlat recovery, but before returning117.91 + * to run_slice. If NULL, control returns directly.117.92 + * @return This method never returns.117.93 + */117.94 +void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk );117.95 +117.96 +/**117.97 + * From within the translator, immediately exit the current translation block with117.98 + * the specified exit code (one of the XLAT_EXIT_* values).117.99 + */117.100 +void sh4_translate_exit( int exit_code );
118.1 --- a/src/sh4/sh4x86.c Thu Dec 20 09:56:07 2007 +0000118.2 +++ b/src/sh4/sh4x86.c Tue Jan 15 20:50:23 2008 +0000118.3 @@ -1,5 +1,5 @@118.4 /**118.5 - * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $118.6 + * $Id$118.7 *118.8 * SH4 => x86 translation. This version does no real optimization, it just118.9 * outputs straight-line x86 code - it mainly exists to provide a baseline118.10 @@ -34,6 +34,14 @@118.12 #define DEFAULT_BACKPATCH_SIZE 4096118.14 +struct backpatch_record {118.15 + uint32_t *fixup_addr;118.16 + uint32_t fixup_icount;118.17 + uint32_t exc_code;118.18 +};118.19 +118.20 +#define MAX_RECOVERY_SIZE 2048118.21 +118.22 /**118.23 * Struct to manage internal translation state. This state is not saved -118.24 * it is only valid between calls to sh4_translate_begin_block() and118.25 @@ -48,10 +56,15 @@118.26 uint32_t stack_posn; /* Trace stack height for alignment purposes */118.27 int tstate;118.29 + /* mode flags */118.30 + gboolean tlb_on; /* True if tlb translation is active */118.31 +118.32 /* Allocated memory for the (block-wide) back-patch list */118.33 - uint32_t **backpatch_list;118.34 + struct backpatch_record *backpatch_list;118.35 uint32_t backpatch_posn;118.36 uint32_t backpatch_size;118.37 + struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];118.38 + uint32_t recovery_posn;118.39 };118.41 #define TSTATE_NONE -1118.42 @@ -75,14 +88,6 @@118.43 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \118.44 MARK_JMP(rel8, label)118.46 -118.47 -#define EXIT_DATA_ADDR_READ 0118.48 -#define EXIT_DATA_ADDR_WRITE 7118.49 -#define EXIT_ILLEGAL 14118.50 -#define EXIT_SLOT_ILLEGAL 21118.51 -#define EXIT_FPU_DISABLED 28118.52 -#define EXIT_SLOT_FPU_DISABLED 35118.53 -118.54 static struct sh4_x86_state sh4_x86;118.56 static uint32_t max_int = 0x7FFFFFFF;118.57 @@ -93,26 +98,32 @@118.58 void sh4_x86_init()118.59 {118.60 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);118.61 - sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);118.62 + sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);118.63 }118.66 -static void sh4_x86_add_backpatch( uint8_t *ptr )118.67 +static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )118.68 {118.69 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {118.70 sh4_x86.backpatch_size <<= 1;118.71 - sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );118.72 + sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,118.73 + sh4_x86.backpatch_size * sizeof(struct backpatch_record));118.74 assert( sh4_x86.backpatch_list != NULL );118.75 }118.76 - sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;118.77 + if( sh4_x86.in_delay_slot ) {118.78 + fixup_pc -= 2;118.79 + }118.80 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;118.81 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;118.82 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;118.83 + sh4_x86.backpatch_posn++;118.84 }118.86 -static void sh4_x86_do_backpatch( uint8_t *reloc_base )118.87 +void sh4_x86_add_recovery( uint32_t pc )118.88 {118.89 - unsigned int i;118.90 - for( i=0; i<sh4_x86.backpatch_posn; i++ ) {118.91 - *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);118.92 - }118.93 + xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;118.94 + xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;118.95 + xlat_recovery_posn++;118.96 }118.98 /**118.99 @@ -266,86 +277,46 @@118.100 }118.102 /* Exception checks - Note that all exception checks will clobber EAX */118.103 -#define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)118.105 #define check_priv( ) \118.106 if( !sh4_x86.priv_checked ) { \118.107 sh4_x86.priv_checked = TRUE;\118.108 - precheck();\118.109 load_spreg( R_EAX, R_SR );\118.110 AND_imm32_r32( SR_MD, R_EAX );\118.111 if( sh4_x86.in_delay_slot ) {\118.112 - JE_exit( EXIT_SLOT_ILLEGAL );\118.113 + JE_exc( EXC_SLOT_ILLEGAL );\118.114 } else {\118.115 - JE_exit( EXIT_ILLEGAL );\118.116 + JE_exc( EXC_ILLEGAL );\118.117 }\118.118 }\118.120 -118.121 -static void check_priv_no_precheck()118.122 -{118.123 - if( !sh4_x86.priv_checked ) {118.124 - sh4_x86.priv_checked = TRUE;118.125 - load_spreg( R_EAX, R_SR );118.126 - AND_imm32_r32( SR_MD, R_EAX );118.127 - if( sh4_x86.in_delay_slot ) {118.128 - JE_exit( EXIT_SLOT_ILLEGAL );118.129 - } else {118.130 - JE_exit( EXIT_ILLEGAL );118.131 - }118.132 - }118.133 -}118.134 -118.135 #define check_fpuen( ) \118.136 if( !sh4_x86.fpuen_checked ) {\118.137 sh4_x86.fpuen_checked = TRUE;\118.138 - precheck();\118.139 load_spreg( R_EAX, R_SR );\118.140 AND_imm32_r32( SR_FD, R_EAX );\118.141 if( sh4_x86.in_delay_slot ) {\118.142 - JNE_exit(EXIT_SLOT_FPU_DISABLED);\118.143 + JNE_exc(EXC_SLOT_FPU_DISABLED);\118.144 } else {\118.145 - JNE_exit(EXIT_FPU_DISABLED);\118.146 + JNE_exc(EXC_FPU_DISABLED);\118.147 }\118.148 }118.150 -static void check_fpuen_no_precheck()118.151 -{118.152 - if( !sh4_x86.fpuen_checked ) {118.153 - sh4_x86.fpuen_checked = TRUE;118.154 - load_spreg( R_EAX, R_SR );118.155 - AND_imm32_r32( SR_FD, R_EAX );118.156 - if( sh4_x86.in_delay_slot ) {118.157 - JNE_exit(EXIT_SLOT_FPU_DISABLED);118.158 - } else {118.159 - JNE_exit(EXIT_FPU_DISABLED);118.160 - }118.161 - }118.162 +#define check_ralign16( x86reg ) \118.163 + TEST_imm32_r32( 0x00000001, x86reg ); \118.164 + JNE_exc(EXC_DATA_ADDR_READ)118.166 -}118.167 +#define check_walign16( x86reg ) \118.168 + TEST_imm32_r32( 0x00000001, x86reg ); \118.169 + JNE_exc(EXC_DATA_ADDR_WRITE);118.171 -static void check_ralign16( int x86reg )118.172 -{118.173 - TEST_imm32_r32( 0x00000001, x86reg );118.174 - JNE_exit(EXIT_DATA_ADDR_READ);118.175 -}118.176 +#define check_ralign32( x86reg ) \118.177 + TEST_imm32_r32( 0x00000003, x86reg ); \118.178 + JNE_exc(EXC_DATA_ADDR_READ)118.180 -static void check_walign16( int x86reg )118.181 -{118.182 - TEST_imm32_r32( 0x00000001, x86reg );118.183 - JNE_exit(EXIT_DATA_ADDR_WRITE);118.184 -}118.185 -118.186 -static void check_ralign32( int x86reg )118.187 -{118.188 - TEST_imm32_r32( 0x00000003, x86reg );118.189 - JNE_exit(EXIT_DATA_ADDR_READ);118.190 -}118.191 -static void check_walign32( int x86reg )118.192 -{118.193 - TEST_imm32_r32( 0x00000003, x86reg );118.194 - JNE_exit(EXIT_DATA_ADDR_WRITE);118.195 -}118.196 +#define check_walign32( x86reg ) \118.197 + TEST_imm32_r32( 0x00000003, x86reg ); \118.198 + JNE_exc(EXC_DATA_ADDR_WRITE);118.200 #define UNDEF()118.201 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }118.202 @@ -356,10 +327,22 @@118.203 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)118.204 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)118.206 -#define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;118.207 +/**118.208 + * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned118.209 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.118.210 + */118.211 +#define MMU_TRANSLATE_READ( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }118.212 +/**118.213 + * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned118.214 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.118.215 + */118.216 +#define MMU_TRANSLATE_WRITE( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }118.218 -extern uint16_t *sh4_icache;118.219 -extern uint32_t sh4_icache_addr;118.220 +#define MEM_READ_SIZE (CALL_FUNC1_SIZE)118.221 +#define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)118.222 +#define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )118.223 +118.224 +#define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;118.226 /****** Import appropriate calling conventions ******/118.227 #if SH4_TRANSLATOR == TARGET_X86_64118.228 @@ -372,11 +355,18 @@118.229 #endif118.230 #endif118.232 +void sh4_translate_emit_breakpoint( sh4vma_t pc )118.233 +{118.234 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );118.235 + call_func1( sh4_translate_exit, R_EAX );118.236 +}118.237 +118.239 /**118.240 * Translate a single instruction. Delayed branches are handled specially118.241 * by translating both branch and delayed instruction as a single unit (as118.242 *118.243 + * The instruction MUST be in the icache (assert check)118.244 *118.245 * @return true if the instruction marks the end of a basic block118.246 * (eg a branch or118.247 @@ -384,24 +374,23 @@118.248 uint32_t sh4_translate_instruction( sh4addr_t pc )118.249 {118.250 uint32_t ir;118.251 - /* Read instruction */118.252 - uint32_t pageaddr = pc >> 12;118.253 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {118.254 - ir = sh4_icache[(pc&0xFFF)>>1];118.255 - } else {118.256 - sh4_icache = (uint16_t *)mem_get_page(pc);118.257 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {118.258 - /* If someone's actually been so daft as to try to execute out of an IO118.259 - * region, fallback on the full-blown memory read118.260 - */118.261 - sh4_icache = NULL;118.262 - ir = sh4_read_word(pc);118.263 - } else {118.264 - sh4_icache_addr = pageaddr;118.265 - ir = sh4_icache[(pc&0xFFF)>>1];118.266 - }118.267 + /* Read instruction from icache */118.268 + assert( IS_IN_ICACHE(pc) );118.269 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);118.270 +118.271 + /* PC is not in the current icache - this usually means we're running118.272 + * with MMU on, and we've gone past the end of the page. And since118.273 + * sh4_translate_block is pretty careful about this, it means we're118.274 + * almost certainly in a delay slot.118.275 + *118.276 + * Since we can't assume the page is present (and we can't fault it in118.277 + * at this point, inline a call to sh4_execute_instruction (with a few118.278 + * small repairs to cope with the different environment).118.279 + */118.280 +118.281 + if( !sh4_x86.in_delay_slot ) {118.282 + sh4_x86_add_recovery(pc);118.283 }118.284 -118.285 switch( (ir&0xF000) >> 12 ) {118.286 case 0x0:118.287 switch( ir&0xF ) {118.288 @@ -514,8 +503,10 @@118.289 MOV_r32_r32( R_EAX, R_ECX );118.290 AND_imm32_r32( 0xFC000000, R_EAX );118.291 CMP_imm32_r32( 0xE0000000, R_EAX );118.292 - JNE_rel8(CALL_FUNC1_SIZE, end);118.293 + JNE_rel8(8+CALL_FUNC1_SIZE, end);118.294 call_func1( sh4_flush_store_queue, R_ECX );118.295 + TEST_r32_r32( R_EAX, R_EAX );118.296 + JE_exc(-1);118.297 JMP_TARGET(end);118.298 sh4_x86.tstate = TSTATE_NONE;118.299 }118.300 @@ -538,11 +529,11 @@118.301 case 0xC:118.302 { /* MOVCA.L R0, @Rn */118.303 uint32_t Rn = ((ir>>8)&0xF);118.304 - load_reg( R_EAX, 0 );118.305 - load_reg( R_ECX, Rn );118.306 - precheck();118.307 - check_walign32( R_ECX );118.308 - MEM_WRITE_LONG( R_ECX, R_EAX );118.309 + load_reg( R_EAX, Rn );118.310 + check_walign32( R_EAX );118.311 + MMU_TRANSLATE_WRITE( R_EAX );118.312 + load_reg( R_EDX, 0 );118.313 + MEM_WRITE_LONG( R_EAX, R_EDX );118.314 sh4_x86.tstate = TSTATE_NONE;118.315 }118.316 break;118.317 @@ -556,9 +547,10 @@118.318 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.319 load_reg( R_EAX, 0 );118.320 load_reg( R_ECX, Rn );118.321 - ADD_r32_r32( R_EAX, R_ECX );118.322 - load_reg( R_EAX, Rm );118.323 - MEM_WRITE_BYTE( R_ECX, R_EAX );118.324 + ADD_r32_r32( R_ECX, R_EAX );118.325 + MMU_TRANSLATE_WRITE( R_EAX );118.326 + load_reg( R_EDX, Rm );118.327 + MEM_WRITE_BYTE( R_EAX, R_EDX );118.328 sh4_x86.tstate = TSTATE_NONE;118.329 }118.330 break;118.331 @@ -567,11 +559,11 @@118.332 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.333 load_reg( R_EAX, 0 );118.334 load_reg( R_ECX, Rn );118.335 - ADD_r32_r32( R_EAX, R_ECX );118.336 - precheck();118.337 - check_walign16( R_ECX );118.338 - load_reg( R_EAX, Rm );118.339 - MEM_WRITE_WORD( R_ECX, R_EAX );118.340 + ADD_r32_r32( R_ECX, R_EAX );118.341 + check_walign16( R_EAX );118.342 + MMU_TRANSLATE_WRITE( R_EAX );118.343 + load_reg( R_EDX, Rm );118.344 + MEM_WRITE_WORD( R_EAX, R_EDX );118.345 sh4_x86.tstate = TSTATE_NONE;118.346 }118.347 break;118.348 @@ -580,11 +572,11 @@118.349 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.350 load_reg( R_EAX, 0 );118.351 load_reg( R_ECX, Rn );118.352 - ADD_r32_r32( R_EAX, R_ECX );118.353 - precheck();118.354 - check_walign32( R_ECX );118.355 - load_reg( R_EAX, Rm );118.356 - MEM_WRITE_LONG( R_ECX, R_EAX );118.357 + ADD_r32_r32( R_ECX, R_EAX );118.358 + check_walign32( R_EAX );118.359 + MMU_TRANSLATE_WRITE( R_EAX );118.360 + load_reg( R_EDX, Rm );118.361 + MEM_WRITE_LONG( R_EAX, R_EDX );118.362 sh4_x86.tstate = TSTATE_NONE;118.363 }118.364 break;118.365 @@ -791,8 +783,9 @@118.366 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.367 load_reg( R_EAX, 0 );118.368 load_reg( R_ECX, Rm );118.369 - ADD_r32_r32( R_EAX, R_ECX );118.370 - MEM_READ_BYTE( R_ECX, R_EAX );118.371 + ADD_r32_r32( R_ECX, R_EAX );118.372 + MMU_TRANSLATE_READ( R_EAX )118.373 + MEM_READ_BYTE( R_EAX, R_EAX );118.374 store_reg( R_EAX, Rn );118.375 sh4_x86.tstate = TSTATE_NONE;118.376 }118.377 @@ -802,10 +795,10 @@118.378 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.379 load_reg( R_EAX, 0 );118.380 load_reg( R_ECX, Rm );118.381 - ADD_r32_r32( R_EAX, R_ECX );118.382 - precheck();118.383 - check_ralign16( R_ECX );118.384 - MEM_READ_WORD( R_ECX, R_EAX );118.385 + ADD_r32_r32( R_ECX, R_EAX );118.386 + check_ralign16( R_EAX );118.387 + MMU_TRANSLATE_READ( R_EAX );118.388 + MEM_READ_WORD( R_EAX, R_EAX );118.389 store_reg( R_EAX, Rn );118.390 sh4_x86.tstate = TSTATE_NONE;118.391 }118.392 @@ -815,10 +808,10 @@118.393 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.394 load_reg( R_EAX, 0 );118.395 load_reg( R_ECX, Rm );118.396 - ADD_r32_r32( R_EAX, R_ECX );118.397 - precheck();118.398 - check_ralign32( R_ECX );118.399 - MEM_READ_LONG( R_ECX, R_EAX );118.400 + ADD_r32_r32( R_ECX, R_EAX );118.401 + check_ralign32( R_EAX );118.402 + MMU_TRANSLATE_READ( R_EAX );118.403 + MEM_READ_LONG( R_EAX, R_EAX );118.404 store_reg( R_EAX, Rn );118.405 sh4_x86.tstate = TSTATE_NONE;118.406 }118.407 @@ -826,18 +819,34 @@118.408 case 0xF:118.409 { /* MAC.L @Rm+, @Rn+ */118.410 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.411 - load_reg( R_ECX, Rm );118.412 - precheck();118.413 - check_ralign32( R_ECX );118.414 - load_reg( R_ECX, Rn );118.415 - check_ralign32( R_ECX );118.416 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );118.417 - MEM_READ_LONG( R_ECX, R_EAX );118.418 - PUSH_realigned_r32( R_EAX );118.419 - load_reg( R_ECX, Rm );118.420 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.421 + if( Rm == Rn ) {118.422 + load_reg( R_EAX, Rm );118.423 + check_ralign32( R_EAX );118.424 + MMU_TRANSLATE_READ( R_EAX );118.425 + PUSH_realigned_r32( R_EAX );118.426 + load_reg( R_EAX, Rn );118.427 + ADD_imm8s_r32( 4, R_EAX );118.428 + MMU_TRANSLATE_READ( R_EAX );118.429 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );118.430 + // Note translate twice in case of page boundaries. Maybe worth118.431 + // adding a page-boundary check to skip the second translation118.432 + } else {118.433 + load_reg( R_EAX, Rm );118.434 + check_ralign32( R_EAX );118.435 + MMU_TRANSLATE_READ( R_EAX );118.436 + PUSH_realigned_r32( R_EAX );118.437 + load_reg( R_EAX, Rn );118.438 + check_ralign32( R_EAX );118.439 + MMU_TRANSLATE_READ( R_EAX );118.440 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );118.441 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.442 + }118.443 + MEM_READ_LONG( R_EAX, R_EAX );118.444 + POP_r32( R_ECX );118.445 + PUSH_r32( R_EAX );118.446 MEM_READ_LONG( R_ECX, R_EAX );118.447 POP_realigned_r32( R_ECX );118.448 +118.449 IMUL_r32( R_ECX );118.450 ADD_r32_sh4r( R_EAX, R_MACL );118.451 ADC_r32_sh4r( R_EDX, R_MACH );118.452 @@ -858,12 +867,12 @@118.453 case 0x1:118.454 { /* MOV.L Rm, @(disp, Rn) */118.455 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;118.456 - load_reg( R_ECX, Rn );118.457 - load_reg( R_EAX, Rm );118.458 - ADD_imm32_r32( disp, R_ECX );118.459 - precheck();118.460 - check_walign32( R_ECX );118.461 - MEM_WRITE_LONG( R_ECX, R_EAX );118.462 + load_reg( R_EAX, Rn );118.463 + ADD_imm32_r32( disp, R_EAX );118.464 + check_walign32( R_EAX );118.465 + MMU_TRANSLATE_WRITE( R_EAX );118.466 + load_reg( R_EDX, Rm );118.467 + MEM_WRITE_LONG( R_EAX, R_EDX );118.468 sh4_x86.tstate = TSTATE_NONE;118.469 }118.470 break;118.471 @@ -872,68 +881,70 @@118.472 case 0x0:118.473 { /* MOV.B Rm, @Rn */118.474 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.475 - load_reg( R_EAX, Rm );118.476 - load_reg( R_ECX, Rn );118.477 - MEM_WRITE_BYTE( R_ECX, R_EAX );118.478 + load_reg( R_EAX, Rn );118.479 + MMU_TRANSLATE_WRITE( R_EAX );118.480 + load_reg( R_EDX, Rm );118.481 + MEM_WRITE_BYTE( R_EAX, R_EDX );118.482 sh4_x86.tstate = TSTATE_NONE;118.483 }118.484 break;118.485 case 0x1:118.486 { /* MOV.W Rm, @Rn */118.487 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.488 - load_reg( R_ECX, Rn );118.489 - precheck();118.490 - check_walign16( R_ECX );118.491 - load_reg( R_EAX, Rm );118.492 - MEM_WRITE_WORD( R_ECX, R_EAX );118.493 + load_reg( R_EAX, Rn );118.494 + check_walign16( R_EAX );118.495 + MMU_TRANSLATE_WRITE( R_EAX )118.496 + load_reg( R_EDX, Rm );118.497 + MEM_WRITE_WORD( R_EAX, R_EDX );118.498 sh4_x86.tstate = TSTATE_NONE;118.499 }118.500 break;118.501 case 0x2:118.502 { /* MOV.L Rm, @Rn */118.503 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.504 - load_reg( R_EAX, Rm );118.505 - load_reg( R_ECX, Rn );118.506 - precheck();118.507 - check_walign32(R_ECX);118.508 - MEM_WRITE_LONG( R_ECX, R_EAX );118.509 + load_reg( R_EAX, Rn );118.510 + check_walign32(R_EAX);118.511 + MMU_TRANSLATE_WRITE( R_EAX );118.512 + load_reg( R_EDX, Rm );118.513 + MEM_WRITE_LONG( R_EAX, R_EDX );118.514 sh4_x86.tstate = TSTATE_NONE;118.515 }118.516 break;118.517 case 0x4:118.518 { /* MOV.B Rm, @-Rn */118.519 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.520 - load_reg( R_EAX, Rm );118.521 - load_reg( R_ECX, Rn );118.522 - ADD_imm8s_r32( -1, R_ECX );118.523 - store_reg( R_ECX, Rn );118.524 - MEM_WRITE_BYTE( R_ECX, R_EAX );118.525 + load_reg( R_EAX, Rn );118.526 + ADD_imm8s_r32( -1, R_EAX );118.527 + MMU_TRANSLATE_WRITE( R_EAX );118.528 + load_reg( R_EDX, Rm );118.529 + ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );118.530 + MEM_WRITE_BYTE( R_EAX, R_EDX );118.531 sh4_x86.tstate = TSTATE_NONE;118.532 }118.533 break;118.534 case 0x5:118.535 { /* MOV.W Rm, @-Rn */118.536 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.537 - load_reg( R_ECX, Rn );118.538 - precheck();118.539 - check_walign16( R_ECX );118.540 - load_reg( R_EAX, Rm );118.541 - ADD_imm8s_r32( -2, R_ECX );118.542 - store_reg( R_ECX, Rn );118.543 - MEM_WRITE_WORD( R_ECX, R_EAX );118.544 + load_reg( R_EAX, Rn );118.545 + ADD_imm8s_r32( -2, R_EAX );118.546 + check_walign16( R_EAX );118.547 + MMU_TRANSLATE_WRITE( R_EAX );118.548 + load_reg( R_EDX, Rm );118.549 + ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );118.550 + MEM_WRITE_WORD( R_EAX, R_EDX );118.551 sh4_x86.tstate = TSTATE_NONE;118.552 }118.553 break;118.554 case 0x6:118.555 { /* MOV.L Rm, @-Rn */118.556 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.557 - load_reg( R_EAX, Rm );118.558 - load_reg( R_ECX, Rn );118.559 - precheck();118.560 - check_walign32( R_ECX );118.561 - ADD_imm8s_r32( -4, R_ECX );118.562 - store_reg( R_ECX, Rn );118.563 - MEM_WRITE_LONG( R_ECX, R_EAX );118.564 + load_reg( R_EAX, Rn );118.565 + ADD_imm8s_r32( -4, R_EAX );118.566 + check_walign32( R_EAX );118.567 + MMU_TRANSLATE_WRITE( R_EAX );118.568 + load_reg( R_EDX, Rm );118.569 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.570 + MEM_WRITE_LONG( R_EAX, R_EDX );118.571 sh4_x86.tstate = TSTATE_NONE;118.572 }118.573 break;118.574 @@ -1306,93 +1317,93 @@118.575 case 0x0:118.576 { /* STS.L MACH, @-Rn */118.577 uint32_t Rn = ((ir>>8)&0xF);118.578 - load_reg( R_ECX, Rn );118.579 - precheck();118.580 - check_walign32( R_ECX );118.581 - ADD_imm8s_r32( -4, R_ECX );118.582 - store_reg( R_ECX, Rn );118.583 - load_spreg( R_EAX, R_MACH );118.584 - MEM_WRITE_LONG( R_ECX, R_EAX );118.585 + load_reg( R_EAX, Rn );118.586 + check_walign32( R_EAX );118.587 + ADD_imm8s_r32( -4, R_EAX );118.588 + MMU_TRANSLATE_WRITE( R_EAX );118.589 + load_spreg( R_EDX, R_MACH );118.590 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.591 + MEM_WRITE_LONG( R_EAX, R_EDX );118.592 sh4_x86.tstate = TSTATE_NONE;118.593 }118.594 break;118.595 case 0x1:118.596 { /* STS.L MACL, @-Rn */118.597 uint32_t Rn = ((ir>>8)&0xF);118.598 - load_reg( R_ECX, Rn );118.599 - precheck();118.600 - check_walign32( R_ECX );118.601 - ADD_imm8s_r32( -4, R_ECX );118.602 - store_reg( R_ECX, Rn );118.603 - load_spreg( R_EAX, R_MACL );118.604 - MEM_WRITE_LONG( R_ECX, R_EAX );118.605 + load_reg( R_EAX, Rn );118.606 + check_walign32( R_EAX );118.607 + ADD_imm8s_r32( -4, R_EAX );118.608 + MMU_TRANSLATE_WRITE( R_EAX );118.609 + load_spreg( R_EDX, R_MACL );118.610 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.611 + MEM_WRITE_LONG( R_EAX, R_EDX );118.612 sh4_x86.tstate = TSTATE_NONE;118.613 }118.614 break;118.615 case 0x2:118.616 { /* STS.L PR, @-Rn */118.617 uint32_t Rn = ((ir>>8)&0xF);118.618 - load_reg( R_ECX, Rn );118.619 - precheck();118.620 - check_walign32( R_ECX );118.621 - ADD_imm8s_r32( -4, R_ECX );118.622 - store_reg( R_ECX, Rn );118.623 - load_spreg( R_EAX, R_PR );118.624 - MEM_WRITE_LONG( R_ECX, R_EAX );118.625 + load_reg( R_EAX, Rn );118.626 + check_walign32( R_EAX );118.627 + ADD_imm8s_r32( -4, R_EAX );118.628 + MMU_TRANSLATE_WRITE( R_EAX );118.629 + load_spreg( R_EDX, R_PR );118.630 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.631 + MEM_WRITE_LONG( R_EAX, R_EDX );118.632 sh4_x86.tstate = TSTATE_NONE;118.633 }118.634 break;118.635 case 0x3:118.636 { /* STC.L SGR, @-Rn */118.637 uint32_t Rn = ((ir>>8)&0xF);118.638 - precheck();118.639 - check_priv_no_precheck();118.640 - load_reg( R_ECX, Rn );118.641 - check_walign32( R_ECX );118.642 - ADD_imm8s_r32( -4, R_ECX );118.643 - store_reg( R_ECX, Rn );118.644 - load_spreg( R_EAX, R_SGR );118.645 - MEM_WRITE_LONG( R_ECX, R_EAX );118.646 + check_priv();118.647 + load_reg( R_EAX, Rn );118.648 + check_walign32( R_EAX );118.649 + ADD_imm8s_r32( -4, R_EAX );118.650 + MMU_TRANSLATE_WRITE( R_EAX );118.651 + load_spreg( R_EDX, R_SGR );118.652 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.653 + MEM_WRITE_LONG( R_EAX, R_EDX );118.654 sh4_x86.tstate = TSTATE_NONE;118.655 }118.656 break;118.657 case 0x5:118.658 { /* STS.L FPUL, @-Rn */118.659 uint32_t Rn = ((ir>>8)&0xF);118.660 - load_reg( R_ECX, Rn );118.661 - precheck();118.662 - check_walign32( R_ECX );118.663 - ADD_imm8s_r32( -4, R_ECX );118.664 - store_reg( R_ECX, Rn );118.665 - load_spreg( R_EAX, R_FPUL );118.666 - MEM_WRITE_LONG( R_ECX, R_EAX );118.667 + load_reg( R_EAX, Rn );118.668 + check_walign32( R_EAX );118.669 + ADD_imm8s_r32( -4, R_EAX );118.670 + MMU_TRANSLATE_WRITE( R_EAX );118.671 + load_spreg( R_EDX, R_FPUL );118.672 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.673 + MEM_WRITE_LONG( R_EAX, R_EDX );118.674 sh4_x86.tstate = TSTATE_NONE;118.675 }118.676 break;118.677 case 0x6:118.678 { /* STS.L FPSCR, @-Rn */118.679 uint32_t Rn = ((ir>>8)&0xF);118.680 - load_reg( R_ECX, Rn );118.681 - precheck();118.682 - check_walign32( R_ECX );118.683 - ADD_imm8s_r32( -4, R_ECX );118.684 - store_reg( R_ECX, Rn );118.685 - load_spreg( R_EAX, R_FPSCR );118.686 - MEM_WRITE_LONG( R_ECX, R_EAX );118.687 + load_reg( R_EAX, Rn );118.688 + check_walign32( R_EAX );118.689 + ADD_imm8s_r32( -4, R_EAX );118.690 + MMU_TRANSLATE_WRITE( R_EAX );118.691 + load_spreg( R_EDX, R_FPSCR );118.692 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.693 + MEM_WRITE_LONG( R_EAX, R_EDX );118.694 sh4_x86.tstate = TSTATE_NONE;118.695 }118.696 break;118.697 case 0xF:118.698 { /* STC.L DBR, @-Rn */118.699 uint32_t Rn = ((ir>>8)&0xF);118.700 - precheck();118.701 - check_priv_no_precheck();118.702 - load_reg( R_ECX, Rn );118.703 - check_walign32( R_ECX );118.704 - ADD_imm8s_r32( -4, R_ECX );118.705 - store_reg( R_ECX, Rn );118.706 - load_spreg( R_EAX, R_DBR );118.707 - MEM_WRITE_LONG( R_ECX, R_EAX );118.708 + check_priv();118.709 + load_reg( R_EAX, Rn );118.710 + check_walign32( R_EAX );118.711 + ADD_imm8s_r32( -4, R_EAX );118.712 + MMU_TRANSLATE_WRITE( R_EAX );118.713 + load_spreg( R_EDX, R_DBR );118.714 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.715 + MEM_WRITE_LONG( R_EAX, R_EDX );118.716 sh4_x86.tstate = TSTATE_NONE;118.717 }118.718 break;118.719 @@ -1408,13 +1419,15 @@118.720 case 0x0:118.721 { /* STC.L SR, @-Rn */118.722 uint32_t Rn = ((ir>>8)&0xF);118.723 - precheck();118.724 - check_priv_no_precheck();118.725 + check_priv();118.726 + load_reg( R_EAX, Rn );118.727 + check_walign32( R_EAX );118.728 + ADD_imm8s_r32( -4, R_EAX );118.729 + MMU_TRANSLATE_WRITE( R_EAX );118.730 + PUSH_realigned_r32( R_EAX );118.731 call_func0( sh4_read_sr );118.732 - load_reg( R_ECX, Rn );118.733 - check_walign32( R_ECX );118.734 - ADD_imm8s_r32( -4, R_ECX );118.735 - store_reg( R_ECX, Rn );118.736 + POP_realigned_r32( R_ECX );118.737 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.738 MEM_WRITE_LONG( R_ECX, R_EAX );118.739 sh4_x86.tstate = TSTATE_NONE;118.740 }118.741 @@ -1422,55 +1435,55 @@118.742 case 0x1:118.743 { /* STC.L GBR, @-Rn */118.744 uint32_t Rn = ((ir>>8)&0xF);118.745 - load_reg( R_ECX, Rn );118.746 - precheck();118.747 - check_walign32( R_ECX );118.748 - ADD_imm8s_r32( -4, R_ECX );118.749 - store_reg( R_ECX, Rn );118.750 - load_spreg( R_EAX, R_GBR );118.751 - MEM_WRITE_LONG( R_ECX, R_EAX );118.752 + load_reg( R_EAX, Rn );118.753 + check_walign32( R_EAX );118.754 + ADD_imm8s_r32( -4, R_EAX );118.755 + MMU_TRANSLATE_WRITE( R_EAX );118.756 + load_spreg( R_EDX, R_GBR );118.757 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.758 + MEM_WRITE_LONG( R_EAX, R_EDX );118.759 sh4_x86.tstate = TSTATE_NONE;118.760 }118.761 break;118.762 case 0x2:118.763 { /* STC.L VBR, @-Rn */118.764 uint32_t Rn = ((ir>>8)&0xF);118.765 - precheck();118.766 - check_priv_no_precheck();118.767 - load_reg( R_ECX, Rn );118.768 - check_walign32( R_ECX );118.769 - ADD_imm8s_r32( -4, R_ECX );118.770 - store_reg( R_ECX, Rn );118.771 - load_spreg( R_EAX, R_VBR );118.772 - MEM_WRITE_LONG( R_ECX, R_EAX );118.773 + check_priv();118.774 + load_reg( R_EAX, Rn );118.775 + check_walign32( R_EAX );118.776 + ADD_imm8s_r32( -4, R_EAX );118.777 + MMU_TRANSLATE_WRITE( R_EAX );118.778 + load_spreg( R_EDX, R_VBR );118.779 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.780 + MEM_WRITE_LONG( R_EAX, R_EDX );118.781 sh4_x86.tstate = TSTATE_NONE;118.782 }118.783 break;118.784 case 0x3:118.785 { /* STC.L SSR, @-Rn */118.786 uint32_t Rn = ((ir>>8)&0xF);118.787 - precheck();118.788 - check_priv_no_precheck();118.789 - load_reg( R_ECX, Rn );118.790 - check_walign32( R_ECX );118.791 - ADD_imm8s_r32( -4, R_ECX );118.792 - store_reg( R_ECX, Rn );118.793 - load_spreg( R_EAX, R_SSR );118.794 - MEM_WRITE_LONG( R_ECX, R_EAX );118.795 + check_priv();118.796 + load_reg( R_EAX, Rn );118.797 + check_walign32( R_EAX );118.798 + ADD_imm8s_r32( -4, R_EAX );118.799 + MMU_TRANSLATE_WRITE( R_EAX );118.800 + load_spreg( R_EDX, R_SSR );118.801 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.802 + MEM_WRITE_LONG( R_EAX, R_EDX );118.803 sh4_x86.tstate = TSTATE_NONE;118.804 }118.805 break;118.806 case 0x4:118.807 { /* STC.L SPC, @-Rn */118.808 uint32_t Rn = ((ir>>8)&0xF);118.809 - precheck();118.810 - check_priv_no_precheck();118.811 - load_reg( R_ECX, Rn );118.812 - check_walign32( R_ECX );118.813 - ADD_imm8s_r32( -4, R_ECX );118.814 - store_reg( R_ECX, Rn );118.815 - load_spreg( R_EAX, R_SPC );118.816 - MEM_WRITE_LONG( R_ECX, R_EAX );118.817 + check_priv();118.818 + load_reg( R_EAX, Rn );118.819 + check_walign32( R_EAX );118.820 + ADD_imm8s_r32( -4, R_EAX );118.821 + MMU_TRANSLATE_WRITE( R_EAX );118.822 + load_spreg( R_EDX, R_SPC );118.823 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.824 + MEM_WRITE_LONG( R_EAX, R_EDX );118.825 sh4_x86.tstate = TSTATE_NONE;118.826 }118.827 break;118.828 @@ -1482,14 +1495,14 @@118.829 case 0x1:118.830 { /* STC.L Rm_BANK, @-Rn */118.831 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);118.832 - precheck();118.833 - check_priv_no_precheck();118.834 - load_reg( R_ECX, Rn );118.835 - check_walign32( R_ECX );118.836 - ADD_imm8s_r32( -4, R_ECX );118.837 - store_reg( R_ECX, Rn );118.838 - load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );118.839 - MEM_WRITE_LONG( R_ECX, R_EAX );118.840 + check_priv();118.841 + load_reg( R_EAX, Rn );118.842 + check_walign32( R_EAX );118.843 + ADD_imm8s_r32( -4, R_EAX );118.844 + MMU_TRANSLATE_WRITE( R_EAX );118.845 + load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );118.846 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );118.847 + MEM_WRITE_LONG( R_EAX, R_EDX );118.848 sh4_x86.tstate = TSTATE_NONE;118.849 }118.850 break;118.851 @@ -1570,12 +1583,10 @@118.852 { /* LDS.L @Rm+, MACH */118.853 uint32_t Rm = ((ir>>8)&0xF);118.854 load_reg( R_EAX, Rm );118.855 - precheck();118.856 check_ralign32( R_EAX );118.857 - MOV_r32_r32( R_EAX, R_ECX );118.858 - ADD_imm8s_r32( 4, R_EAX );118.859 - store_reg( R_EAX, Rm );118.860 - MEM_READ_LONG( R_ECX, R_EAX );118.861 + MMU_TRANSLATE_READ( R_EAX );118.862 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.863 + MEM_READ_LONG( R_EAX, R_EAX );118.864 store_spreg( R_EAX, R_MACH );118.865 sh4_x86.tstate = TSTATE_NONE;118.866 }118.867 @@ -1584,12 +1595,10 @@118.868 { /* LDS.L @Rm+, MACL */118.869 uint32_t Rm = ((ir>>8)&0xF);118.870 load_reg( R_EAX, Rm );118.871 - precheck();118.872 check_ralign32( R_EAX );118.873 - MOV_r32_r32( R_EAX, R_ECX );118.874 - ADD_imm8s_r32( 4, R_EAX );118.875 - store_reg( R_EAX, Rm );118.876 - MEM_READ_LONG( R_ECX, R_EAX );118.877 + MMU_TRANSLATE_READ( R_EAX );118.878 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.879 + MEM_READ_LONG( R_EAX, R_EAX );118.880 store_spreg( R_EAX, R_MACL );118.881 sh4_x86.tstate = TSTATE_NONE;118.882 }118.883 @@ -1598,12 +1607,10 @@118.884 { /* LDS.L @Rm+, PR */118.885 uint32_t Rm = ((ir>>8)&0xF);118.886 load_reg( R_EAX, Rm );118.887 - precheck();118.888 check_ralign32( R_EAX );118.889 - MOV_r32_r32( R_EAX, R_ECX );118.890 - ADD_imm8s_r32( 4, R_EAX );118.891 - store_reg( R_EAX, Rm );118.892 - MEM_READ_LONG( R_ECX, R_EAX );118.893 + MMU_TRANSLATE_READ( R_EAX );118.894 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.895 + MEM_READ_LONG( R_EAX, R_EAX );118.896 store_spreg( R_EAX, R_PR );118.897 sh4_x86.tstate = TSTATE_NONE;118.898 }118.899 @@ -1611,14 +1618,12 @@118.900 case 0x3:118.901 { /* LDC.L @Rm+, SGR */118.902 uint32_t Rm = ((ir>>8)&0xF);118.903 - precheck();118.904 - check_priv_no_precheck();118.905 + check_priv();118.906 load_reg( R_EAX, Rm );118.907 check_ralign32( R_EAX );118.908 - MOV_r32_r32( R_EAX, R_ECX );118.909 - ADD_imm8s_r32( 4, R_EAX );118.910 - store_reg( R_EAX, Rm );118.911 - MEM_READ_LONG( R_ECX, R_EAX );118.912 + MMU_TRANSLATE_READ( R_EAX );118.913 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.914 + MEM_READ_LONG( R_EAX, R_EAX );118.915 store_spreg( R_EAX, R_SGR );118.916 sh4_x86.tstate = TSTATE_NONE;118.917 }118.918 @@ -1627,12 +1632,10 @@118.919 { /* LDS.L @Rm+, FPUL */118.920 uint32_t Rm = ((ir>>8)&0xF);118.921 load_reg( R_EAX, Rm );118.922 - precheck();118.923 check_ralign32( R_EAX );118.924 - MOV_r32_r32( R_EAX, R_ECX );118.925 - ADD_imm8s_r32( 4, R_EAX );118.926 - store_reg( R_EAX, Rm );118.927 - MEM_READ_LONG( R_ECX, R_EAX );118.928 + MMU_TRANSLATE_READ( R_EAX );118.929 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.930 + MEM_READ_LONG( R_EAX, R_EAX );118.931 store_spreg( R_EAX, R_FPUL );118.932 sh4_x86.tstate = TSTATE_NONE;118.933 }118.934 @@ -1641,12 +1644,10 @@118.935 { /* LDS.L @Rm+, FPSCR */118.936 uint32_t Rm = ((ir>>8)&0xF);118.937 load_reg( R_EAX, Rm );118.938 - precheck();118.939 check_ralign32( R_EAX );118.940 - MOV_r32_r32( R_EAX, R_ECX );118.941 - ADD_imm8s_r32( 4, R_EAX );118.942 - store_reg( R_EAX, Rm );118.943 - MEM_READ_LONG( R_ECX, R_EAX );118.944 + MMU_TRANSLATE_READ( R_EAX );118.945 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.946 + MEM_READ_LONG( R_EAX, R_EAX );118.947 store_spreg( R_EAX, R_FPSCR );118.948 update_fr_bank( R_EAX );118.949 sh4_x86.tstate = TSTATE_NONE;118.950 @@ -1655,14 +1656,12 @@118.951 case 0xF:118.952 { /* LDC.L @Rm+, DBR */118.953 uint32_t Rm = ((ir>>8)&0xF);118.954 - precheck();118.955 - check_priv_no_precheck();118.956 + check_priv();118.957 load_reg( R_EAX, Rm );118.958 check_ralign32( R_EAX );118.959 - MOV_r32_r32( R_EAX, R_ECX );118.960 - ADD_imm8s_r32( 4, R_EAX );118.961 - store_reg( R_EAX, Rm );118.962 - MEM_READ_LONG( R_ECX, R_EAX );118.963 + MMU_TRANSLATE_READ( R_EAX );118.964 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.965 + MEM_READ_LONG( R_EAX, R_EAX );118.966 store_spreg( R_EAX, R_DBR );118.967 sh4_x86.tstate = TSTATE_NONE;118.968 }118.969 @@ -1682,14 +1681,12 @@118.970 if( sh4_x86.in_delay_slot ) {118.971 SLOTILLEGAL();118.972 } else {118.973 - precheck();118.974 - check_priv_no_precheck();118.975 + check_priv();118.976 load_reg( R_EAX, Rm );118.977 check_ralign32( R_EAX );118.978 - MOV_r32_r32( R_EAX, R_ECX );118.979 - ADD_imm8s_r32( 4, R_EAX );118.980 - store_reg( R_EAX, Rm );118.981 - MEM_READ_LONG( R_ECX, R_EAX );118.982 + MMU_TRANSLATE_READ( R_EAX );118.983 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.984 + MEM_READ_LONG( R_EAX, R_EAX );118.985 call_func1( sh4_write_sr, R_EAX );118.986 sh4_x86.priv_checked = FALSE;118.987 sh4_x86.fpuen_checked = FALSE;118.988 @@ -1701,12 +1698,10 @@118.989 { /* LDC.L @Rm+, GBR */118.990 uint32_t Rm = ((ir>>8)&0xF);118.991 load_reg( R_EAX, Rm );118.992 - precheck();118.993 check_ralign32( R_EAX );118.994 - MOV_r32_r32( R_EAX, R_ECX );118.995 - ADD_imm8s_r32( 4, R_EAX );118.996 - store_reg( R_EAX, Rm );118.997 - MEM_READ_LONG( R_ECX, R_EAX );118.998 + MMU_TRANSLATE_READ( R_EAX );118.999 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1000 + MEM_READ_LONG( R_EAX, R_EAX );118.1001 store_spreg( R_EAX, R_GBR );118.1002 sh4_x86.tstate = TSTATE_NONE;118.1003 }118.1004 @@ -1714,14 +1709,12 @@118.1005 case 0x2:118.1006 { /* LDC.L @Rm+, VBR */118.1007 uint32_t Rm = ((ir>>8)&0xF);118.1008 - precheck();118.1009 - check_priv_no_precheck();118.1010 + check_priv();118.1011 load_reg( R_EAX, Rm );118.1012 check_ralign32( R_EAX );118.1013 - MOV_r32_r32( R_EAX, R_ECX );118.1014 - ADD_imm8s_r32( 4, R_EAX );118.1015 - store_reg( R_EAX, Rm );118.1016 - MEM_READ_LONG( R_ECX, R_EAX );118.1017 + MMU_TRANSLATE_READ( R_EAX );118.1018 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1019 + MEM_READ_LONG( R_EAX, R_EAX );118.1020 store_spreg( R_EAX, R_VBR );118.1021 sh4_x86.tstate = TSTATE_NONE;118.1022 }118.1023 @@ -1729,14 +1722,12 @@118.1024 case 0x3:118.1025 { /* LDC.L @Rm+, SSR */118.1026 uint32_t Rm = ((ir>>8)&0xF);118.1027 - precheck();118.1028 - check_priv_no_precheck();118.1029 + check_priv();118.1030 load_reg( R_EAX, Rm );118.1031 check_ralign32( R_EAX );118.1032 - MOV_r32_r32( R_EAX, R_ECX );118.1033 - ADD_imm8s_r32( 4, R_EAX );118.1034 - store_reg( R_EAX, Rm );118.1035 - MEM_READ_LONG( R_ECX, R_EAX );118.1036 + MMU_TRANSLATE_READ( R_EAX );118.1037 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1038 + MEM_READ_LONG( R_EAX, R_EAX );118.1039 store_spreg( R_EAX, R_SSR );118.1040 sh4_x86.tstate = TSTATE_NONE;118.1041 }118.1042 @@ -1744,14 +1735,12 @@118.1043 case 0x4:118.1044 { /* LDC.L @Rm+, SPC */118.1045 uint32_t Rm = ((ir>>8)&0xF);118.1046 - precheck();118.1047 - check_priv_no_precheck();118.1048 + check_priv();118.1049 load_reg( R_EAX, Rm );118.1050 check_ralign32( R_EAX );118.1051 - MOV_r32_r32( R_EAX, R_ECX );118.1052 - ADD_imm8s_r32( 4, R_EAX );118.1053 - store_reg( R_EAX, Rm );118.1054 - MEM_READ_LONG( R_ECX, R_EAX );118.1055 + MMU_TRANSLATE_READ( R_EAX );118.1056 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1057 + MEM_READ_LONG( R_EAX, R_EAX );118.1058 store_spreg( R_EAX, R_SPC );118.1059 sh4_x86.tstate = TSTATE_NONE;118.1060 }118.1061 @@ -1764,14 +1753,12 @@118.1062 case 0x1:118.1063 { /* LDC.L @Rm+, Rn_BANK */118.1064 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);118.1065 - precheck();118.1066 - check_priv_no_precheck();118.1067 + check_priv();118.1068 load_reg( R_EAX, Rm );118.1069 check_ralign32( R_EAX );118.1070 - MOV_r32_r32( R_EAX, R_ECX );118.1071 - ADD_imm8s_r32( 4, R_EAX );118.1072 - store_reg( R_EAX, Rm );118.1073 - MEM_READ_LONG( R_ECX, R_EAX );118.1074 + MMU_TRANSLATE_READ( R_EAX );118.1075 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1076 + MEM_READ_LONG( R_EAX, R_EAX );118.1077 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );118.1078 sh4_x86.tstate = TSTATE_NONE;118.1079 }118.1080 @@ -1931,12 +1918,14 @@118.1081 case 0x1:118.1082 { /* TAS.B @Rn */118.1083 uint32_t Rn = ((ir>>8)&0xF);118.1084 - load_reg( R_ECX, Rn );118.1085 - MEM_READ_BYTE( R_ECX, R_EAX );118.1086 + load_reg( R_EAX, Rn );118.1087 + MMU_TRANSLATE_WRITE( R_EAX );118.1088 + PUSH_realigned_r32( R_EAX );118.1089 + MEM_READ_BYTE( R_EAX, R_EAX );118.1090 TEST_r8_r8( R_AL, R_AL );118.1091 SETE_t();118.1092 OR_imm8_r8( 0x80, R_AL );118.1093 - load_reg( R_ECX, Rn );118.1094 + POP_realigned_r32( R_ECX );118.1095 MEM_WRITE_BYTE( R_ECX, R_EAX );118.1096 sh4_x86.tstate = TSTATE_NONE;118.1097 }118.1098 @@ -2089,16 +2078,31 @@118.1099 case 0xF:118.1100 { /* MAC.W @Rm+, @Rn+ */118.1101 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1102 - load_reg( R_ECX, Rm );118.1103 - precheck();118.1104 - check_ralign16( R_ECX );118.1105 - load_reg( R_ECX, Rn );118.1106 - check_ralign16( R_ECX );118.1107 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );118.1108 - MEM_READ_WORD( R_ECX, R_EAX );118.1109 - PUSH_realigned_r32( R_EAX );118.1110 - load_reg( R_ECX, Rm );118.1111 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );118.1112 + if( Rm == Rn ) {118.1113 + load_reg( R_EAX, Rm );118.1114 + check_ralign16( R_EAX );118.1115 + MMU_TRANSLATE_READ( R_EAX );118.1116 + PUSH_realigned_r32( R_EAX );118.1117 + load_reg( R_EAX, Rn );118.1118 + ADD_imm8s_r32( 2, R_EAX );118.1119 + MMU_TRANSLATE_READ( R_EAX );118.1120 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );118.1121 + // Note translate twice in case of page boundaries. Maybe worth118.1122 + // adding a page-boundary check to skip the second translation118.1123 + } else {118.1124 + load_reg( R_EAX, Rm );118.1125 + check_ralign16( R_EAX );118.1126 + MMU_TRANSLATE_READ( R_EAX );118.1127 + PUSH_realigned_r32( R_EAX );118.1128 + load_reg( R_EAX, Rn );118.1129 + check_ralign16( R_EAX );118.1130 + MMU_TRANSLATE_READ( R_EAX );118.1131 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );118.1132 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );118.1133 + }118.1134 + MEM_READ_WORD( R_EAX, R_EAX );118.1135 + POP_r32( R_ECX );118.1136 + PUSH_r32( R_EAX );118.1137 MEM_READ_WORD( R_ECX, R_EAX );118.1138 POP_realigned_r32( R_ECX );118.1139 IMUL_r32( R_ECX );118.1140 @@ -2135,11 +2139,11 @@118.1141 case 0x5:118.1142 { /* MOV.L @(disp, Rm), Rn */118.1143 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;118.1144 - load_reg( R_ECX, Rm );118.1145 - ADD_imm8s_r32( disp, R_ECX );118.1146 - precheck();118.1147 - check_ralign32( R_ECX );118.1148 - MEM_READ_LONG( R_ECX, R_EAX );118.1149 + load_reg( R_EAX, Rm );118.1150 + ADD_imm8s_r32( disp, R_EAX );118.1151 + check_ralign32( R_EAX );118.1152 + MMU_TRANSLATE_READ( R_EAX );118.1153 + MEM_READ_LONG( R_EAX, R_EAX );118.1154 store_reg( R_EAX, Rn );118.1155 sh4_x86.tstate = TSTATE_NONE;118.1156 }118.1157 @@ -2149,8 +2153,9 @@118.1158 case 0x0:118.1159 { /* MOV.B @Rm, Rn */118.1160 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1161 - load_reg( R_ECX, Rm );118.1162 - MEM_READ_BYTE( R_ECX, R_EAX );118.1163 + load_reg( R_EAX, Rm );118.1164 + MMU_TRANSLATE_READ( R_EAX );118.1165 + MEM_READ_BYTE( R_EAX, R_EAX );118.1166 store_reg( R_EAX, Rn );118.1167 sh4_x86.tstate = TSTATE_NONE;118.1168 }118.1169 @@ -2158,10 +2163,10 @@118.1170 case 0x1:118.1171 { /* MOV.W @Rm, Rn */118.1172 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1173 - load_reg( R_ECX, Rm );118.1174 - precheck();118.1175 - check_ralign16( R_ECX );118.1176 - MEM_READ_WORD( R_ECX, R_EAX );118.1177 + load_reg( R_EAX, Rm );118.1178 + check_ralign16( R_EAX );118.1179 + MMU_TRANSLATE_READ( R_EAX );118.1180 + MEM_READ_WORD( R_EAX, R_EAX );118.1181 store_reg( R_EAX, Rn );118.1182 sh4_x86.tstate = TSTATE_NONE;118.1183 }118.1184 @@ -2169,10 +2174,10 @@118.1185 case 0x2:118.1186 { /* MOV.L @Rm, Rn */118.1187 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1188 - load_reg( R_ECX, Rm );118.1189 - precheck();118.1190 - check_ralign32( R_ECX );118.1191 - MEM_READ_LONG( R_ECX, R_EAX );118.1192 + load_reg( R_EAX, Rm );118.1193 + check_ralign32( R_EAX );118.1194 + MMU_TRANSLATE_READ( R_EAX );118.1195 + MEM_READ_LONG( R_EAX, R_EAX );118.1196 store_reg( R_EAX, Rn );118.1197 sh4_x86.tstate = TSTATE_NONE;118.1198 }118.1199 @@ -2187,11 +2192,10 @@118.1200 case 0x4:118.1201 { /* MOV.B @Rm+, Rn */118.1202 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1203 - load_reg( R_ECX, Rm );118.1204 - MOV_r32_r32( R_ECX, R_EAX );118.1205 - ADD_imm8s_r32( 1, R_EAX );118.1206 - store_reg( R_EAX, Rm );118.1207 - MEM_READ_BYTE( R_ECX, R_EAX );118.1208 + load_reg( R_EAX, Rm );118.1209 + MMU_TRANSLATE_READ( R_EAX );118.1210 + ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );118.1211 + MEM_READ_BYTE( R_EAX, R_EAX );118.1212 store_reg( R_EAX, Rn );118.1213 sh4_x86.tstate = TSTATE_NONE;118.1214 }118.1215 @@ -2200,12 +2204,10 @@118.1216 { /* MOV.W @Rm+, Rn */118.1217 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1218 load_reg( R_EAX, Rm );118.1219 - precheck();118.1220 check_ralign16( R_EAX );118.1221 - MOV_r32_r32( R_EAX, R_ECX );118.1222 - ADD_imm8s_r32( 2, R_EAX );118.1223 - store_reg( R_EAX, Rm );118.1224 - MEM_READ_WORD( R_ECX, R_EAX );118.1225 + MMU_TRANSLATE_READ( R_EAX );118.1226 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );118.1227 + MEM_READ_WORD( R_EAX, R_EAX );118.1228 store_reg( R_EAX, Rn );118.1229 sh4_x86.tstate = TSTATE_NONE;118.1230 }118.1231 @@ -2214,12 +2216,10 @@118.1232 { /* MOV.L @Rm+, Rn */118.1233 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1234 load_reg( R_EAX, Rm );118.1235 - precheck();118.1236 check_ralign32( R_EAX );118.1237 - MOV_r32_r32( R_EAX, R_ECX );118.1238 - ADD_imm8s_r32( 4, R_EAX );118.1239 - store_reg( R_EAX, Rm );118.1240 - MEM_READ_LONG( R_ECX, R_EAX );118.1241 + MMU_TRANSLATE_READ( R_EAX );118.1242 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1243 + MEM_READ_LONG( R_EAX, R_EAX );118.1244 store_reg( R_EAX, Rn );118.1245 sh4_x86.tstate = TSTATE_NONE;118.1246 }118.1247 @@ -2322,31 +2322,33 @@118.1248 case 0x0:118.1249 { /* MOV.B R0, @(disp, Rn) */118.1250 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);118.1251 - load_reg( R_EAX, 0 );118.1252 - load_reg( R_ECX, Rn );118.1253 - ADD_imm32_r32( disp, R_ECX );118.1254 - MEM_WRITE_BYTE( R_ECX, R_EAX );118.1255 + load_reg( R_EAX, Rn );118.1256 + ADD_imm32_r32( disp, R_EAX );118.1257 + MMU_TRANSLATE_WRITE( R_EAX );118.1258 + load_reg( R_EDX, 0 );118.1259 + MEM_WRITE_BYTE( R_EAX, R_EDX );118.1260 sh4_x86.tstate = TSTATE_NONE;118.1261 }118.1262 break;118.1263 case 0x1:118.1264 { /* MOV.W R0, @(disp, Rn) */118.1265 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;118.1266 - load_reg( R_ECX, Rn );118.1267 - load_reg( R_EAX, 0 );118.1268 - ADD_imm32_r32( disp, R_ECX );118.1269 - precheck();118.1270 - check_walign16( R_ECX );118.1271 - MEM_WRITE_WORD( R_ECX, R_EAX );118.1272 + load_reg( R_EAX, Rn );118.1273 + ADD_imm32_r32( disp, R_EAX );118.1274 + check_walign16( R_EAX );118.1275 + MMU_TRANSLATE_WRITE( R_EAX );118.1276 + load_reg( R_EDX, 0 );118.1277 + MEM_WRITE_WORD( R_EAX, R_EDX );118.1278 sh4_x86.tstate = TSTATE_NONE;118.1279 }118.1280 break;118.1281 case 0x4:118.1282 { /* MOV.B @(disp, Rm), R0 */118.1283 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);118.1284 - load_reg( R_ECX, Rm );118.1285 - ADD_imm32_r32( disp, R_ECX );118.1286 - MEM_READ_BYTE( R_ECX, R_EAX );118.1287 + load_reg( R_EAX, Rm );118.1288 + ADD_imm32_r32( disp, R_EAX );118.1289 + MMU_TRANSLATE_READ( R_EAX );118.1290 + MEM_READ_BYTE( R_EAX, R_EAX );118.1291 store_reg( R_EAX, 0 );118.1292 sh4_x86.tstate = TSTATE_NONE;118.1293 }118.1294 @@ -2354,11 +2356,11 @@118.1295 case 0x5:118.1296 { /* MOV.W @(disp, Rm), R0 */118.1297 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;118.1298 - load_reg( R_ECX, Rm );118.1299 - ADD_imm32_r32( disp, R_ECX );118.1300 - precheck();118.1301 - check_ralign16( R_ECX );118.1302 - MEM_READ_WORD( R_ECX, R_EAX );118.1303 + load_reg( R_EAX, Rm );118.1304 + ADD_imm32_r32( disp, R_EAX );118.1305 + check_ralign16( R_EAX );118.1306 + MMU_TRANSLATE_READ( R_EAX );118.1307 + MEM_READ_WORD( R_EAX, R_EAX );118.1308 store_reg( R_EAX, 0 );118.1309 sh4_x86.tstate = TSTATE_NONE;118.1310 }118.1311 @@ -2378,8 +2380,9 @@118.1312 if( sh4_x86.in_delay_slot ) {118.1313 SLOTILLEGAL();118.1314 } else {118.1315 - JF_rel8( EXIT_BLOCK_SIZE, nottaken );118.1316 - exit_block( disp + pc + 4, pc+2 );118.1317 + sh4vma_t target = disp + pc + 4;118.1318 + JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );118.1319 + exit_block_rel(target, pc+2 );118.1320 JMP_TARGET(nottaken);118.1321 return 2;118.1322 }118.1323 @@ -2391,8 +2394,9 @@118.1324 if( sh4_x86.in_delay_slot ) {118.1325 SLOTILLEGAL();118.1326 } else {118.1327 - JT_rel8( EXIT_BLOCK_SIZE, nottaken );118.1328 - exit_block( disp + pc + 4, pc+2 );118.1329 + sh4vma_t target = disp + pc + 4;118.1330 + JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );118.1331 + exit_block_rel(target, pc+2 );118.1332 JMP_TARGET(nottaken);118.1333 return 2;118.1334 }118.1335 @@ -2411,7 +2415,7 @@118.1336 }118.1337 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32118.1338 sh4_translate_instruction(pc+2);118.1339 - exit_block( disp + pc + 4, pc+4 );118.1340 + exit_block_rel( disp + pc + 4, pc+4 );118.1341 // not taken118.1342 *patch = (xlat_output - ((uint8_t *)patch)) - 4;118.1343 sh4_translate_instruction(pc+2);118.1344 @@ -2425,6 +2429,7 @@118.1345 if( sh4_x86.in_delay_slot ) {118.1346 SLOTILLEGAL();118.1347 } else {118.1348 + sh4vma_t target = disp + pc + 4;118.1349 sh4_x86.in_delay_slot = TRUE;118.1350 if( sh4_x86.tstate == TSTATE_NONE ) {118.1351 CMP_imm8s_sh4r( 1, R_T );118.1352 @@ -2432,7 +2437,7 @@118.1353 }118.1354 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32118.1355 sh4_translate_instruction(pc+2);118.1356 - exit_block( disp + pc + 4, pc+4 );118.1357 + exit_block_rel( target, pc+4 );118.1358 // not taken118.1359 *patch = (xlat_output - ((uint8_t *)patch)) - 4;118.1360 sh4_translate_instruction(pc+2);118.1361 @@ -2451,10 +2456,20 @@118.1362 if( sh4_x86.in_delay_slot ) {118.1363 SLOTILLEGAL();118.1364 } else {118.1365 - load_imm32( R_ECX, pc + disp + 4 );118.1366 - MEM_READ_WORD( R_ECX, R_EAX );118.1367 + // See comments for MOV.L @(disp, PC), Rn118.1368 + uint32_t target = pc + disp + 4;118.1369 + if( IS_IN_ICACHE(target) ) {118.1370 + sh4ptr_t ptr = GET_ICACHE_PTR(target);118.1371 + MOV_moff32_EAX( ptr );118.1372 + MOVSX_r16_r32( R_EAX, R_EAX );118.1373 + } else {118.1374 + load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );118.1375 + ADD_sh4r_r32( R_PC, R_EAX );118.1376 + MMU_TRANSLATE_READ( R_EAX );118.1377 + MEM_READ_WORD( R_EAX, R_EAX );118.1378 + sh4_x86.tstate = TSTATE_NONE;118.1379 + }118.1380 store_reg( R_EAX, Rn );118.1381 - sh4_x86.tstate = TSTATE_NONE;118.1382 }118.1383 }118.1384 break;118.1385 @@ -2466,7 +2481,7 @@118.1386 } else {118.1387 sh4_x86.in_delay_slot = TRUE;118.1388 sh4_translate_instruction( pc + 2 );118.1389 - exit_block( disp + pc + 4, pc+4 );118.1390 + exit_block_rel( disp + pc + 4, pc+4 );118.1391 sh4_x86.branch_taken = TRUE;118.1392 return 4;118.1393 }118.1394 @@ -2482,7 +2497,7 @@118.1395 store_spreg( R_EAX, R_PR );118.1396 sh4_x86.in_delay_slot = TRUE;118.1397 sh4_translate_instruction( pc + 2 );118.1398 - exit_block( disp + pc + 4, pc+4 );118.1399 + exit_block_rel( disp + pc + 4, pc+4 );118.1400 sh4_x86.branch_taken = TRUE;118.1401 return 4;118.1402 }118.1403 @@ -2493,34 +2508,35 @@118.1404 case 0x0:118.1405 { /* MOV.B R0, @(disp, GBR) */118.1406 uint32_t disp = (ir&0xFF);118.1407 - load_reg( R_EAX, 0 );118.1408 - load_spreg( R_ECX, R_GBR );118.1409 - ADD_imm32_r32( disp, R_ECX );118.1410 - MEM_WRITE_BYTE( R_ECX, R_EAX );118.1411 + load_spreg( R_EAX, R_GBR );118.1412 + ADD_imm32_r32( disp, R_EAX );118.1413 + MMU_TRANSLATE_WRITE( R_EAX );118.1414 + load_reg( R_EDX, 0 );118.1415 + MEM_WRITE_BYTE( R_EAX, R_EDX );118.1416 sh4_x86.tstate = TSTATE_NONE;118.1417 }118.1418 break;118.1419 case 0x1:118.1420 { /* MOV.W R0, @(disp, GBR) */118.1421 uint32_t disp = (ir&0xFF)<<1;118.1422 - load_spreg( R_ECX, R_GBR );118.1423 - load_reg( R_EAX, 0 );118.1424 - ADD_imm32_r32( disp, R_ECX );118.1425 - precheck();118.1426 - check_walign16( R_ECX );118.1427 - MEM_WRITE_WORD( R_ECX, R_EAX );118.1428 + load_spreg( R_EAX, R_GBR );118.1429 + ADD_imm32_r32( disp, R_EAX );118.1430 + check_walign16( R_EAX );118.1431 + MMU_TRANSLATE_WRITE( R_EAX );118.1432 + load_reg( R_EDX, 0 );118.1433 + MEM_WRITE_WORD( R_EAX, R_EDX );118.1434 sh4_x86.tstate = TSTATE_NONE;118.1435 }118.1436 break;118.1437 case 0x2:118.1438 { /* MOV.L R0, @(disp, GBR) */118.1439 uint32_t disp = (ir&0xFF)<<2;118.1440 - load_spreg( R_ECX, R_GBR );118.1441 - load_reg( R_EAX, 0 );118.1442 - ADD_imm32_r32( disp, R_ECX );118.1443 - precheck();118.1444 - check_walign32( R_ECX );118.1445 - MEM_WRITE_LONG( R_ECX, R_EAX );118.1446 + load_spreg( R_EAX, R_GBR );118.1447 + ADD_imm32_r32( disp, R_EAX );118.1448 + check_walign32( R_EAX );118.1449 + MMU_TRANSLATE_WRITE( R_EAX );118.1450 + load_reg( R_EDX, 0 );118.1451 + MEM_WRITE_LONG( R_EAX, R_EDX );118.1452 sh4_x86.tstate = TSTATE_NONE;118.1453 }118.1454 break;118.1455 @@ -2544,9 +2560,10 @@118.1456 case 0x4:118.1457 { /* MOV.B @(disp, GBR), R0 */118.1458 uint32_t disp = (ir&0xFF);118.1459 - load_spreg( R_ECX, R_GBR );118.1460 - ADD_imm32_r32( disp, R_ECX );118.1461 - MEM_READ_BYTE( R_ECX, R_EAX );118.1462 + load_spreg( R_EAX, R_GBR );118.1463 + ADD_imm32_r32( disp, R_EAX );118.1464 + MMU_TRANSLATE_READ( R_EAX );118.1465 + MEM_READ_BYTE( R_EAX, R_EAX );118.1466 store_reg( R_EAX, 0 );118.1467 sh4_x86.tstate = TSTATE_NONE;118.1468 }118.1469 @@ -2554,11 +2571,11 @@118.1470 case 0x5:118.1471 { /* MOV.W @(disp, GBR), R0 */118.1472 uint32_t disp = (ir&0xFF)<<1;118.1473 - load_spreg( R_ECX, R_GBR );118.1474 - ADD_imm32_r32( disp, R_ECX );118.1475 - precheck();118.1476 - check_ralign16( R_ECX );118.1477 - MEM_READ_WORD( R_ECX, R_EAX );118.1478 + load_spreg( R_EAX, R_GBR );118.1479 + ADD_imm32_r32( disp, R_EAX );118.1480 + check_ralign16( R_EAX );118.1481 + MMU_TRANSLATE_READ( R_EAX );118.1482 + MEM_READ_WORD( R_EAX, R_EAX );118.1483 store_reg( R_EAX, 0 );118.1484 sh4_x86.tstate = TSTATE_NONE;118.1485 }118.1486 @@ -2566,11 +2583,11 @@118.1487 case 0x6:118.1488 { /* MOV.L @(disp, GBR), R0 */118.1489 uint32_t disp = (ir&0xFF)<<2;118.1490 - load_spreg( R_ECX, R_GBR );118.1491 - ADD_imm32_r32( disp, R_ECX );118.1492 - precheck();118.1493 - check_ralign32( R_ECX );118.1494 - MEM_READ_LONG( R_ECX, R_EAX );118.1495 + load_spreg( R_EAX, R_GBR );118.1496 + ADD_imm32_r32( disp, R_EAX );118.1497 + check_ralign32( R_EAX );118.1498 + MMU_TRANSLATE_READ( R_EAX );118.1499 + MEM_READ_LONG( R_EAX, R_EAX );118.1500 store_reg( R_EAX, 0 );118.1501 sh4_x86.tstate = TSTATE_NONE;118.1502 }118.1503 @@ -2581,8 +2598,10 @@118.1504 if( sh4_x86.in_delay_slot ) {118.1505 SLOTILLEGAL();118.1506 } else {118.1507 - load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );118.1508 + load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );118.1509 + ADD_sh4r_r32( R_PC, R_ECX );118.1510 store_reg( R_ECX, 0 );118.1511 + sh4_x86.tstate = TSTATE_NONE;118.1512 }118.1513 }118.1514 break;118.1515 @@ -2627,8 +2646,9 @@118.1516 uint32_t imm = (ir&0xFF);118.1517 load_reg( R_EAX, 0);118.1518 load_reg( R_ECX, R_GBR);118.1519 - ADD_r32_r32( R_EAX, R_ECX );118.1520 - MEM_READ_BYTE( R_ECX, R_EAX );118.1521 + ADD_r32_r32( R_ECX, R_EAX );118.1522 + MMU_TRANSLATE_READ( R_EAX );118.1523 + MEM_READ_BYTE( R_EAX, R_EAX );118.1524 TEST_imm8_r8( imm, R_AL );118.1525 SETE_t();118.1526 sh4_x86.tstate = TSTATE_E;118.1527 @@ -2639,9 +2659,10 @@118.1528 uint32_t imm = (ir&0xFF);118.1529 load_reg( R_EAX, 0 );118.1530 load_spreg( R_ECX, R_GBR );118.1531 - ADD_r32_r32( R_EAX, R_ECX );118.1532 - PUSH_realigned_r32(R_ECX);118.1533 - MEM_READ_BYTE( R_ECX, R_EAX );118.1534 + ADD_r32_r32( R_ECX, R_EAX );118.1535 + MMU_TRANSLATE_WRITE( R_EAX );118.1536 + PUSH_realigned_r32(R_EAX);118.1537 + MEM_READ_BYTE( R_EAX, R_EAX );118.1538 POP_realigned_r32(R_ECX);118.1539 AND_imm32_r32(imm, R_EAX );118.1540 MEM_WRITE_BYTE( R_ECX, R_EAX );118.1541 @@ -2653,9 +2674,10 @@118.1542 uint32_t imm = (ir&0xFF);118.1543 load_reg( R_EAX, 0 );118.1544 load_spreg( R_ECX, R_GBR );118.1545 - ADD_r32_r32( R_EAX, R_ECX );118.1546 - PUSH_realigned_r32(R_ECX);118.1547 - MEM_READ_BYTE(R_ECX, R_EAX);118.1548 + ADD_r32_r32( R_ECX, R_EAX );118.1549 + MMU_TRANSLATE_WRITE( R_EAX );118.1550 + PUSH_realigned_r32(R_EAX);118.1551 + MEM_READ_BYTE(R_EAX, R_EAX);118.1552 POP_realigned_r32(R_ECX);118.1553 XOR_imm32_r32( imm, R_EAX );118.1554 MEM_WRITE_BYTE( R_ECX, R_EAX );118.1555 @@ -2667,9 +2689,10 @@118.1556 uint32_t imm = (ir&0xFF);118.1557 load_reg( R_EAX, 0 );118.1558 load_spreg( R_ECX, R_GBR );118.1559 - ADD_r32_r32( R_EAX, R_ECX );118.1560 - PUSH_realigned_r32(R_ECX);118.1561 - MEM_READ_BYTE( R_ECX, R_EAX );118.1562 + ADD_r32_r32( R_ECX, R_EAX );118.1563 + MMU_TRANSLATE_WRITE( R_EAX );118.1564 + PUSH_realigned_r32(R_EAX);118.1565 + MEM_READ_BYTE( R_EAX, R_EAX );118.1566 POP_realigned_r32(R_ECX);118.1567 OR_imm32_r32(imm, R_EAX );118.1568 MEM_WRITE_BYTE( R_ECX, R_EAX );118.1569 @@ -2685,15 +2708,29 @@118.1570 SLOTILLEGAL();118.1571 } else {118.1572 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;118.1573 - sh4ptr_t ptr = mem_get_region(target);118.1574 - if( ptr != NULL ) {118.1575 + if( IS_IN_ICACHE(target) ) {118.1576 + // If the target address is in the same page as the code, it's118.1577 + // pretty safe to just ref it directly and circumvent the whole118.1578 + // memory subsystem. (this is a big performance win)118.1579 +118.1580 + // FIXME: There's a corner-case that's not handled here when118.1581 + // the current code-page is in the ITLB but not in the UTLB.118.1582 + // (should generate a TLB miss although need to test SH4118.1583 + // behaviour to confirm) Unlikely to be anyone depending on this118.1584 + // behaviour though.118.1585 + sh4ptr_t ptr = GET_ICACHE_PTR(target);118.1586 MOV_moff32_EAX( ptr );118.1587 } else {118.1588 - load_imm32( R_ECX, target );118.1589 - MEM_READ_LONG( R_ECX, R_EAX );118.1590 + // Note: we use sh4r.pc for the calc as we could be running at a118.1591 + // different virtual address than the translation was done with,118.1592 + // but we can safely assume that the low bits are the same.118.1593 + load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );118.1594 + ADD_sh4r_r32( R_PC, R_EAX );118.1595 + MMU_TRANSLATE_READ( R_EAX );118.1596 + MEM_READ_LONG( R_EAX, R_EAX );118.1597 + sh4_x86.tstate = TSTATE_NONE;118.1598 }118.1599 store_reg( R_EAX, Rn );118.1600 - sh4_x86.tstate = TSTATE_NONE;118.1601 }118.1602 }118.1603 break;118.1604 @@ -2839,33 +2876,33 @@118.1605 case 0x6:118.1606 { /* FMOV @(R0, Rm), FRn */118.1607 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1608 - precheck();118.1609 - check_fpuen_no_precheck();118.1610 - load_reg( R_ECX, Rm );118.1611 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );118.1612 - check_ralign32( R_ECX );118.1613 + check_fpuen();118.1614 + load_reg( R_EAX, Rm );118.1615 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );118.1616 + check_ralign32( R_EAX );118.1617 + MMU_TRANSLATE_READ( R_EAX );118.1618 load_spreg( R_EDX, R_FPSCR );118.1619 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1620 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);118.1621 - MEM_READ_LONG( R_ECX, R_EAX );118.1622 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);118.1623 + MEM_READ_LONG( R_EAX, R_EAX );118.1624 load_fr_bank( R_EDX );118.1625 store_fr( R_EDX, R_EAX, FRn );118.1626 if( FRn&1 ) {118.1627 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);118.1628 JMP_TARGET(doublesize);118.1629 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1630 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1631 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it118.1632 load_xf_bank( R_EDX );118.1633 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1634 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1635 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1636 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1637 JMP_TARGET(end);118.1638 } else {118.1639 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);118.1640 JMP_TARGET(doublesize);118.1641 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1642 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1643 load_fr_bank( R_EDX );118.1644 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1645 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1646 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1647 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1648 JMP_TARGET(end);118.1649 }118.1650 sh4_x86.tstate = TSTATE_NONE;118.1651 @@ -2874,32 +2911,32 @@118.1652 case 0x7:118.1653 { /* FMOV FRm, @(R0, Rn) */118.1654 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);118.1655 - precheck();118.1656 - check_fpuen_no_precheck();118.1657 - load_reg( R_ECX, Rn );118.1658 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );118.1659 - check_walign32( R_ECX );118.1660 + check_fpuen();118.1661 + load_reg( R_EAX, Rn );118.1662 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );118.1663 + check_walign32( R_EAX );118.1664 + MMU_TRANSLATE_WRITE( R_EAX );118.1665 load_spreg( R_EDX, R_FPSCR );118.1666 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1667 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);118.1668 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);118.1669 load_fr_bank( R_EDX );118.1670 - load_fr( R_EDX, R_EAX, FRm );118.1671 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12118.1672 + load_fr( R_EDX, R_ECX, FRm );118.1673 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12118.1674 if( FRm&1 ) {118.1675 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );118.1676 JMP_TARGET(doublesize);118.1677 load_xf_bank( R_EDX );118.1678 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1679 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1680 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1681 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1682 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1683 JMP_TARGET(end);118.1684 } else {118.1685 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );118.1686 JMP_TARGET(doublesize);118.1687 load_fr_bank( R_EDX );118.1688 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1689 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1690 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1691 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1692 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1693 JMP_TARGET(end);118.1694 }118.1695 sh4_x86.tstate = TSTATE_NONE;118.1696 @@ -2908,32 +2945,32 @@118.1697 case 0x8:118.1698 { /* FMOV @Rm, FRn */118.1699 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1700 - precheck();118.1701 - check_fpuen_no_precheck();118.1702 - load_reg( R_ECX, Rm );118.1703 - check_ralign32( R_ECX );118.1704 + check_fpuen();118.1705 + load_reg( R_EAX, Rm );118.1706 + check_ralign32( R_EAX );118.1707 + MMU_TRANSLATE_READ( R_EAX );118.1708 load_spreg( R_EDX, R_FPSCR );118.1709 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1710 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);118.1711 - MEM_READ_LONG( R_ECX, R_EAX );118.1712 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);118.1713 + MEM_READ_LONG( R_EAX, R_EAX );118.1714 load_fr_bank( R_EDX );118.1715 store_fr( R_EDX, R_EAX, FRn );118.1716 if( FRn&1 ) {118.1717 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);118.1718 JMP_TARGET(doublesize);118.1719 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1720 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1721 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it118.1722 load_xf_bank( R_EDX );118.1723 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1724 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1725 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1726 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1727 JMP_TARGET(end);118.1728 } else {118.1729 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);118.1730 JMP_TARGET(doublesize);118.1731 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1732 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1733 load_fr_bank( R_EDX );118.1734 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1735 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1736 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1737 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1738 JMP_TARGET(end);118.1739 }118.1740 sh4_x86.tstate = TSTATE_NONE;118.1741 @@ -2942,38 +2979,34 @@118.1742 case 0x9:118.1743 { /* FMOV @Rm+, FRn */118.1744 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);118.1745 - precheck();118.1746 - check_fpuen_no_precheck();118.1747 - load_reg( R_ECX, Rm );118.1748 - check_ralign32( R_ECX );118.1749 - MOV_r32_r32( R_ECX, R_EAX );118.1750 + check_fpuen();118.1751 + load_reg( R_EAX, Rm );118.1752 + check_ralign32( R_EAX );118.1753 + MMU_TRANSLATE_READ( R_EAX );118.1754 load_spreg( R_EDX, R_FPSCR );118.1755 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1756 - JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);118.1757 - ADD_imm8s_r32( 4, R_EAX );118.1758 - store_reg( R_EAX, Rm );118.1759 - MEM_READ_LONG( R_ECX, R_EAX );118.1760 + JNE_rel8(12 + MEM_READ_SIZE, doublesize);118.1761 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );118.1762 + MEM_READ_LONG( R_EAX, R_EAX );118.1763 load_fr_bank( R_EDX );118.1764 store_fr( R_EDX, R_EAX, FRn );118.1765 if( FRn&1 ) {118.1766 - JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);118.1767 + JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);118.1768 JMP_TARGET(doublesize);118.1769 - ADD_imm8s_r32( 8, R_EAX );118.1770 - store_reg(R_EAX, Rm);118.1771 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1772 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );118.1773 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1774 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it118.1775 load_xf_bank( R_EDX );118.1776 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1777 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1778 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1779 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1780 JMP_TARGET(end);118.1781 } else {118.1782 - JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);118.1783 - ADD_imm8s_r32( 8, R_EAX );118.1784 - store_reg(R_EAX, Rm);118.1785 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );118.1786 + JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);118.1787 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );118.1788 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );118.1789 load_fr_bank( R_EDX );118.1790 - store_fr( R_EDX, R_EAX, FRn&0x0E );118.1791 - store_fr( R_EDX, R_ECX, FRn|0x01 );118.1792 + store_fr( R_EDX, R_ECX, FRn&0x0E );118.1793 + store_fr( R_EDX, R_EAX, FRn|0x01 );118.1794 JMP_TARGET(end);118.1795 }118.1796 sh4_x86.tstate = TSTATE_NONE;118.1797 @@ -2982,31 +3015,31 @@118.1798 case 0xA:118.1799 { /* FMOV FRm, @Rn */118.1800 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);118.1801 - precheck();118.1802 - check_fpuen_no_precheck();118.1803 - load_reg( R_ECX, Rn );118.1804 - check_walign32( R_ECX );118.1805 + check_fpuen();118.1806 + load_reg( R_EAX, Rn );118.1807 + check_walign32( R_EAX );118.1808 + MMU_TRANSLATE_WRITE( R_EAX );118.1809 load_spreg( R_EDX, R_FPSCR );118.1810 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1811 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);118.1812 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);118.1813 load_fr_bank( R_EDX );118.1814 - load_fr( R_EDX, R_EAX, FRm );118.1815 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12118.1816 + load_fr( R_EDX, R_ECX, FRm );118.1817 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12118.1818 if( FRm&1 ) {118.1819 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );118.1820 JMP_TARGET(doublesize);118.1821 load_xf_bank( R_EDX );118.1822 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1823 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1824 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1825 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1826 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1827 JMP_TARGET(end);118.1828 } else {118.1829 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );118.1830 JMP_TARGET(doublesize);118.1831 load_fr_bank( R_EDX );118.1832 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1833 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1834 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1835 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1836 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1837 JMP_TARGET(end);118.1838 }118.1839 sh4_x86.tstate = TSTATE_NONE;118.1840 @@ -3015,37 +3048,39 @@118.1841 case 0xB:118.1842 { /* FMOV FRm, @-Rn */118.1843 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);118.1844 - precheck();118.1845 - check_fpuen_no_precheck();118.1846 - load_reg( R_ECX, Rn );118.1847 - check_walign32( R_ECX );118.1848 + check_fpuen();118.1849 + load_reg( R_EAX, Rn );118.1850 + check_walign32( R_EAX );118.1851 load_spreg( R_EDX, R_FPSCR );118.1852 TEST_imm32_r32( FPSCR_SZ, R_EDX );118.1853 - JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);118.1854 + JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);118.1855 + ADD_imm8s_r32( -4, R_EAX );118.1856 + MMU_TRANSLATE_WRITE( R_EAX );118.1857 load_fr_bank( R_EDX );118.1858 - load_fr( R_EDX, R_EAX, FRm );118.1859 - ADD_imm8s_r32(-4,R_ECX);118.1860 - store_reg( R_ECX, Rn );118.1861 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12118.1862 + load_fr( R_EDX, R_ECX, FRm );118.1863 + ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));118.1864 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12118.1865 if( FRm&1 ) {118.1866 - JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );118.1867 + JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );118.1868 JMP_TARGET(doublesize);118.1869 + ADD_imm8s_r32(-8,R_EAX);118.1870 + MMU_TRANSLATE_WRITE( R_EAX );118.1871 load_xf_bank( R_EDX );118.1872 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1873 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1874 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1875 - ADD_imm8s_r32(-8,R_ECX);118.1876 - store_reg( R_ECX, Rn );118.1877 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1878 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));118.1879 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1880 JMP_TARGET(end);118.1881 } else {118.1882 - JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );118.1883 + JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );118.1884 JMP_TARGET(doublesize);118.1885 + ADD_imm8s_r32(-8,R_EAX);118.1886 + MMU_TRANSLATE_WRITE( R_EAX );118.1887 load_fr_bank( R_EDX );118.1888 - load_fr( R_EDX, R_EAX, FRm&0x0E );118.1889 + load_fr( R_EDX, R_ECX, FRm&0x0E );118.1890 load_fr( R_EDX, R_EDX, FRm|0x01 );118.1891 - ADD_imm8s_r32(-8,R_ECX);118.1892 - store_reg( R_ECX, Rn );118.1893 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );118.1894 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));118.1895 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );118.1896 JMP_TARGET(end);118.1897 }118.1898 sh4_x86.tstate = TSTATE_NONE;118.1899 @@ -3405,8 +3440,7 @@118.1900 if( sh4_x86.in_delay_slot ) {118.1901 SLOTILLEGAL();118.1902 } else {118.1903 - precheck();118.1904 - JMP_exit(EXIT_ILLEGAL);118.1905 + JMP_exc(EXC_ILLEGAL);118.1906 return 2;118.1907 }118.1908 }
119.1 --- a/src/sh4/sh4x86.in Thu Dec 20 09:56:07 2007 +0000119.2 +++ b/src/sh4/sh4x86.in Tue Jan 15 20:50:23 2008 +0000119.3 @@ -1,5 +1,5 @@119.4 /**119.5 - * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $119.6 + * $Id$119.7 *119.8 * SH4 => x86 translation. This version does no real optimization, it just119.9 * outputs straight-line x86 code - it mainly exists to provide a baseline119.10 @@ -34,6 +34,14 @@119.12 #define DEFAULT_BACKPATCH_SIZE 4096119.14 +struct backpatch_record {119.15 + uint32_t *fixup_addr;119.16 + uint32_t fixup_icount;119.17 + uint32_t exc_code;119.18 +};119.19 +119.20 +#define MAX_RECOVERY_SIZE 2048119.21 +119.22 /**119.23 * Struct to manage internal translation state. This state is not saved -119.24 * it is only valid between calls to sh4_translate_begin_block() and119.25 @@ -48,10 +56,15 @@119.26 uint32_t stack_posn; /* Trace stack height for alignment purposes */119.27 int tstate;119.29 + /* mode flags */119.30 + gboolean tlb_on; /* True if tlb translation is active */119.31 +119.32 /* Allocated memory for the (block-wide) back-patch list */119.33 - uint32_t **backpatch_list;119.34 + struct backpatch_record *backpatch_list;119.35 uint32_t backpatch_posn;119.36 uint32_t backpatch_size;119.37 + struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];119.38 + uint32_t recovery_posn;119.39 };119.41 #define TSTATE_NONE -1119.42 @@ -75,14 +88,6 @@119.43 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \119.44 MARK_JMP(rel8, label)119.46 -119.47 -#define EXIT_DATA_ADDR_READ 0119.48 -#define EXIT_DATA_ADDR_WRITE 7119.49 -#define EXIT_ILLEGAL 14119.50 -#define EXIT_SLOT_ILLEGAL 21119.51 -#define EXIT_FPU_DISABLED 28119.52 -#define EXIT_SLOT_FPU_DISABLED 35119.53 -119.54 static struct sh4_x86_state sh4_x86;119.56 static uint32_t max_int = 0x7FFFFFFF;119.57 @@ -93,26 +98,32 @@119.58 void sh4_x86_init()119.59 {119.60 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);119.61 - sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);119.62 + sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);119.63 }119.66 -static void sh4_x86_add_backpatch( uint8_t *ptr )119.67 +static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )119.68 {119.69 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {119.70 sh4_x86.backpatch_size <<= 1;119.71 - sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );119.72 + sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,119.73 + sh4_x86.backpatch_size * sizeof(struct backpatch_record));119.74 assert( sh4_x86.backpatch_list != NULL );119.75 }119.76 - sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;119.77 + if( sh4_x86.in_delay_slot ) {119.78 + fixup_pc -= 2;119.79 + }119.80 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;119.81 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;119.82 + sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;119.83 + sh4_x86.backpatch_posn++;119.84 }119.86 -static void sh4_x86_do_backpatch( uint8_t *reloc_base )119.87 +void sh4_x86_add_recovery( uint32_t pc )119.88 {119.89 - unsigned int i;119.90 - for( i=0; i<sh4_x86.backpatch_posn; i++ ) {119.91 - *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);119.92 - }119.93 + xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;119.94 + xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;119.95 + xlat_recovery_posn++;119.96 }119.98 /**119.99 @@ -266,86 +277,46 @@119.100 }119.102 /* Exception checks - Note that all exception checks will clobber EAX */119.103 -#define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)119.105 #define check_priv( ) \119.106 if( !sh4_x86.priv_checked ) { \119.107 sh4_x86.priv_checked = TRUE;\119.108 - precheck();\119.109 load_spreg( R_EAX, R_SR );\119.110 AND_imm32_r32( SR_MD, R_EAX );\119.111 if( sh4_x86.in_delay_slot ) {\119.112 - JE_exit( EXIT_SLOT_ILLEGAL );\119.113 + JE_exc( EXC_SLOT_ILLEGAL );\119.114 } else {\119.115 - JE_exit( EXIT_ILLEGAL );\119.116 + JE_exc( EXC_ILLEGAL );\119.117 }\119.118 }\119.120 -119.121 -static void check_priv_no_precheck()119.122 -{119.123 - if( !sh4_x86.priv_checked ) {119.124 - sh4_x86.priv_checked = TRUE;119.125 - load_spreg( R_EAX, R_SR );119.126 - AND_imm32_r32( SR_MD, R_EAX );119.127 - if( sh4_x86.in_delay_slot ) {119.128 - JE_exit( EXIT_SLOT_ILLEGAL );119.129 - } else {119.130 - JE_exit( EXIT_ILLEGAL );119.131 - }119.132 - }119.133 -}119.134 -119.135 #define check_fpuen( ) \119.136 if( !sh4_x86.fpuen_checked ) {\119.137 sh4_x86.fpuen_checked = TRUE;\119.138 - precheck();\119.139 load_spreg( R_EAX, R_SR );\119.140 AND_imm32_r32( SR_FD, R_EAX );\119.141 if( sh4_x86.in_delay_slot ) {\119.142 - JNE_exit(EXIT_SLOT_FPU_DISABLED);\119.143 + JNE_exc(EXC_SLOT_FPU_DISABLED);\119.144 } else {\119.145 - JNE_exit(EXIT_FPU_DISABLED);\119.146 + JNE_exc(EXC_FPU_DISABLED);\119.147 }\119.148 }119.150 -static void check_fpuen_no_precheck()119.151 -{119.152 - if( !sh4_x86.fpuen_checked ) {119.153 - sh4_x86.fpuen_checked = TRUE;119.154 - load_spreg( R_EAX, R_SR );119.155 - AND_imm32_r32( SR_FD, R_EAX );119.156 - if( sh4_x86.in_delay_slot ) {119.157 - JNE_exit(EXIT_SLOT_FPU_DISABLED);119.158 - } else {119.159 - JNE_exit(EXIT_FPU_DISABLED);119.160 - }119.161 - }119.162 +#define check_ralign16( x86reg ) \119.163 + TEST_imm32_r32( 0x00000001, x86reg ); \119.164 + JNE_exc(EXC_DATA_ADDR_READ)119.166 -}119.167 +#define check_walign16( x86reg ) \119.168 + TEST_imm32_r32( 0x00000001, x86reg ); \119.169 + JNE_exc(EXC_DATA_ADDR_WRITE);119.171 -static void check_ralign16( int x86reg )119.172 -{119.173 - TEST_imm32_r32( 0x00000001, x86reg );119.174 - JNE_exit(EXIT_DATA_ADDR_READ);119.175 -}119.176 +#define check_ralign32( x86reg ) \119.177 + TEST_imm32_r32( 0x00000003, x86reg ); \119.178 + JNE_exc(EXC_DATA_ADDR_READ)119.180 -static void check_walign16( int x86reg )119.181 -{119.182 - TEST_imm32_r32( 0x00000001, x86reg );119.183 - JNE_exit(EXIT_DATA_ADDR_WRITE);119.184 -}119.185 -119.186 -static void check_ralign32( int x86reg )119.187 -{119.188 - TEST_imm32_r32( 0x00000003, x86reg );119.189 - JNE_exit(EXIT_DATA_ADDR_READ);119.190 -}119.191 -static void check_walign32( int x86reg )119.192 -{119.193 - TEST_imm32_r32( 0x00000003, x86reg );119.194 - JNE_exit(EXIT_DATA_ADDR_WRITE);119.195 -}119.196 +#define check_walign32( x86reg ) \119.197 + TEST_imm32_r32( 0x00000003, x86reg ); \119.198 + JNE_exc(EXC_DATA_ADDR_WRITE);119.200 #define UNDEF()119.201 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }119.202 @@ -356,10 +327,22 @@119.203 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)119.204 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)119.206 -#define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;119.207 +/**119.208 + * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned119.209 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.119.210 + */119.211 +#define MMU_TRANSLATE_READ( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }119.212 +/**119.213 + * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned119.214 + * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.119.215 + */119.216 +#define MMU_TRANSLATE_WRITE( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }119.218 -extern uint16_t *sh4_icache;119.219 -extern uint32_t sh4_icache_addr;119.220 +#define MEM_READ_SIZE (CALL_FUNC1_SIZE)119.221 +#define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)119.222 +#define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )119.223 +119.224 +#define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;119.226 /****** Import appropriate calling conventions ******/119.227 #if SH4_TRANSLATOR == TARGET_X86_64119.228 @@ -372,11 +355,18 @@119.229 #endif119.230 #endif119.232 +void sh4_translate_emit_breakpoint( sh4vma_t pc )119.233 +{119.234 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );119.235 + call_func1( sh4_translate_exit, R_EAX );119.236 +}119.237 +119.239 /**119.240 * Translate a single instruction. Delayed branches are handled specially119.241 * by translating both branch and delayed instruction as a single unit (as119.242 *119.243 + * The instruction MUST be in the icache (assert check)119.244 *119.245 * @return true if the instruction marks the end of a basic block119.246 * (eg a branch or119.247 @@ -384,24 +374,23 @@119.248 uint32_t sh4_translate_instruction( sh4addr_t pc )119.249 {119.250 uint32_t ir;119.251 - /* Read instruction */119.252 - uint32_t pageaddr = pc >> 12;119.253 - if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {119.254 - ir = sh4_icache[(pc&0xFFF)>>1];119.255 - } else {119.256 - sh4_icache = (uint16_t *)mem_get_page(pc);119.257 - if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {119.258 - /* If someone's actually been so daft as to try to execute out of an IO119.259 - * region, fallback on the full-blown memory read119.260 - */119.261 - sh4_icache = NULL;119.262 - ir = sh4_read_word(pc);119.263 - } else {119.264 - sh4_icache_addr = pageaddr;119.265 - ir = sh4_icache[(pc&0xFFF)>>1];119.266 - }119.267 + /* Read instruction from icache */119.268 + assert( IS_IN_ICACHE(pc) );119.269 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);119.270 +119.271 + /* PC is not in the current icache - this usually means we're running119.272 + * with MMU on, and we've gone past the end of the page. And since119.273 + * sh4_translate_block is pretty careful about this, it means we're119.274 + * almost certainly in a delay slot.119.275 + *119.276 + * Since we can't assume the page is present (and we can't fault it in119.277 + * at this point, inline a call to sh4_execute_instruction (with a few119.278 + * small repairs to cope with the different environment).119.279 + */119.280 +119.281 + if( !sh4_x86.in_delay_slot ) {119.282 + sh4_x86_add_recovery(pc);119.283 }119.284 -119.285 %%119.286 /* ALU operations */119.287 ADD Rm, Rn {:119.288 @@ -452,9 +441,10 @@119.289 AND.B #imm, @(R0, GBR) {:119.290 load_reg( R_EAX, 0 );119.291 load_spreg( R_ECX, R_GBR );119.292 - ADD_r32_r32( R_EAX, R_ECX );119.293 - PUSH_realigned_r32(R_ECX);119.294 - MEM_READ_BYTE( R_ECX, R_EAX );119.295 + ADD_r32_r32( R_ECX, R_EAX );119.296 + MMU_TRANSLATE_WRITE( R_EAX );119.297 + PUSH_realigned_r32(R_EAX);119.298 + MEM_READ_BYTE( R_EAX, R_EAX );119.299 POP_realigned_r32(R_ECX);119.300 AND_imm32_r32(imm, R_EAX );119.301 MEM_WRITE_BYTE( R_ECX, R_EAX );119.302 @@ -617,19 +607,35 @@119.303 MOVZX_r16_r32( R_EAX, R_EAX );119.304 store_reg( R_EAX, Rn );119.305 :}119.306 -MAC.L @Rm+, @Rn+ {:119.307 - load_reg( R_ECX, Rm );119.308 - precheck();119.309 - check_ralign32( R_ECX );119.310 - load_reg( R_ECX, Rn );119.311 - check_ralign32( R_ECX );119.312 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );119.313 - MEM_READ_LONG( R_ECX, R_EAX );119.314 - PUSH_realigned_r32( R_EAX );119.315 - load_reg( R_ECX, Rm );119.316 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.317 +MAC.L @Rm+, @Rn+ {:119.318 + if( Rm == Rn ) {119.319 + load_reg( R_EAX, Rm );119.320 + check_ralign32( R_EAX );119.321 + MMU_TRANSLATE_READ( R_EAX );119.322 + PUSH_realigned_r32( R_EAX );119.323 + load_reg( R_EAX, Rn );119.324 + ADD_imm8s_r32( 4, R_EAX );119.325 + MMU_TRANSLATE_READ( R_EAX );119.326 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );119.327 + // Note translate twice in case of page boundaries. Maybe worth119.328 + // adding a page-boundary check to skip the second translation119.329 + } else {119.330 + load_reg( R_EAX, Rm );119.331 + check_ralign32( R_EAX );119.332 + MMU_TRANSLATE_READ( R_EAX );119.333 + PUSH_realigned_r32( R_EAX );119.334 + load_reg( R_EAX, Rn );119.335 + check_ralign32( R_EAX );119.336 + MMU_TRANSLATE_READ( R_EAX );119.337 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );119.338 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.339 + }119.340 + MEM_READ_LONG( R_EAX, R_EAX );119.341 + POP_r32( R_ECX );119.342 + PUSH_r32( R_EAX );119.343 MEM_READ_LONG( R_ECX, R_EAX );119.344 POP_realigned_r32( R_ECX );119.345 +119.346 IMUL_r32( R_ECX );119.347 ADD_r32_sh4r( R_EAX, R_MACL );119.348 ADC_r32_sh4r( R_EDX, R_MACH );119.349 @@ -642,16 +648,31 @@119.350 sh4_x86.tstate = TSTATE_NONE;119.351 :}119.352 MAC.W @Rm+, @Rn+ {:119.353 - load_reg( R_ECX, Rm );119.354 - precheck();119.355 - check_ralign16( R_ECX );119.356 - load_reg( R_ECX, Rn );119.357 - check_ralign16( R_ECX );119.358 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );119.359 - MEM_READ_WORD( R_ECX, R_EAX );119.360 - PUSH_realigned_r32( R_EAX );119.361 - load_reg( R_ECX, Rm );119.362 - ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );119.363 + if( Rm == Rn ) {119.364 + load_reg( R_EAX, Rm );119.365 + check_ralign16( R_EAX );119.366 + MMU_TRANSLATE_READ( R_EAX );119.367 + PUSH_realigned_r32( R_EAX );119.368 + load_reg( R_EAX, Rn );119.369 + ADD_imm8s_r32( 2, R_EAX );119.370 + MMU_TRANSLATE_READ( R_EAX );119.371 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );119.372 + // Note translate twice in case of page boundaries. Maybe worth119.373 + // adding a page-boundary check to skip the second translation119.374 + } else {119.375 + load_reg( R_EAX, Rm );119.376 + check_ralign16( R_EAX );119.377 + MMU_TRANSLATE_READ( R_EAX );119.378 + PUSH_realigned_r32( R_EAX );119.379 + load_reg( R_EAX, Rn );119.380 + check_ralign16( R_EAX );119.381 + MMU_TRANSLATE_READ( R_EAX );119.382 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );119.383 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );119.384 + }119.385 + MEM_READ_WORD( R_EAX, R_EAX );119.386 + POP_r32( R_ECX );119.387 + PUSH_r32( R_EAX );119.388 MEM_READ_WORD( R_ECX, R_EAX );119.389 POP_realigned_r32( R_ECX );119.390 IMUL_r32( R_ECX );119.391 @@ -744,9 +765,10 @@119.392 OR.B #imm, @(R0, GBR) {:119.393 load_reg( R_EAX, 0 );119.394 load_spreg( R_ECX, R_GBR );119.395 - ADD_r32_r32( R_EAX, R_ECX );119.396 - PUSH_realigned_r32(R_ECX);119.397 - MEM_READ_BYTE( R_ECX, R_EAX );119.398 + ADD_r32_r32( R_ECX, R_EAX );119.399 + MMU_TRANSLATE_WRITE( R_EAX );119.400 + PUSH_realigned_r32(R_EAX);119.401 + MEM_READ_BYTE( R_EAX, R_EAX );119.402 POP_realigned_r32(R_ECX);119.403 OR_imm32_r32(imm, R_EAX );119.404 MEM_WRITE_BYTE( R_ECX, R_EAX );119.405 @@ -940,12 +962,14 @@119.406 sh4_x86.tstate = TSTATE_NONE;119.407 :}119.408 TAS.B @Rn {:119.409 - load_reg( R_ECX, Rn );119.410 - MEM_READ_BYTE( R_ECX, R_EAX );119.411 + load_reg( R_EAX, Rn );119.412 + MMU_TRANSLATE_WRITE( R_EAX );119.413 + PUSH_realigned_r32( R_EAX );119.414 + MEM_READ_BYTE( R_EAX, R_EAX );119.415 TEST_r8_r8( R_AL, R_AL );119.416 SETE_t();119.417 OR_imm8_r8( 0x80, R_AL );119.418 - load_reg( R_ECX, Rn );119.419 + POP_realigned_r32( R_ECX );119.420 MEM_WRITE_BYTE( R_ECX, R_EAX );119.421 sh4_x86.tstate = TSTATE_NONE;119.422 :}119.423 @@ -965,8 +989,9 @@119.424 TST.B #imm, @(R0, GBR) {:119.425 load_reg( R_EAX, 0);119.426 load_reg( R_ECX, R_GBR);119.427 - ADD_r32_r32( R_EAX, R_ECX );119.428 - MEM_READ_BYTE( R_ECX, R_EAX );119.429 + ADD_r32_r32( R_ECX, R_EAX );119.430 + MMU_TRANSLATE_READ( R_EAX );119.431 + MEM_READ_BYTE( R_EAX, R_EAX );119.432 TEST_imm8_r8( imm, R_AL );119.433 SETE_t();119.434 sh4_x86.tstate = TSTATE_E;119.435 @@ -987,9 +1012,10 @@119.436 XOR.B #imm, @(R0, GBR) {:119.437 load_reg( R_EAX, 0 );119.438 load_spreg( R_ECX, R_GBR );119.439 - ADD_r32_r32( R_EAX, R_ECX );119.440 - PUSH_realigned_r32(R_ECX);119.441 - MEM_READ_BYTE(R_ECX, R_EAX);119.442 + ADD_r32_r32( R_ECX, R_EAX );119.443 + MMU_TRANSLATE_WRITE( R_EAX );119.444 + PUSH_realigned_r32(R_EAX);119.445 + MEM_READ_BYTE(R_EAX, R_EAX);119.446 POP_realigned_r32(R_ECX);119.447 XOR_imm32_r32( imm, R_EAX );119.448 MEM_WRITE_BYTE( R_ECX, R_EAX );119.449 @@ -1015,159 +1041,165 @@119.450 store_reg( R_EAX, Rn );119.451 :}119.452 MOV.B Rm, @Rn {:119.453 - load_reg( R_EAX, Rm );119.454 - load_reg( R_ECX, Rn );119.455 - MEM_WRITE_BYTE( R_ECX, R_EAX );119.456 + load_reg( R_EAX, Rn );119.457 + MMU_TRANSLATE_WRITE( R_EAX );119.458 + load_reg( R_EDX, Rm );119.459 + MEM_WRITE_BYTE( R_EAX, R_EDX );119.460 sh4_x86.tstate = TSTATE_NONE;119.461 :}119.462 MOV.B Rm, @-Rn {:119.463 - load_reg( R_EAX, Rm );119.464 - load_reg( R_ECX, Rn );119.465 - ADD_imm8s_r32( -1, R_ECX );119.466 - store_reg( R_ECX, Rn );119.467 - MEM_WRITE_BYTE( R_ECX, R_EAX );119.468 + load_reg( R_EAX, Rn );119.469 + ADD_imm8s_r32( -1, R_EAX );119.470 + MMU_TRANSLATE_WRITE( R_EAX );119.471 + load_reg( R_EDX, Rm );119.472 + ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );119.473 + MEM_WRITE_BYTE( R_EAX, R_EDX );119.474 sh4_x86.tstate = TSTATE_NONE;119.475 :}119.476 MOV.B Rm, @(R0, Rn) {:119.477 load_reg( R_EAX, 0 );119.478 load_reg( R_ECX, Rn );119.479 - ADD_r32_r32( R_EAX, R_ECX );119.480 - load_reg( R_EAX, Rm );119.481 - MEM_WRITE_BYTE( R_ECX, R_EAX );119.482 + ADD_r32_r32( R_ECX, R_EAX );119.483 + MMU_TRANSLATE_WRITE( R_EAX );119.484 + load_reg( R_EDX, Rm );119.485 + MEM_WRITE_BYTE( R_EAX, R_EDX );119.486 sh4_x86.tstate = TSTATE_NONE;119.487 :}119.488 MOV.B R0, @(disp, GBR) {:119.489 - load_reg( R_EAX, 0 );119.490 - load_spreg( R_ECX, R_GBR );119.491 - ADD_imm32_r32( disp, R_ECX );119.492 - MEM_WRITE_BYTE( R_ECX, R_EAX );119.493 + load_spreg( R_EAX, R_GBR );119.494 + ADD_imm32_r32( disp, R_EAX );119.495 + MMU_TRANSLATE_WRITE( R_EAX );119.496 + load_reg( R_EDX, 0 );119.497 + MEM_WRITE_BYTE( R_EAX, R_EDX );119.498 sh4_x86.tstate = TSTATE_NONE;119.499 :}119.500 MOV.B R0, @(disp, Rn) {:119.501 - load_reg( R_EAX, 0 );119.502 - load_reg( R_ECX, Rn );119.503 - ADD_imm32_r32( disp, R_ECX );119.504 - MEM_WRITE_BYTE( R_ECX, R_EAX );119.505 + load_reg( R_EAX, Rn );119.506 + ADD_imm32_r32( disp, R_EAX );119.507 + MMU_TRANSLATE_WRITE( R_EAX );119.508 + load_reg( R_EDX, 0 );119.509 + MEM_WRITE_BYTE( R_EAX, R_EDX );119.510 sh4_x86.tstate = TSTATE_NONE;119.511 :}119.512 MOV.B @Rm, Rn {:119.513 - load_reg( R_ECX, Rm );119.514 - MEM_READ_BYTE( R_ECX, R_EAX );119.515 + load_reg( R_EAX, Rm );119.516 + MMU_TRANSLATE_READ( R_EAX );119.517 + MEM_READ_BYTE( R_EAX, R_EAX );119.518 store_reg( R_EAX, Rn );119.519 sh4_x86.tstate = TSTATE_NONE;119.520 :}119.521 MOV.B @Rm+, Rn {:119.522 - load_reg( R_ECX, Rm );119.523 - MOV_r32_r32( R_ECX, R_EAX );119.524 - ADD_imm8s_r32( 1, R_EAX );119.525 - store_reg( R_EAX, Rm );119.526 - MEM_READ_BYTE( R_ECX, R_EAX );119.527 + load_reg( R_EAX, Rm );119.528 + MMU_TRANSLATE_READ( R_EAX );119.529 + ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );119.530 + MEM_READ_BYTE( R_EAX, R_EAX );119.531 store_reg( R_EAX, Rn );119.532 sh4_x86.tstate = TSTATE_NONE;119.533 :}119.534 MOV.B @(R0, Rm), Rn {:119.535 load_reg( R_EAX, 0 );119.536 load_reg( R_ECX, Rm );119.537 - ADD_r32_r32( R_EAX, R_ECX );119.538 - MEM_READ_BYTE( R_ECX, R_EAX );119.539 + ADD_r32_r32( R_ECX, R_EAX );119.540 + MMU_TRANSLATE_READ( R_EAX )119.541 + MEM_READ_BYTE( R_EAX, R_EAX );119.542 store_reg( R_EAX, Rn );119.543 sh4_x86.tstate = TSTATE_NONE;119.544 :}119.545 MOV.B @(disp, GBR), R0 {:119.546 - load_spreg( R_ECX, R_GBR );119.547 - ADD_imm32_r32( disp, R_ECX );119.548 - MEM_READ_BYTE( R_ECX, R_EAX );119.549 + load_spreg( R_EAX, R_GBR );119.550 + ADD_imm32_r32( disp, R_EAX );119.551 + MMU_TRANSLATE_READ( R_EAX );119.552 + MEM_READ_BYTE( R_EAX, R_EAX );119.553 store_reg( R_EAX, 0 );119.554 sh4_x86.tstate = TSTATE_NONE;119.555 :}119.556 MOV.B @(disp, Rm), R0 {:119.557 - load_reg( R_ECX, Rm );119.558 - ADD_imm32_r32( disp, R_ECX );119.559 - MEM_READ_BYTE( R_ECX, R_EAX );119.560 + load_reg( R_EAX, Rm );119.561 + ADD_imm32_r32( disp, R_EAX );119.562 + MMU_TRANSLATE_READ( R_EAX );119.563 + MEM_READ_BYTE( R_EAX, R_EAX );119.564 store_reg( R_EAX, 0 );119.565 sh4_x86.tstate = TSTATE_NONE;119.566 :}119.567 MOV.L Rm, @Rn {:119.568 - load_reg( R_EAX, Rm );119.569 - load_reg( R_ECX, Rn );119.570 - precheck();119.571 - check_walign32(R_ECX);119.572 - MEM_WRITE_LONG( R_ECX, R_EAX );119.573 + load_reg( R_EAX, Rn );119.574 + check_walign32(R_EAX);119.575 + MMU_TRANSLATE_WRITE( R_EAX );119.576 + load_reg( R_EDX, Rm );119.577 + MEM_WRITE_LONG( R_EAX, R_EDX );119.578 sh4_x86.tstate = TSTATE_NONE;119.579 :}119.580 MOV.L Rm, @-Rn {:119.581 - load_reg( R_EAX, Rm );119.582 - load_reg( R_ECX, Rn );119.583 - precheck();119.584 - check_walign32( R_ECX );119.585 - ADD_imm8s_r32( -4, R_ECX );119.586 - store_reg( R_ECX, Rn );119.587 - MEM_WRITE_LONG( R_ECX, R_EAX );119.588 + load_reg( R_EAX, Rn );119.589 + ADD_imm8s_r32( -4, R_EAX );119.590 + check_walign32( R_EAX );119.591 + MMU_TRANSLATE_WRITE( R_EAX );119.592 + load_reg( R_EDX, Rm );119.593 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.594 + MEM_WRITE_LONG( R_EAX, R_EDX );119.595 sh4_x86.tstate = TSTATE_NONE;119.596 :}119.597 MOV.L Rm, @(R0, Rn) {:119.598 load_reg( R_EAX, 0 );119.599 load_reg( R_ECX, Rn );119.600 - ADD_r32_r32( R_EAX, R_ECX );119.601 - precheck();119.602 - check_walign32( R_ECX );119.603 - load_reg( R_EAX, Rm );119.604 - MEM_WRITE_LONG( R_ECX, R_EAX );119.605 + ADD_r32_r32( R_ECX, R_EAX );119.606 + check_walign32( R_EAX );119.607 + MMU_TRANSLATE_WRITE( R_EAX );119.608 + load_reg( R_EDX, Rm );119.609 + MEM_WRITE_LONG( R_EAX, R_EDX );119.610 sh4_x86.tstate = TSTATE_NONE;119.611 :}119.612 MOV.L R0, @(disp, GBR) {:119.613 - load_spreg( R_ECX, R_GBR );119.614 - load_reg( R_EAX, 0 );119.615 - ADD_imm32_r32( disp, R_ECX );119.616 - precheck();119.617 - check_walign32( R_ECX );119.618 - MEM_WRITE_LONG( R_ECX, R_EAX );119.619 + load_spreg( R_EAX, R_GBR );119.620 + ADD_imm32_r32( disp, R_EAX );119.621 + check_walign32( R_EAX );119.622 + MMU_TRANSLATE_WRITE( R_EAX );119.623 + load_reg( R_EDX, 0 );119.624 + MEM_WRITE_LONG( R_EAX, R_EDX );119.625 sh4_x86.tstate = TSTATE_NONE;119.626 :}119.627 MOV.L Rm, @(disp, Rn) {:119.628 - load_reg( R_ECX, Rn );119.629 - load_reg( R_EAX, Rm );119.630 - ADD_imm32_r32( disp, R_ECX );119.631 - precheck();119.632 - check_walign32( R_ECX );119.633 - MEM_WRITE_LONG( R_ECX, R_EAX );119.634 + load_reg( R_EAX, Rn );119.635 + ADD_imm32_r32( disp, R_EAX );119.636 + check_walign32( R_EAX );119.637 + MMU_TRANSLATE_WRITE( R_EAX );119.638 + load_reg( R_EDX, Rm );119.639 + MEM_WRITE_LONG( R_EAX, R_EDX );119.640 sh4_x86.tstate = TSTATE_NONE;119.641 :}119.642 MOV.L @Rm, Rn {:119.643 - load_reg( R_ECX, Rm );119.644 - precheck();119.645 - check_ralign32( R_ECX );119.646 - MEM_READ_LONG( R_ECX, R_EAX );119.647 + load_reg( R_EAX, Rm );119.648 + check_ralign32( R_EAX );119.649 + MMU_TRANSLATE_READ( R_EAX );119.650 + MEM_READ_LONG( R_EAX, R_EAX );119.651 store_reg( R_EAX, Rn );119.652 sh4_x86.tstate = TSTATE_NONE;119.653 :}119.654 MOV.L @Rm+, Rn {:119.655 load_reg( R_EAX, Rm );119.656 - precheck();119.657 check_ralign32( R_EAX );119.658 - MOV_r32_r32( R_EAX, R_ECX );119.659 - ADD_imm8s_r32( 4, R_EAX );119.660 - store_reg( R_EAX, Rm );119.661 - MEM_READ_LONG( R_ECX, R_EAX );119.662 + MMU_TRANSLATE_READ( R_EAX );119.663 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.664 + MEM_READ_LONG( R_EAX, R_EAX );119.665 store_reg( R_EAX, Rn );119.666 sh4_x86.tstate = TSTATE_NONE;119.667 :}119.668 MOV.L @(R0, Rm), Rn {:119.669 load_reg( R_EAX, 0 );119.670 load_reg( R_ECX, Rm );119.671 - ADD_r32_r32( R_EAX, R_ECX );119.672 - precheck();119.673 - check_ralign32( R_ECX );119.674 - MEM_READ_LONG( R_ECX, R_EAX );119.675 + ADD_r32_r32( R_ECX, R_EAX );119.676 + check_ralign32( R_EAX );119.677 + MMU_TRANSLATE_READ( R_EAX );119.678 + MEM_READ_LONG( R_EAX, R_EAX );119.679 store_reg( R_EAX, Rn );119.680 sh4_x86.tstate = TSTATE_NONE;119.681 :}119.682 MOV.L @(disp, GBR), R0 {:119.683 - load_spreg( R_ECX, R_GBR );119.684 - ADD_imm32_r32( disp, R_ECX );119.685 - precheck();119.686 - check_ralign32( R_ECX );119.687 - MEM_READ_LONG( R_ECX, R_EAX );119.688 + load_spreg( R_EAX, R_GBR );119.689 + ADD_imm32_r32( disp, R_EAX );119.690 + check_ralign32( R_EAX );119.691 + MMU_TRANSLATE_READ( R_EAX );119.692 + MEM_READ_LONG( R_EAX, R_EAX );119.693 store_reg( R_EAX, 0 );119.694 sh4_x86.tstate = TSTATE_NONE;119.695 :}119.696 @@ -1176,107 +1208,119 @@119.697 SLOTILLEGAL();119.698 } else {119.699 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;119.700 - sh4ptr_t ptr = mem_get_region(target);119.701 - if( ptr != NULL ) {119.702 + if( IS_IN_ICACHE(target) ) {119.703 + // If the target address is in the same page as the code, it's119.704 + // pretty safe to just ref it directly and circumvent the whole119.705 + // memory subsystem. (this is a big performance win)119.706 +119.707 + // FIXME: There's a corner-case that's not handled here when119.708 + // the current code-page is in the ITLB but not in the UTLB.119.709 + // (should generate a TLB miss although need to test SH4119.710 + // behaviour to confirm) Unlikely to be anyone depending on this119.711 + // behaviour though.119.712 + sh4ptr_t ptr = GET_ICACHE_PTR(target);119.713 MOV_moff32_EAX( ptr );119.714 } else {119.715 - load_imm32( R_ECX, target );119.716 - MEM_READ_LONG( R_ECX, R_EAX );119.717 + // Note: we use sh4r.pc for the calc as we could be running at a119.718 + // different virtual address than the translation was done with,119.719 + // but we can safely assume that the low bits are the same.119.720 + load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );119.721 + ADD_sh4r_r32( R_PC, R_EAX );119.722 + MMU_TRANSLATE_READ( R_EAX );119.723 + MEM_READ_LONG( R_EAX, R_EAX );119.724 + sh4_x86.tstate = TSTATE_NONE;119.725 }119.726 store_reg( R_EAX, Rn );119.727 - sh4_x86.tstate = TSTATE_NONE;119.728 }119.729 :}119.730 MOV.L @(disp, Rm), Rn {:119.731 - load_reg( R_ECX, Rm );119.732 - ADD_imm8s_r32( disp, R_ECX );119.733 - precheck();119.734 - check_ralign32( R_ECX );119.735 - MEM_READ_LONG( R_ECX, R_EAX );119.736 + load_reg( R_EAX, Rm );119.737 + ADD_imm8s_r32( disp, R_EAX );119.738 + check_ralign32( R_EAX );119.739 + MMU_TRANSLATE_READ( R_EAX );119.740 + MEM_READ_LONG( R_EAX, R_EAX );119.741 store_reg( R_EAX, Rn );119.742 sh4_x86.tstate = TSTATE_NONE;119.743 :}119.744 MOV.W Rm, @Rn {:119.745 - load_reg( R_ECX, Rn );119.746 - precheck();119.747 - check_walign16( R_ECX );119.748 - load_reg( R_EAX, Rm );119.749 - MEM_WRITE_WORD( R_ECX, R_EAX );119.750 + load_reg( R_EAX, Rn );119.751 + check_walign16( R_EAX );119.752 + MMU_TRANSLATE_WRITE( R_EAX )119.753 + load_reg( R_EDX, Rm );119.754 + MEM_WRITE_WORD( R_EAX, R_EDX );119.755 sh4_x86.tstate = TSTATE_NONE;119.756 :}119.757 MOV.W Rm, @-Rn {:119.758 - load_reg( R_ECX, Rn );119.759 - precheck();119.760 - check_walign16( R_ECX );119.761 - load_reg( R_EAX, Rm );119.762 - ADD_imm8s_r32( -2, R_ECX );119.763 - store_reg( R_ECX, Rn );119.764 - MEM_WRITE_WORD( R_ECX, R_EAX );119.765 + load_reg( R_EAX, Rn );119.766 + ADD_imm8s_r32( -2, R_EAX );119.767 + check_walign16( R_EAX );119.768 + MMU_TRANSLATE_WRITE( R_EAX );119.769 + load_reg( R_EDX, Rm );119.770 + ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );119.771 + MEM_WRITE_WORD( R_EAX, R_EDX );119.772 sh4_x86.tstate = TSTATE_NONE;119.773 :}119.774 MOV.W Rm, @(R0, Rn) {:119.775 load_reg( R_EAX, 0 );119.776 load_reg( R_ECX, Rn );119.777 - ADD_r32_r32( R_EAX, R_ECX );119.778 - precheck();119.779 - check_walign16( R_ECX );119.780 - load_reg( R_EAX, Rm );119.781 - MEM_WRITE_WORD( R_ECX, R_EAX );119.782 + ADD_r32_r32( R_ECX, R_EAX );119.783 + check_walign16( R_EAX );119.784 + MMU_TRANSLATE_WRITE( R_EAX );119.785 + load_reg( R_EDX, Rm );119.786 + MEM_WRITE_WORD( R_EAX, R_EDX );119.787 sh4_x86.tstate = TSTATE_NONE;119.788 :}119.789 MOV.W R0, @(disp, GBR) {:119.790 - load_spreg( R_ECX, R_GBR );119.791 - load_reg( R_EAX, 0 );119.792 - ADD_imm32_r32( disp, R_ECX );119.793 - precheck();119.794 - check_walign16( R_ECX );119.795 - MEM_WRITE_WORD( R_ECX, R_EAX );119.796 + load_spreg( R_EAX, R_GBR );119.797 + ADD_imm32_r32( disp, R_EAX );119.798 + check_walign16( R_EAX );119.799 + MMU_TRANSLATE_WRITE( R_EAX );119.800 + load_reg( R_EDX, 0 );119.801 + MEM_WRITE_WORD( R_EAX, R_EDX );119.802 sh4_x86.tstate = TSTATE_NONE;119.803 :}119.804 MOV.W R0, @(disp, Rn) {:119.805 - load_reg( R_ECX, Rn );119.806 - load_reg( R_EAX, 0 );119.807 - ADD_imm32_r32( disp, R_ECX );119.808 - precheck();119.809 - check_walign16( R_ECX );119.810 - MEM_WRITE_WORD( R_ECX, R_EAX );119.811 + load_reg( R_EAX, Rn );119.812 + ADD_imm32_r32( disp, R_EAX );119.813 + check_walign16( R_EAX );119.814 + MMU_TRANSLATE_WRITE( R_EAX );119.815 + load_reg( R_EDX, 0 );119.816 + MEM_WRITE_WORD( R_EAX, R_EDX );119.817 sh4_x86.tstate = TSTATE_NONE;119.818 :}119.819 MOV.W @Rm, Rn {:119.820 - load_reg( R_ECX, Rm );119.821 - precheck();119.822 - check_ralign16( R_ECX );119.823 - MEM_READ_WORD( R_ECX, R_EAX );119.824 + load_reg( R_EAX, Rm );119.825 + check_ralign16( R_EAX );119.826 + MMU_TRANSLATE_READ( R_EAX );119.827 + MEM_READ_WORD( R_EAX, R_EAX );119.828 store_reg( R_EAX, Rn );119.829 sh4_x86.tstate = TSTATE_NONE;119.830 :}119.831 MOV.W @Rm+, Rn {:119.832 load_reg( R_EAX, Rm );119.833 - precheck();119.834 check_ralign16( R_EAX );119.835 - MOV_r32_r32( R_EAX, R_ECX );119.836 - ADD_imm8s_r32( 2, R_EAX );119.837 - store_reg( R_EAX, Rm );119.838 - MEM_READ_WORD( R_ECX, R_EAX );119.839 + MMU_TRANSLATE_READ( R_EAX );119.840 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );119.841 + MEM_READ_WORD( R_EAX, R_EAX );119.842 store_reg( R_EAX, Rn );119.843 sh4_x86.tstate = TSTATE_NONE;119.844 :}119.845 MOV.W @(R0, Rm), Rn {:119.846 load_reg( R_EAX, 0 );119.847 load_reg( R_ECX, Rm );119.848 - ADD_r32_r32( R_EAX, R_ECX );119.849 - precheck();119.850 - check_ralign16( R_ECX );119.851 - MEM_READ_WORD( R_ECX, R_EAX );119.852 + ADD_r32_r32( R_ECX, R_EAX );119.853 + check_ralign16( R_EAX );119.854 + MMU_TRANSLATE_READ( R_EAX );119.855 + MEM_READ_WORD( R_EAX, R_EAX );119.856 store_reg( R_EAX, Rn );119.857 sh4_x86.tstate = TSTATE_NONE;119.858 :}119.859 MOV.W @(disp, GBR), R0 {:119.860 - load_spreg( R_ECX, R_GBR );119.861 - ADD_imm32_r32( disp, R_ECX );119.862 - precheck();119.863 - check_ralign16( R_ECX );119.864 - MEM_READ_WORD( R_ECX, R_EAX );119.865 + load_spreg( R_EAX, R_GBR );119.866 + ADD_imm32_r32( disp, R_EAX );119.867 + check_ralign16( R_EAX );119.868 + MMU_TRANSLATE_READ( R_EAX );119.869 + MEM_READ_WORD( R_EAX, R_EAX );119.870 store_reg( R_EAX, 0 );119.871 sh4_x86.tstate = TSTATE_NONE;119.872 :}119.873 @@ -1284,18 +1328,28 @@119.874 if( sh4_x86.in_delay_slot ) {119.875 SLOTILLEGAL();119.876 } else {119.877 - load_imm32( R_ECX, pc + disp + 4 );119.878 - MEM_READ_WORD( R_ECX, R_EAX );119.879 + // See comments for MOV.L @(disp, PC), Rn119.880 + uint32_t target = pc + disp + 4;119.881 + if( IS_IN_ICACHE(target) ) {119.882 + sh4ptr_t ptr = GET_ICACHE_PTR(target);119.883 + MOV_moff32_EAX( ptr );119.884 + MOVSX_r16_r32( R_EAX, R_EAX );119.885 + } else {119.886 + load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );119.887 + ADD_sh4r_r32( R_PC, R_EAX );119.888 + MMU_TRANSLATE_READ( R_EAX );119.889 + MEM_READ_WORD( R_EAX, R_EAX );119.890 + sh4_x86.tstate = TSTATE_NONE;119.891 + }119.892 store_reg( R_EAX, Rn );119.893 - sh4_x86.tstate = TSTATE_NONE;119.894 }119.895 :}119.896 MOV.W @(disp, Rm), R0 {:119.897 - load_reg( R_ECX, Rm );119.898 - ADD_imm32_r32( disp, R_ECX );119.899 - precheck();119.900 - check_ralign16( R_ECX );119.901 - MEM_READ_WORD( R_ECX, R_EAX );119.902 + load_reg( R_EAX, Rm );119.903 + ADD_imm32_r32( disp, R_EAX );119.904 + check_ralign16( R_EAX );119.905 + MMU_TRANSLATE_READ( R_EAX );119.906 + MEM_READ_WORD( R_EAX, R_EAX );119.907 store_reg( R_EAX, 0 );119.908 sh4_x86.tstate = TSTATE_NONE;119.909 :}119.910 @@ -1303,16 +1357,18 @@119.911 if( sh4_x86.in_delay_slot ) {119.912 SLOTILLEGAL();119.913 } else {119.914 - load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );119.915 + load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );119.916 + ADD_sh4r_r32( R_PC, R_ECX );119.917 store_reg( R_ECX, 0 );119.918 + sh4_x86.tstate = TSTATE_NONE;119.919 }119.920 :}119.921 MOVCA.L R0, @Rn {:119.922 - load_reg( R_EAX, 0 );119.923 - load_reg( R_ECX, Rn );119.924 - precheck();119.925 - check_walign32( R_ECX );119.926 - MEM_WRITE_LONG( R_ECX, R_EAX );119.927 + load_reg( R_EAX, Rn );119.928 + check_walign32( R_EAX );119.929 + MMU_TRANSLATE_WRITE( R_EAX );119.930 + load_reg( R_EDX, 0 );119.931 + MEM_WRITE_LONG( R_EAX, R_EDX );119.932 sh4_x86.tstate = TSTATE_NONE;119.933 :}119.935 @@ -1321,8 +1377,9 @@119.936 if( sh4_x86.in_delay_slot ) {119.937 SLOTILLEGAL();119.938 } else {119.939 - JT_rel8( EXIT_BLOCK_SIZE, nottaken );119.940 - exit_block( disp + pc + 4, pc+2 );119.941 + sh4vma_t target = disp + pc + 4;119.942 + JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );119.943 + exit_block_rel(target, pc+2 );119.944 JMP_TARGET(nottaken);119.945 return 2;119.946 }119.947 @@ -1331,6 +1388,7 @@119.948 if( sh4_x86.in_delay_slot ) {119.949 SLOTILLEGAL();119.950 } else {119.951 + sh4vma_t target = disp + pc + 4;119.952 sh4_x86.in_delay_slot = TRUE;119.953 if( sh4_x86.tstate == TSTATE_NONE ) {119.954 CMP_imm8s_sh4r( 1, R_T );119.955 @@ -1338,7 +1396,7 @@119.956 }119.957 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32119.958 sh4_translate_instruction(pc+2);119.959 - exit_block( disp + pc + 4, pc+4 );119.960 + exit_block_rel( target, pc+4 );119.961 // not taken119.962 *patch = (xlat_output - ((uint8_t *)patch)) - 4;119.963 sh4_translate_instruction(pc+2);119.964 @@ -1351,7 +1409,7 @@119.965 } else {119.966 sh4_x86.in_delay_slot = TRUE;119.967 sh4_translate_instruction( pc + 2 );119.968 - exit_block( disp + pc + 4, pc+4 );119.969 + exit_block_rel( disp + pc + 4, pc+4 );119.970 sh4_x86.branch_taken = TRUE;119.971 return 4;119.972 }119.973 @@ -1379,7 +1437,7 @@119.974 store_spreg( R_EAX, R_PR );119.975 sh4_x86.in_delay_slot = TRUE;119.976 sh4_translate_instruction( pc + 2 );119.977 - exit_block( disp + pc + 4, pc+4 );119.978 + exit_block_rel( disp + pc + 4, pc+4 );119.979 sh4_x86.branch_taken = TRUE;119.980 return 4;119.981 }119.982 @@ -1404,8 +1462,9 @@119.983 if( sh4_x86.in_delay_slot ) {119.984 SLOTILLEGAL();119.985 } else {119.986 - JF_rel8( EXIT_BLOCK_SIZE, nottaken );119.987 - exit_block( disp + pc + 4, pc+2 );119.988 + sh4vma_t target = disp + pc + 4;119.989 + JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );119.990 + exit_block_rel(target, pc+2 );119.991 JMP_TARGET(nottaken);119.992 return 2;119.993 }119.994 @@ -1421,7 +1480,7 @@119.995 }119.996 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32119.997 sh4_translate_instruction(pc+2);119.998 - exit_block( disp + pc + 4, pc+4 );119.999 + exit_block_rel( disp + pc + 4, pc+4 );119.1000 // not taken119.1001 *patch = (xlat_output - ((uint8_t *)patch)) - 4;119.1002 sh4_translate_instruction(pc+2);119.1003 @@ -1506,8 +1565,7 @@119.1004 if( sh4_x86.in_delay_slot ) {119.1005 SLOTILLEGAL();119.1006 } else {119.1007 - precheck();119.1008 - JMP_exit(EXIT_ILLEGAL);119.1009 + JMP_exc(EXC_ILLEGAL);119.1010 return 2;119.1011 }119.1012 :}119.1013 @@ -1591,198 +1649,196 @@119.1014 sh4_x86.tstate = TSTATE_NONE;119.1015 :}119.1016 FMOV FRm, @Rn {:119.1017 - precheck();119.1018 - check_fpuen_no_precheck();119.1019 - load_reg( R_ECX, Rn );119.1020 - check_walign32( R_ECX );119.1021 + check_fpuen();119.1022 + load_reg( R_EAX, Rn );119.1023 + check_walign32( R_EAX );119.1024 + MMU_TRANSLATE_WRITE( R_EAX );119.1025 load_spreg( R_EDX, R_FPSCR );119.1026 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1027 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);119.1028 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);119.1029 load_fr_bank( R_EDX );119.1030 - load_fr( R_EDX, R_EAX, FRm );119.1031 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12119.1032 + load_fr( R_EDX, R_ECX, FRm );119.1033 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12119.1034 if( FRm&1 ) {119.1035 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );119.1036 JMP_TARGET(doublesize);119.1037 load_xf_bank( R_EDX );119.1038 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1039 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1040 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1041 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1042 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1043 JMP_TARGET(end);119.1044 } else {119.1045 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );119.1046 JMP_TARGET(doublesize);119.1047 load_fr_bank( R_EDX );119.1048 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1049 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1050 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1051 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1052 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1053 JMP_TARGET(end);119.1054 }119.1055 sh4_x86.tstate = TSTATE_NONE;119.1056 :}119.1057 FMOV @Rm, FRn {:119.1058 - precheck();119.1059 - check_fpuen_no_precheck();119.1060 - load_reg( R_ECX, Rm );119.1061 - check_ralign32( R_ECX );119.1062 + check_fpuen();119.1063 + load_reg( R_EAX, Rm );119.1064 + check_ralign32( R_EAX );119.1065 + MMU_TRANSLATE_READ( R_EAX );119.1066 load_spreg( R_EDX, R_FPSCR );119.1067 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1068 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);119.1069 - MEM_READ_LONG( R_ECX, R_EAX );119.1070 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);119.1071 + MEM_READ_LONG( R_EAX, R_EAX );119.1072 load_fr_bank( R_EDX );119.1073 store_fr( R_EDX, R_EAX, FRn );119.1074 if( FRn&1 ) {119.1075 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);119.1076 JMP_TARGET(doublesize);119.1077 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1078 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1079 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it119.1080 load_xf_bank( R_EDX );119.1081 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1082 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1083 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1084 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1085 JMP_TARGET(end);119.1086 } else {119.1087 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);119.1088 JMP_TARGET(doublesize);119.1089 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1090 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1091 load_fr_bank( R_EDX );119.1092 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1093 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1094 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1095 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1096 JMP_TARGET(end);119.1097 }119.1098 sh4_x86.tstate = TSTATE_NONE;119.1099 :}119.1100 FMOV FRm, @-Rn {:119.1101 - precheck();119.1102 - check_fpuen_no_precheck();119.1103 - load_reg( R_ECX, Rn );119.1104 - check_walign32( R_ECX );119.1105 + check_fpuen();119.1106 + load_reg( R_EAX, Rn );119.1107 + check_walign32( R_EAX );119.1108 load_spreg( R_EDX, R_FPSCR );119.1109 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1110 - JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);119.1111 + JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);119.1112 + ADD_imm8s_r32( -4, R_EAX );119.1113 + MMU_TRANSLATE_WRITE( R_EAX );119.1114 load_fr_bank( R_EDX );119.1115 - load_fr( R_EDX, R_EAX, FRm );119.1116 - ADD_imm8s_r32(-4,R_ECX);119.1117 - store_reg( R_ECX, Rn );119.1118 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12119.1119 + load_fr( R_EDX, R_ECX, FRm );119.1120 + ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));119.1121 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12119.1122 if( FRm&1 ) {119.1123 - JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );119.1124 + JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );119.1125 JMP_TARGET(doublesize);119.1126 + ADD_imm8s_r32(-8,R_EAX);119.1127 + MMU_TRANSLATE_WRITE( R_EAX );119.1128 load_xf_bank( R_EDX );119.1129 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1130 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1131 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1132 - ADD_imm8s_r32(-8,R_ECX);119.1133 - store_reg( R_ECX, Rn );119.1134 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1135 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));119.1136 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1137 JMP_TARGET(end);119.1138 } else {119.1139 - JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );119.1140 + JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );119.1141 JMP_TARGET(doublesize);119.1142 + ADD_imm8s_r32(-8,R_EAX);119.1143 + MMU_TRANSLATE_WRITE( R_EAX );119.1144 load_fr_bank( R_EDX );119.1145 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1146 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1147 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1148 - ADD_imm8s_r32(-8,R_ECX);119.1149 - store_reg( R_ECX, Rn );119.1150 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1151 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));119.1152 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1153 JMP_TARGET(end);119.1154 }119.1155 sh4_x86.tstate = TSTATE_NONE;119.1156 :}119.1157 FMOV @Rm+, FRn {:119.1158 - precheck();119.1159 - check_fpuen_no_precheck();119.1160 - load_reg( R_ECX, Rm );119.1161 - check_ralign32( R_ECX );119.1162 - MOV_r32_r32( R_ECX, R_EAX );119.1163 + check_fpuen();119.1164 + load_reg( R_EAX, Rm );119.1165 + check_ralign32( R_EAX );119.1166 + MMU_TRANSLATE_READ( R_EAX );119.1167 load_spreg( R_EDX, R_FPSCR );119.1168 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1169 - JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);119.1170 - ADD_imm8s_r32( 4, R_EAX );119.1171 - store_reg( R_EAX, Rm );119.1172 - MEM_READ_LONG( R_ECX, R_EAX );119.1173 + JNE_rel8(12 + MEM_READ_SIZE, doublesize);119.1174 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1175 + MEM_READ_LONG( R_EAX, R_EAX );119.1176 load_fr_bank( R_EDX );119.1177 store_fr( R_EDX, R_EAX, FRn );119.1178 if( FRn&1 ) {119.1179 - JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);119.1180 + JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);119.1181 JMP_TARGET(doublesize);119.1182 - ADD_imm8s_r32( 8, R_EAX );119.1183 - store_reg(R_EAX, Rm);119.1184 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1185 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );119.1186 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1187 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it119.1188 load_xf_bank( R_EDX );119.1189 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1190 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1191 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1192 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1193 JMP_TARGET(end);119.1194 } else {119.1195 - JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);119.1196 - ADD_imm8s_r32( 8, R_EAX );119.1197 - store_reg(R_EAX, Rm);119.1198 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1199 + JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);119.1200 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );119.1201 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1202 load_fr_bank( R_EDX );119.1203 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1204 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1205 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1206 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1207 JMP_TARGET(end);119.1208 }119.1209 sh4_x86.tstate = TSTATE_NONE;119.1210 :}119.1211 FMOV FRm, @(R0, Rn) {:119.1212 - precheck();119.1213 - check_fpuen_no_precheck();119.1214 - load_reg( R_ECX, Rn );119.1215 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );119.1216 - check_walign32( R_ECX );119.1217 + check_fpuen();119.1218 + load_reg( R_EAX, Rn );119.1219 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );119.1220 + check_walign32( R_EAX );119.1221 + MMU_TRANSLATE_WRITE( R_EAX );119.1222 load_spreg( R_EDX, R_FPSCR );119.1223 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1224 - JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);119.1225 + JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);119.1226 load_fr_bank( R_EDX );119.1227 - load_fr( R_EDX, R_EAX, FRm );119.1228 - MEM_WRITE_LONG( R_ECX, R_EAX ); // 12119.1229 + load_fr( R_EDX, R_ECX, FRm );119.1230 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12119.1231 if( FRm&1 ) {119.1232 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );119.1233 JMP_TARGET(doublesize);119.1234 load_xf_bank( R_EDX );119.1235 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1236 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1237 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1238 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1239 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1240 JMP_TARGET(end);119.1241 } else {119.1242 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );119.1243 JMP_TARGET(doublesize);119.1244 load_fr_bank( R_EDX );119.1245 - load_fr( R_EDX, R_EAX, FRm&0x0E );119.1246 + load_fr( R_EDX, R_ECX, FRm&0x0E );119.1247 load_fr( R_EDX, R_EDX, FRm|0x01 );119.1248 - MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );119.1249 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );119.1250 JMP_TARGET(end);119.1251 }119.1252 sh4_x86.tstate = TSTATE_NONE;119.1253 :}119.1254 FMOV @(R0, Rm), FRn {:119.1255 - precheck();119.1256 - check_fpuen_no_precheck();119.1257 - load_reg( R_ECX, Rm );119.1258 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );119.1259 - check_ralign32( R_ECX );119.1260 + check_fpuen();119.1261 + load_reg( R_EAX, Rm );119.1262 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );119.1263 + check_ralign32( R_EAX );119.1264 + MMU_TRANSLATE_READ( R_EAX );119.1265 load_spreg( R_EDX, R_FPSCR );119.1266 TEST_imm32_r32( FPSCR_SZ, R_EDX );119.1267 - JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);119.1268 - MEM_READ_LONG( R_ECX, R_EAX );119.1269 + JNE_rel8(8 + MEM_READ_SIZE, doublesize);119.1270 + MEM_READ_LONG( R_EAX, R_EAX );119.1271 load_fr_bank( R_EDX );119.1272 store_fr( R_EDX, R_EAX, FRn );119.1273 if( FRn&1 ) {119.1274 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);119.1275 JMP_TARGET(doublesize);119.1276 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1277 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1278 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it119.1279 load_xf_bank( R_EDX );119.1280 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1281 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1282 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1283 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1284 JMP_TARGET(end);119.1285 } else {119.1286 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);119.1287 JMP_TARGET(doublesize);119.1288 - MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );119.1289 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );119.1290 load_fr_bank( R_EDX );119.1291 - store_fr( R_EDX, R_EAX, FRn&0x0E );119.1292 - store_fr( R_EDX, R_ECX, FRn|0x01 );119.1293 + store_fr( R_EDX, R_ECX, FRn&0x0E );119.1294 + store_fr( R_EDX, R_EAX, FRn|0x01 );119.1295 JMP_TARGET(end);119.1296 }119.1297 sh4_x86.tstate = TSTATE_NONE;119.1298 @@ -2222,12 +2278,10 @@119.1299 :}119.1300 LDC.L @Rm+, GBR {:119.1301 load_reg( R_EAX, Rm );119.1302 - precheck();119.1303 check_ralign32( R_EAX );119.1304 - MOV_r32_r32( R_EAX, R_ECX );119.1305 - ADD_imm8s_r32( 4, R_EAX );119.1306 - store_reg( R_EAX, Rm );119.1307 - MEM_READ_LONG( R_ECX, R_EAX );119.1308 + MMU_TRANSLATE_READ( R_EAX );119.1309 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1310 + MEM_READ_LONG( R_EAX, R_EAX );119.1311 store_spreg( R_EAX, R_GBR );119.1312 sh4_x86.tstate = TSTATE_NONE;119.1313 :}119.1314 @@ -2235,14 +2289,12 @@119.1315 if( sh4_x86.in_delay_slot ) {119.1316 SLOTILLEGAL();119.1317 } else {119.1318 - precheck();119.1319 - check_priv_no_precheck();119.1320 + check_priv();119.1321 load_reg( R_EAX, Rm );119.1322 check_ralign32( R_EAX );119.1323 - MOV_r32_r32( R_EAX, R_ECX );119.1324 - ADD_imm8s_r32( 4, R_EAX );119.1325 - store_reg( R_EAX, Rm );119.1326 - MEM_READ_LONG( R_ECX, R_EAX );119.1327 + MMU_TRANSLATE_READ( R_EAX );119.1328 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1329 + MEM_READ_LONG( R_EAX, R_EAX );119.1330 call_func1( sh4_write_sr, R_EAX );119.1331 sh4_x86.priv_checked = FALSE;119.1332 sh4_x86.fpuen_checked = FALSE;119.1333 @@ -2250,74 +2302,62 @@119.1334 }119.1335 :}119.1336 LDC.L @Rm+, VBR {:119.1337 - precheck();119.1338 - check_priv_no_precheck();119.1339 + check_priv();119.1340 load_reg( R_EAX, Rm );119.1341 check_ralign32( R_EAX );119.1342 - MOV_r32_r32( R_EAX, R_ECX );119.1343 - ADD_imm8s_r32( 4, R_EAX );119.1344 - store_reg( R_EAX, Rm );119.1345 - MEM_READ_LONG( R_ECX, R_EAX );119.1346 + MMU_TRANSLATE_READ( R_EAX );119.1347 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1348 + MEM_READ_LONG( R_EAX, R_EAX );119.1349 store_spreg( R_EAX, R_VBR );119.1350 sh4_x86.tstate = TSTATE_NONE;119.1351 :}119.1352 LDC.L @Rm+, SSR {:119.1353 - precheck();119.1354 - check_priv_no_precheck();119.1355 + check_priv();119.1356 load_reg( R_EAX, Rm );119.1357 check_ralign32( R_EAX );119.1358 - MOV_r32_r32( R_EAX, R_ECX );119.1359 - ADD_imm8s_r32( 4, R_EAX );119.1360 - store_reg( R_EAX, Rm );119.1361 - MEM_READ_LONG( R_ECX, R_EAX );119.1362 + MMU_TRANSLATE_READ( R_EAX );119.1363 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1364 + MEM_READ_LONG( R_EAX, R_EAX );119.1365 store_spreg( R_EAX, R_SSR );119.1366 sh4_x86.tstate = TSTATE_NONE;119.1367 :}119.1368 LDC.L @Rm+, SGR {:119.1369 - precheck();119.1370 - check_priv_no_precheck();119.1371 + check_priv();119.1372 load_reg( R_EAX, Rm );119.1373 check_ralign32( R_EAX );119.1374 - MOV_r32_r32( R_EAX, R_ECX );119.1375 - ADD_imm8s_r32( 4, R_EAX );119.1376 - store_reg( R_EAX, Rm );119.1377 - MEM_READ_LONG( R_ECX, R_EAX );119.1378 + MMU_TRANSLATE_READ( R_EAX );119.1379 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1380 + MEM_READ_LONG( R_EAX, R_EAX );119.1381 store_spreg( R_EAX, R_SGR );119.1382 sh4_x86.tstate = TSTATE_NONE;119.1383 :}119.1384 LDC.L @Rm+, SPC {:119.1385 - precheck();119.1386 - check_priv_no_precheck();119.1387 + check_priv();119.1388 load_reg( R_EAX, Rm );119.1389 check_ralign32( R_EAX );119.1390 - MOV_r32_r32( R_EAX, R_ECX );119.1391 - ADD_imm8s_r32( 4, R_EAX );119.1392 - store_reg( R_EAX, Rm );119.1393 - MEM_READ_LONG( R_ECX, R_EAX );119.1394 + MMU_TRANSLATE_READ( R_EAX );119.1395 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1396 + MEM_READ_LONG( R_EAX, R_EAX );119.1397 store_spreg( R_EAX, R_SPC );119.1398 sh4_x86.tstate = TSTATE_NONE;119.1399 :}119.1400 LDC.L @Rm+, DBR {:119.1401 - precheck();119.1402 - check_priv_no_precheck();119.1403 + check_priv();119.1404 load_reg( R_EAX, Rm );119.1405 check_ralign32( R_EAX );119.1406 - MOV_r32_r32( R_EAX, R_ECX );119.1407 - ADD_imm8s_r32( 4, R_EAX );119.1408 - store_reg( R_EAX, Rm );119.1409 - MEM_READ_LONG( R_ECX, R_EAX );119.1410 + MMU_TRANSLATE_READ( R_EAX );119.1411 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1412 + MEM_READ_LONG( R_EAX, R_EAX );119.1413 store_spreg( R_EAX, R_DBR );119.1414 sh4_x86.tstate = TSTATE_NONE;119.1415 :}119.1416 LDC.L @Rm+, Rn_BANK {:119.1417 - precheck();119.1418 - check_priv_no_precheck();119.1419 + check_priv();119.1420 load_reg( R_EAX, Rm );119.1421 check_ralign32( R_EAX );119.1422 - MOV_r32_r32( R_EAX, R_ECX );119.1423 - ADD_imm8s_r32( 4, R_EAX );119.1424 - store_reg( R_EAX, Rm );119.1425 - MEM_READ_LONG( R_ECX, R_EAX );119.1426 + MMU_TRANSLATE_READ( R_EAX );119.1427 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1428 + MEM_READ_LONG( R_EAX, R_EAX );119.1429 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );119.1430 sh4_x86.tstate = TSTATE_NONE;119.1431 :}119.1432 @@ -2329,12 +2369,10 @@119.1433 :}119.1434 LDS.L @Rm+, FPSCR {:119.1435 load_reg( R_EAX, Rm );119.1436 - precheck();119.1437 check_ralign32( R_EAX );119.1438 - MOV_r32_r32( R_EAX, R_ECX );119.1439 - ADD_imm8s_r32( 4, R_EAX );119.1440 - store_reg( R_EAX, Rm );119.1441 - MEM_READ_LONG( R_ECX, R_EAX );119.1442 + MMU_TRANSLATE_READ( R_EAX );119.1443 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1444 + MEM_READ_LONG( R_EAX, R_EAX );119.1445 store_spreg( R_EAX, R_FPSCR );119.1446 update_fr_bank( R_EAX );119.1447 sh4_x86.tstate = TSTATE_NONE;119.1448 @@ -2345,12 +2383,10 @@119.1449 :}119.1450 LDS.L @Rm+, FPUL {:119.1451 load_reg( R_EAX, Rm );119.1452 - precheck();119.1453 check_ralign32( R_EAX );119.1454 - MOV_r32_r32( R_EAX, R_ECX );119.1455 - ADD_imm8s_r32( 4, R_EAX );119.1456 - store_reg( R_EAX, Rm );119.1457 - MEM_READ_LONG( R_ECX, R_EAX );119.1458 + MMU_TRANSLATE_READ( R_EAX );119.1459 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1460 + MEM_READ_LONG( R_EAX, R_EAX );119.1461 store_spreg( R_EAX, R_FPUL );119.1462 sh4_x86.tstate = TSTATE_NONE;119.1463 :}119.1464 @@ -2360,12 +2396,10 @@119.1465 :}119.1466 LDS.L @Rm+, MACH {:119.1467 load_reg( R_EAX, Rm );119.1468 - precheck();119.1469 check_ralign32( R_EAX );119.1470 - MOV_r32_r32( R_EAX, R_ECX );119.1471 - ADD_imm8s_r32( 4, R_EAX );119.1472 - store_reg( R_EAX, Rm );119.1473 - MEM_READ_LONG( R_ECX, R_EAX );119.1474 + MMU_TRANSLATE_READ( R_EAX );119.1475 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1476 + MEM_READ_LONG( R_EAX, R_EAX );119.1477 store_spreg( R_EAX, R_MACH );119.1478 sh4_x86.tstate = TSTATE_NONE;119.1479 :}119.1480 @@ -2375,12 +2409,10 @@119.1481 :}119.1482 LDS.L @Rm+, MACL {:119.1483 load_reg( R_EAX, Rm );119.1484 - precheck();119.1485 check_ralign32( R_EAX );119.1486 - MOV_r32_r32( R_EAX, R_ECX );119.1487 - ADD_imm8s_r32( 4, R_EAX );119.1488 - store_reg( R_EAX, Rm );119.1489 - MEM_READ_LONG( R_ECX, R_EAX );119.1490 + MMU_TRANSLATE_READ( R_EAX );119.1491 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1492 + MEM_READ_LONG( R_EAX, R_EAX );119.1493 store_spreg( R_EAX, R_MACL );119.1494 sh4_x86.tstate = TSTATE_NONE;119.1495 :}119.1496 @@ -2390,12 +2422,10 @@119.1497 :}119.1498 LDS.L @Rm+, PR {:119.1499 load_reg( R_EAX, Rm );119.1500 - precheck();119.1501 check_ralign32( R_EAX );119.1502 - MOV_r32_r32( R_EAX, R_ECX );119.1503 - ADD_imm8s_r32( 4, R_EAX );119.1504 - store_reg( R_EAX, Rm );119.1505 - MEM_READ_LONG( R_ECX, R_EAX );119.1506 + MMU_TRANSLATE_READ( R_EAX );119.1507 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );119.1508 + MEM_READ_LONG( R_EAX, R_EAX );119.1509 store_spreg( R_EAX, R_PR );119.1510 sh4_x86.tstate = TSTATE_NONE;119.1511 :}119.1512 @@ -2410,8 +2440,10 @@119.1513 MOV_r32_r32( R_EAX, R_ECX );119.1514 AND_imm32_r32( 0xFC000000, R_EAX );119.1515 CMP_imm32_r32( 0xE0000000, R_EAX );119.1516 - JNE_rel8(CALL_FUNC1_SIZE, end);119.1517 + JNE_rel8(8+CALL_FUNC1_SIZE, end);119.1518 call_func1( sh4_flush_store_queue, R_ECX );119.1519 + TEST_r32_r32( R_EAX, R_EAX );119.1520 + JE_exc(-1);119.1521 JMP_TARGET(end);119.1522 sh4_x86.tstate = TSTATE_NONE;119.1523 :}119.1524 @@ -2469,90 +2501,92 @@119.1525 sh4_x86.tstate = TSTATE_NONE;119.1526 :}119.1527 STC.L SR, @-Rn {:119.1528 - precheck();119.1529 - check_priv_no_precheck();119.1530 + check_priv();119.1531 + load_reg( R_EAX, Rn );119.1532 + check_walign32( R_EAX );119.1533 + ADD_imm8s_r32( -4, R_EAX );119.1534 + MMU_TRANSLATE_WRITE( R_EAX );119.1535 + PUSH_realigned_r32( R_EAX );119.1536 call_func0( sh4_read_sr );119.1537 - load_reg( R_ECX, Rn );119.1538 - check_walign32( R_ECX );119.1539 - ADD_imm8s_r32( -4, R_ECX );119.1540 - store_reg( R_ECX, Rn );119.1541 + POP_realigned_r32( R_ECX );119.1542 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1543 MEM_WRITE_LONG( R_ECX, R_EAX );119.1544 sh4_x86.tstate = TSTATE_NONE;119.1545 :}119.1546 STC.L VBR, @-Rn {:119.1547 - precheck();119.1548 - check_priv_no_precheck();119.1549 - load_reg( R_ECX, Rn );119.1550 - check_walign32( R_ECX );119.1551 - ADD_imm8s_r32( -4, R_ECX );119.1552 - store_reg( R_ECX, Rn );119.1553 - load_spreg( R_EAX, R_VBR );119.1554 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1555 + check_priv();119.1556 + load_reg( R_EAX, Rn );119.1557 + check_walign32( R_EAX );119.1558 + ADD_imm8s_r32( -4, R_EAX );119.1559 + MMU_TRANSLATE_WRITE( R_EAX );119.1560 + load_spreg( R_EDX, R_VBR );119.1561 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1562 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1563 sh4_x86.tstate = TSTATE_NONE;119.1564 :}119.1565 STC.L SSR, @-Rn {:119.1566 - precheck();119.1567 - check_priv_no_precheck();119.1568 - load_reg( R_ECX, Rn );119.1569 - check_walign32( R_ECX );119.1570 - ADD_imm8s_r32( -4, R_ECX );119.1571 - store_reg( R_ECX, Rn );119.1572 - load_spreg( R_EAX, R_SSR );119.1573 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1574 + check_priv();119.1575 + load_reg( R_EAX, Rn );119.1576 + check_walign32( R_EAX );119.1577 + ADD_imm8s_r32( -4, R_EAX );119.1578 + MMU_TRANSLATE_WRITE( R_EAX );119.1579 + load_spreg( R_EDX, R_SSR );119.1580 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1581 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1582 sh4_x86.tstate = TSTATE_NONE;119.1583 :}119.1584 STC.L SPC, @-Rn {:119.1585 - precheck();119.1586 - check_priv_no_precheck();119.1587 - load_reg( R_ECX, Rn );119.1588 - check_walign32( R_ECX );119.1589 - ADD_imm8s_r32( -4, R_ECX );119.1590 - store_reg( R_ECX, Rn );119.1591 - load_spreg( R_EAX, R_SPC );119.1592 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1593 + check_priv();119.1594 + load_reg( R_EAX, Rn );119.1595 + check_walign32( R_EAX );119.1596 + ADD_imm8s_r32( -4, R_EAX );119.1597 + MMU_TRANSLATE_WRITE( R_EAX );119.1598 + load_spreg( R_EDX, R_SPC );119.1599 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1600 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1601 sh4_x86.tstate = TSTATE_NONE;119.1602 :}119.1603 STC.L SGR, @-Rn {:119.1604 - precheck();119.1605 - check_priv_no_precheck();119.1606 - load_reg( R_ECX, Rn );119.1607 - check_walign32( R_ECX );119.1608 - ADD_imm8s_r32( -4, R_ECX );119.1609 - store_reg( R_ECX, Rn );119.1610 - load_spreg( R_EAX, R_SGR );119.1611 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1612 + check_priv();119.1613 + load_reg( R_EAX, Rn );119.1614 + check_walign32( R_EAX );119.1615 + ADD_imm8s_r32( -4, R_EAX );119.1616 + MMU_TRANSLATE_WRITE( R_EAX );119.1617 + load_spreg( R_EDX, R_SGR );119.1618 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1619 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1620 sh4_x86.tstate = TSTATE_NONE;119.1621 :}119.1622 STC.L DBR, @-Rn {:119.1623 - precheck();119.1624 - check_priv_no_precheck();119.1625 - load_reg( R_ECX, Rn );119.1626 - check_walign32( R_ECX );119.1627 - ADD_imm8s_r32( -4, R_ECX );119.1628 - store_reg( R_ECX, Rn );119.1629 - load_spreg( R_EAX, R_DBR );119.1630 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1631 + check_priv();119.1632 + load_reg( R_EAX, Rn );119.1633 + check_walign32( R_EAX );119.1634 + ADD_imm8s_r32( -4, R_EAX );119.1635 + MMU_TRANSLATE_WRITE( R_EAX );119.1636 + load_spreg( R_EDX, R_DBR );119.1637 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1638 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1639 sh4_x86.tstate = TSTATE_NONE;119.1640 :}119.1641 STC.L Rm_BANK, @-Rn {:119.1642 - precheck();119.1643 - check_priv_no_precheck();119.1644 - load_reg( R_ECX, Rn );119.1645 - check_walign32( R_ECX );119.1646 - ADD_imm8s_r32( -4, R_ECX );119.1647 - store_reg( R_ECX, Rn );119.1648 - load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );119.1649 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1650 + check_priv();119.1651 + load_reg( R_EAX, Rn );119.1652 + check_walign32( R_EAX );119.1653 + ADD_imm8s_r32( -4, R_EAX );119.1654 + MMU_TRANSLATE_WRITE( R_EAX );119.1655 + load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );119.1656 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1657 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1658 sh4_x86.tstate = TSTATE_NONE;119.1659 :}119.1660 STC.L GBR, @-Rn {:119.1661 - load_reg( R_ECX, Rn );119.1662 - precheck();119.1663 - check_walign32( R_ECX );119.1664 - ADD_imm8s_r32( -4, R_ECX );119.1665 - store_reg( R_ECX, Rn );119.1666 - load_spreg( R_EAX, R_GBR );119.1667 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1668 + load_reg( R_EAX, Rn );119.1669 + check_walign32( R_EAX );119.1670 + ADD_imm8s_r32( -4, R_EAX );119.1671 + MMU_TRANSLATE_WRITE( R_EAX );119.1672 + load_spreg( R_EDX, R_GBR );119.1673 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1674 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1675 sh4_x86.tstate = TSTATE_NONE;119.1676 :}119.1677 STS FPSCR, Rn {:119.1678 @@ -2560,13 +2594,13 @@119.1679 store_reg( R_EAX, Rn );119.1680 :}119.1681 STS.L FPSCR, @-Rn {:119.1682 - load_reg( R_ECX, Rn );119.1683 - precheck();119.1684 - check_walign32( R_ECX );119.1685 - ADD_imm8s_r32( -4, R_ECX );119.1686 - store_reg( R_ECX, Rn );119.1687 - load_spreg( R_EAX, R_FPSCR );119.1688 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1689 + load_reg( R_EAX, Rn );119.1690 + check_walign32( R_EAX );119.1691 + ADD_imm8s_r32( -4, R_EAX );119.1692 + MMU_TRANSLATE_WRITE( R_EAX );119.1693 + load_spreg( R_EDX, R_FPSCR );119.1694 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1695 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1696 sh4_x86.tstate = TSTATE_NONE;119.1697 :}119.1698 STS FPUL, Rn {:119.1699 @@ -2574,13 +2608,13 @@119.1700 store_reg( R_EAX, Rn );119.1701 :}119.1702 STS.L FPUL, @-Rn {:119.1703 - load_reg( R_ECX, Rn );119.1704 - precheck();119.1705 - check_walign32( R_ECX );119.1706 - ADD_imm8s_r32( -4, R_ECX );119.1707 - store_reg( R_ECX, Rn );119.1708 - load_spreg( R_EAX, R_FPUL );119.1709 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1710 + load_reg( R_EAX, Rn );119.1711 + check_walign32( R_EAX );119.1712 + ADD_imm8s_r32( -4, R_EAX );119.1713 + MMU_TRANSLATE_WRITE( R_EAX );119.1714 + load_spreg( R_EDX, R_FPUL );119.1715 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1716 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1717 sh4_x86.tstate = TSTATE_NONE;119.1718 :}119.1719 STS MACH, Rn {:119.1720 @@ -2588,13 +2622,13 @@119.1721 store_reg( R_EAX, Rn );119.1722 :}119.1723 STS.L MACH, @-Rn {:119.1724 - load_reg( R_ECX, Rn );119.1725 - precheck();119.1726 - check_walign32( R_ECX );119.1727 - ADD_imm8s_r32( -4, R_ECX );119.1728 - store_reg( R_ECX, Rn );119.1729 - load_spreg( R_EAX, R_MACH );119.1730 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1731 + load_reg( R_EAX, Rn );119.1732 + check_walign32( R_EAX );119.1733 + ADD_imm8s_r32( -4, R_EAX );119.1734 + MMU_TRANSLATE_WRITE( R_EAX );119.1735 + load_spreg( R_EDX, R_MACH );119.1736 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1737 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1738 sh4_x86.tstate = TSTATE_NONE;119.1739 :}119.1740 STS MACL, Rn {:119.1741 @@ -2602,13 +2636,13 @@119.1742 store_reg( R_EAX, Rn );119.1743 :}119.1744 STS.L MACL, @-Rn {:119.1745 - load_reg( R_ECX, Rn );119.1746 - precheck();119.1747 - check_walign32( R_ECX );119.1748 - ADD_imm8s_r32( -4, R_ECX );119.1749 - store_reg( R_ECX, Rn );119.1750 - load_spreg( R_EAX, R_MACL );119.1751 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1752 + load_reg( R_EAX, Rn );119.1753 + check_walign32( R_EAX );119.1754 + ADD_imm8s_r32( -4, R_EAX );119.1755 + MMU_TRANSLATE_WRITE( R_EAX );119.1756 + load_spreg( R_EDX, R_MACL );119.1757 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1758 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1759 sh4_x86.tstate = TSTATE_NONE;119.1760 :}119.1761 STS PR, Rn {:119.1762 @@ -2616,13 +2650,13 @@119.1763 store_reg( R_EAX, Rn );119.1764 :}119.1765 STS.L PR, @-Rn {:119.1766 - load_reg( R_ECX, Rn );119.1767 - precheck();119.1768 - check_walign32( R_ECX );119.1769 - ADD_imm8s_r32( -4, R_ECX );119.1770 - store_reg( R_ECX, Rn );119.1771 - load_spreg( R_EAX, R_PR );119.1772 - MEM_WRITE_LONG( R_ECX, R_EAX );119.1773 + load_reg( R_EAX, Rn );119.1774 + check_walign32( R_EAX );119.1775 + ADD_imm8s_r32( -4, R_EAX );119.1776 + MMU_TRANSLATE_WRITE( R_EAX );119.1777 + load_spreg( R_EDX, R_PR );119.1778 + ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );119.1779 + MEM_WRITE_LONG( R_EAX, R_EDX );119.1780 sh4_x86.tstate = TSTATE_NONE;119.1781 :}
120.1 --- a/src/sh4/timer.c Thu Dec 20 09:56:07 2007 +0000120.2 +++ b/src/sh4/timer.c Tue Jan 15 20:50:23 2008 +0000120.3 @@ -1,5 +1,5 @@120.4 /**120.5 - * $Id: timer.c,v 1.9 2007-10-06 09:03:24 nkeynes Exp $120.6 + * $Id$120.7 *120.8 * SH4 Timer/Clock peripheral modules (CPG, TMU, RTC), combined together to120.9 * keep things simple (they intertwine a bit).
121.1 --- a/src/sh4/x86op.h Thu Dec 20 09:56:07 2007 +0000121.2 +++ b/src/sh4/x86op.h Tue Jan 15 20:50:23 2008 +0000121.3 @@ -1,5 +1,5 @@121.4 /**121.5 - * $Id: x86op.h,v 1.10 2007-09-19 09:15:18 nkeynes Exp $121.6 + * $Id$121.7 *121.8 * Definitions of x86 opcodes for use by the translator.121.9 *121.10 @@ -99,6 +99,7 @@121.11 #define R_VBR REG_OFFSET(vbr)121.12 #define R_MACH REG_OFFSET(mac)+4121.13 #define R_MACL REG_OFFSET(mac)121.14 +#define R_PC REG_OFFSET(pc)121.15 #define R_PR REG_OFFSET(pr)121.16 #define R_SGR REG_OFFSET(sgr)121.17 #define R_FPUL REG_OFFSET(fpul)121.18 @@ -233,23 +234,27 @@121.19 #define JNS_rel8(rel,label) OP(0x79); OP(rel); MARK_JMP(rel,label)121.20 #define JS_rel8(rel,label) OP(0x78); OP(rel); MARK_JMP(rel,label)121.22 +/** JMP relative 8 or 32 depending on size of rel. rel offset121.23 + * from the start of the instruction (not end)121.24 + */121.25 +#define JMP_rel(rel) if((rel)<-126||(rel)>129) { OP(0xE9); OP32((rel)-5); } else { OP(0xEB); OP((rel)-2); }121.27 -/* 32-bit long forms w/ backpatching to an exit routine */121.28 -#define JMP_exit(rel) OP(0xE9); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.29 -#define JE_exit(rel) OP(0x0F); OP(0x84); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.30 -#define JA_exit(rel) OP(0x0F); OP(0x87); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.31 -#define JAE_exit(rel) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.32 -#define JG_exit(rel) OP(0x0F); OP(0x8F); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.33 -#define JGE_exit(rel) OP(0x0F); OP(0x8D); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.34 -#define JC_exit(rel) OP(0x0F); OP(0x82); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.35 -#define JO_exit(rel) OP(0x0F); OP(0x80); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.36 -#define JNE_exit(rel) OP(0x0F); OP(0x85); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.37 -#define JNA_exit(rel) OP(0x0F); OP(0x86); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.38 -#define JNAE_exit(rel) OP(0x0F);OP(0x82); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.39 -#define JNG_exit(rel) OP(0x0F); OP(0x8E); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.40 -#define JNGE_exit(rel) OP(0x0F);OP(0x8C); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.41 -#define JNC_exit(rel) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.42 -#define JNO_exit(rel) OP(0x0F); OP(0x81); sh4_x86_add_backpatch(xlat_output); OP32(rel)121.43 +/* 32-bit long forms w/ backpatching to an exception routine */121.44 +#define JMP_exc(exc) OP(0xE9); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.45 +#define JE_exc(exc) OP(0x0F); OP(0x84); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.46 +#define JA_exc(exc) OP(0x0F); OP(0x87); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.47 +#define JAE_exc(exc) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.48 +#define JG_exc(exc) OP(0x0F); OP(0x8F); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.49 +#define JGE_exc(exc) OP(0x0F); OP(0x8D); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.50 +#define JC_exc(exc) OP(0x0F); OP(0x82); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.51 +#define JO_exc(exc) OP(0x0F); OP(0x80); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.52 +#define JNE_exc(exc) OP(0x0F); OP(0x85); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.53 +#define JNA_exc(exc) OP(0x0F); OP(0x86); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.54 +#define JNAE_exc(exc) OP(0x0F);OP(0x82); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.55 +#define JNG_exc(exc) OP(0x0F); OP(0x8E); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.56 +#define JNGE_exc(exc) OP(0x0F);OP(0x8C); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.57 +#define JNC_exc(exc) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.58 +#define JNO_exc(exc) OP(0x0F); OP(0x81); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)121.61 /* Conditional moves ebp-rel */
122.1 --- a/src/sh4/xltcache.c Thu Dec 20 09:56:07 2007 +0000122.2 +++ b/src/sh4/xltcache.c Tue Jan 15 20:50:23 2008 +0000122.3 @@ -1,5 +1,5 @@122.4 /**122.5 - * $Id: xltcache.c,v 1.11 2007-11-08 11:54:16 nkeynes Exp $122.6 + * $Id$122.7 *122.8 * Translation cache management. This part is architecture independent.122.9 *122.10 @@ -21,6 +21,7 @@122.11 #include <assert.h>122.13 #include "dreamcast.h"122.14 +#include "sh4/sh4core.h"122.15 #include "sh4/xltcache.h"122.16 #include "x86dasm/x86dasm.h"122.18 @@ -207,6 +208,35 @@122.19 return result;122.20 }122.22 +xlat_recovery_record_t xlat_get_recovery( void *code, void *native_pc, gboolean recover_after )122.23 +{122.24 + if( code != NULL ) {122.25 + xlat_cache_block_t block = BLOCK_FOR_CODE(code);122.26 + uint32_t count = block->recover_table_size;122.27 + xlat_recovery_record_t records = block->recover_table;122.28 + uint32_t posn;122.29 + if( recover_after ) {122.30 + if( records[count-1].xlat_pc <= (uintptr_t)native_pc ) {122.31 + return NULL;122.32 + }122.33 + for( posn=count-1; posn > 0; posn-- ) {122.34 + if( records[posn-1].xlat_pc < (uintptr_t)native_pc ) {122.35 + return &records[posn];122.36 + }122.37 + }122.38 + return &records[0]; // shouldn't happen122.39 + } else {122.40 + for( posn = 1; posn < count; posn++ ) {122.41 + if( records[posn].xlat_pc >= (uintptr_t)native_pc ) {122.42 + return &records[posn-1];122.43 + }122.44 + }122.45 + return &records[count-1];122.46 + }122.47 + }122.48 + return NULL;122.49 +}122.50 +122.51 void **xlat_get_lut_entry( sh4addr_t address )122.52 {122.53 void **page = xlat_lut[XLAT_LUT_PAGE(address)];122.54 @@ -230,6 +260,16 @@122.55 return xlt->size;122.56 }122.58 +uint32_t xlat_get_code_size( void *block )122.59 +{122.60 + xlat_cache_block_t xlt = (xlat_cache_block_t)(((char *)block)-sizeof(struct xlat_cache_block));122.61 + if( xlt->recover_table == NULL ) {122.62 + return xlt->size;122.63 + } else {122.64 + return ((uint8_t *)xlt->recover_table) - ((uint8_t *)block);122.65 + }122.66 +}122.67 +122.68 /**122.69 * Cut the specified block so that it has the given size, with the remaining data122.70 * forming a new free block. If the free block would be less than the minimum size,
123.1 --- a/src/sh4/xltcache.h Thu Dec 20 09:56:07 2007 +0000123.2 +++ b/src/sh4/xltcache.h Tue Jan 15 20:50:23 2008 +0000123.3 @@ -1,5 +1,5 @@123.4 /**123.5 - * $Id: xltcache.h,v 1.7 2007-10-06 09:03:24 nkeynes Exp $123.6 + * $Id$123.7 *123.8 * Translation cache support (architecture independent)123.9 *123.10 @@ -19,12 +19,34 @@123.11 #include "dream.h"123.12 #include "mem.h"123.14 -typedef struct xlat_cache_block {123.15 +#ifndef lxdream_xltcache_H123.16 +#define lxdream_xltcache_H123.17 +123.18 +/**123.19 + * For now, recovery is purely a matter of mapping native pc => sh4 pc,123.20 + * and updating sh4r.pc & sh4r.slice_cycles accordingly. In future more123.21 + * detailed recovery may be required if the translator optimizes more123.22 + * agressively.123.23 + *123.24 + * The recovery table contains (at least) one entry per abortable instruction,123.25 + *123.26 + */123.27 +typedef struct xlat_recovery_record {123.28 + uintptr_t xlat_pc; // native (translated) pc123.29 + uint32_t sh4_icount; // instruction number of the corresponding SH4 instruction123.30 + // (0 = first instruction, 1 = second instruction, ... )123.31 +} *xlat_recovery_record_t;123.32 +123.33 +struct xlat_cache_block {123.34 int active; /* 0 = deleted, 1 = normal. 2 = accessed (temp-space only) */123.35 uint32_t size;123.36 void **lut_entry; /* For deletion */123.37 + xlat_recovery_record_t recover_table;123.38 + uint32_t recover_table_size;123.39 unsigned char code[0];123.40 -} *xlat_cache_block_t;123.41 +} __attribute__((packed));123.42 +123.43 +typedef struct xlat_cache_block *xlat_cache_block_t;123.45 /**123.46 * Initialize the translation cache123.47 @@ -74,18 +96,53 @@123.48 void *xlat_get_code( sh4addr_t address );123.50 /**123.51 + * Retrieve the recovery record corresponding to the given123.52 + * native address, or NULL if there is no recovery code for the address.123.53 + * @param code The code block containing the recovery table.123.54 + * @param native_pc A pointer that must be within the currently executing123.55 + * @param recover_after If TRUE, return the first record after the given pc, otherwise123.56 + * return the first record before or equal to the given pc.123.57 + * translation block.123.58 + */123.59 +struct xlat_recovery_record *xlat_get_recovery( void *code, void *native_pc, gboolean recover_after );123.60 +123.61 +/**123.62 + * Retrieve the entry point for the translated code corresponding to the given123.63 + * SH4 virtual address, or NULL if there is no code for the address.123.64 + * If the virtual address cannot be resolved, this method will raise a TLB miss123.65 + * exception, and return NULL.123.66 + */123.67 +void *xlat_get_code_by_vma( sh4vma_t address );123.68 +123.69 +/**123.70 * Retrieve the address of the lookup table entry corresponding to the123.71 * given SH4 address.123.72 */123.73 void **xlat_get_lut_entry( sh4addr_t address );123.75 /**123.76 - * Retrieve the size of the code block starting at the specified pointer. If the123.77 + * Retrieve the current host address of the running translated code block.123.78 + * @return the host PC, or null if there is no currently executing translated123.79 + * block (or the stack is corrupted)123.80 + * Note: this method is implemented in host-specific asm.123.81 + */123.82 +void *xlat_get_native_pc();123.83 +123.84 +/**123.85 + * Retrieve the size of the block starting at the specified pointer. If the123.86 * pointer is not a valid code block, the return value is undefined.123.87 */123.88 uint32_t xlat_get_block_size( void *ptr );123.90 /**123.91 + * Retrieve the size of the code in the block starting at the specified123.92 + * pointer. Effectively this is xlat_get_block_size() minus the size of123.93 + * the recovery table. If the pointer is not a valid code block, the123.94 + * return value is undefined.123.95 + */123.96 +uint32_t xlat_get_code_size( void *ptr );123.97 +123.98 +/**123.99 * Flush the code cache for the page containing the given address123.100 */123.101 void xlat_flush_page( sh4addr_t address );123.102 @@ -108,3 +165,5 @@123.103 * Check the internal integrity of the cache123.104 */123.105 void xlat_check_integrity();123.106 +123.107 +#endif /* lxdream_xltcache_H */
124.1 --- a/src/syscall.c Thu Dec 20 09:56:07 2007 +0000124.2 +++ b/src/syscall.c Tue Jan 15 20:50:23 2008 +0000124.3 @@ -1,5 +1,5 @@124.4 /**124.5 - * $Id: syscall.c,v 1.1 2006-03-13 12:38:34 nkeynes Exp $124.6 + * $Id$124.7 *124.8 * Routines to add hook functions that are callable from the SH4124.9 *124.10 @@ -19,7 +19,7 @@124.11 #include "dream.h"124.12 #include "mem.h"124.13 #include "syscall.h"124.14 -#include "sh4/sh4core.h"124.15 +#include "sh4/sh4.h"124.18 struct syscall_hook {
125.1 --- a/src/syscall.h Thu Dec 20 09:56:07 2007 +0000125.2 +++ b/src/syscall.h Tue Jan 15 20:50:23 2008 +0000125.3 @@ -1,5 +1,5 @@125.4 /**125.5 - * $Id: syscall.h,v 1.3 2006-08-07 13:18:16 nkeynes Exp $125.6 + * $Id$125.7 *125.8 * Generic syscall support - ability to add hooks into SH4 code to call out125.9 * to the emu.
126.1 --- a/src/test/testsh4x86.c Thu Dec 20 09:56:07 2007 +0000126.2 +++ b/src/test/testsh4x86.c Tue Jan 15 20:50:23 2008 +0000126.3 @@ -1,5 +1,5 @@126.4 /**126.5 - * $Id: testsh4x86.c,v 1.6 2007-11-08 10:49:16 nkeynes Exp $126.6 + * $Id$126.7 *126.8 * Test cases for the SH4 => x86 translator core. Takes as126.9 * input a binary SH4 object (and VMA), generates the126.10 @@ -25,6 +25,11 @@126.11 #include "x86dasm/x86dasm.h"126.12 #include "sh4/sh4trans.h"126.13 #include "sh4/sh4core.h"126.14 +#include "sh4/sh4mmio.h"126.15 +126.16 +struct mmio_region mmio_region_MMU;126.17 +struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];126.18 +int sh4_breakpoint_count = 0;126.20 #define MAX_INS_SIZE 32126.22 @@ -36,6 +41,7 @@126.23 char *output_file = NULL;126.24 uint32_t start_addr = 0x8C010000;126.25 uint32_t sh4_cpu_period = 5;126.26 +sh4ptr_t sh4_main_ram;126.27 FILE *in;126.29 char *inbuf;126.30 @@ -64,30 +70,32 @@126.31 // Stubs126.32 gboolean sh4_execute_instruction( ) { }126.33 void sh4_accept_interrupt() {}126.34 -void sh4_set_breakpoint( uint32_t pc, int type ) { }126.35 -gboolean sh4_clear_breakpoint( uint32_t pc, int type ) { }126.36 +void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type ) { }126.37 +gboolean sh4_clear_breakpoint( uint32_t pc, breakpoint_type_t type ) { }126.38 +gboolean sh4_is_using_xlat() { return TRUE; }126.39 int sh4_get_breakpoint( uint32_t pc ) { }126.40 void event_execute() {}126.41 void TMU_run_slice( uint32_t nanos ) {}126.42 void SCIF_run_slice( uint32_t nanos ) {}126.43 -void MMU_ldtlb(void) {}126.44 void sh4_write_byte( uint32_t addr, uint32_t val ) {}126.45 void sh4_write_word( uint32_t addr, uint32_t val ) {}126.46 void sh4_write_long( uint32_t addr, uint32_t val ) {}126.47 -void sh4_flush_store_queue( uint32_t addr ) {}126.48 +void mem_copy_to_sh4( sh4addr_t addr, sh4ptr_t src, size_t size ) { }126.49 void sh4_write_sr( uint32_t val ) { }126.50 void syscall_invoke( uint32_t val ) { }126.51 +void dreamcast_stop() {}126.52 +void dreamcast_reset() {}126.53 uint32_t sh4_read_sr( void ) { }126.54 +gboolean sh4_raise_reset( int exc ) {}126.55 gboolean sh4_raise_exception( int exc ) {}126.56 +gboolean sh4_raise_tlb_exception( int exc ) {}126.57 gboolean sh4_raise_trap( int exc ) {}126.58 void sh4_sleep() { }126.59 void sh4_fsca( uint32_t angle, float *fr ) { }126.60 void sh4_ftrv( float *fv, float *xmtrx ) { }126.61 void signsat48(void) { }126.62 -uint16_t *sh4_icache = NULL;126.63 -uint32_t sh4_icache_addr = 0;126.64 gboolean gui_error_dialog( const char *fmt, ... ) { }126.65 -126.66 +struct sh4_icache_struct sh4_icache;126.68 void usage()126.69 {
127.1 --- a/src/test/testxlt.c Thu Dec 20 09:56:07 2007 +0000127.2 +++ b/src/test/testxlt.c Tue Jan 15 20:50:23 2008 +0000127.3 @@ -1,3 +1,21 @@127.4 +/**127.5 + * $Id$127.6 + *127.7 + * Translation cache test functions127.8 + *127.9 + * Copyright (c) 2005 Nathan Keynes.127.10 + *127.11 + * This program is free software; you can redistribute it and/or modify127.12 + * it under the terms of the GNU General Public License as published by127.13 + * the Free Software Foundation; either version 2 of the License, or127.14 + * (at your option) any later version.127.15 + *127.16 + * This program is distributed in the hope that it will be useful,127.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of127.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the127.19 + * GNU General Public License for more details.127.20 + */127.21 +127.22 #include <assert.h>127.23 #include "sh4/xltcache.h"127.24 #include "dreamcast.h"
128.1 --- a/src/tools/actparse.c Thu Dec 20 09:56:07 2007 +0000128.2 +++ b/src/tools/actparse.c Tue Jan 15 20:50:23 2008 +0000128.3 @@ -1,3 +1,21 @@128.4 +/**128.5 + * $Id$128.6 + *128.7 + * gendec action file parser.128.8 + *128.9 + * Copyright (c) 2005 Nathan Keynes.128.10 + *128.11 + * This program is free software; you can redistribute it and/or modify128.12 + * it under the terms of the GNU General Public License as published by128.13 + * the Free Software Foundation; either version 2 of the License, or128.14 + * (at your option) any later version.128.15 + *128.16 + * This program is distributed in the hope that it will be useful,128.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of128.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the128.19 + * GNU General Public License for more details.128.20 + */128.21 +128.22 #include <stdlib.h>128.23 #include <stdio.h>128.24 #include <string.h>
129.1 --- a/src/tools/gendec.c Thu Dec 20 09:56:07 2007 +0000129.2 +++ b/src/tools/gendec.c Tue Jan 15 20:50:23 2008 +0000129.3 @@ -1,5 +1,5 @@129.4 /**129.5 - * $Id: gendec.c,v 1.2 2007-10-06 08:48:47 nkeynes Exp $129.6 + * $Id$129.7 *129.8 * Parse the instruction and action files and generate an appropriate129.9 * instruction decoder.
130.1 --- a/src/tools/gendec.h Thu Dec 20 09:56:07 2007 +0000130.2 +++ b/src/tools/gendec.h Tue Jan 15 20:50:23 2008 +0000130.3 @@ -1,5 +1,5 @@130.4 /**130.5 - * $Id: gendec.h,v 1.2 2007-10-06 08:48:47 nkeynes Exp $130.6 + * $Id$130.7 *130.8 * mem is responsible for creating and maintaining the overall system memory130.9 * map, as visible from the SH4 processor. (Note the ARM has a different map)
131.1 --- a/src/tools/genglsl.c Thu Dec 20 09:56:07 2007 +0000131.2 +++ b/src/tools/genglsl.c Tue Jan 15 20:50:23 2008 +0000131.3 @@ -1,5 +1,5 @@131.4 /**131.5 - * $Id: genglsl.c,v 1.1 2007-09-28 07:24:14 nkeynes Exp $131.6 + * $Id$131.7 *131.8 * Trivial tool to take two shader source files and dump them out in131.9 * a C file with appropriate escaping.
132.1 --- a/src/tools/insparse.c Thu Dec 20 09:56:07 2007 +0000132.2 +++ b/src/tools/insparse.c Tue Jan 15 20:50:23 2008 +0000132.3 @@ -1,3 +1,21 @@132.4 +/**132.5 + * $Id$132.6 + *132.7 + * gendec instruction definitions parser132.8 + *132.9 + * Copyright (c) 2005 Nathan Keynes.132.10 + *132.11 + * This program is free software; you can redistribute it and/or modify132.12 + * it under the terms of the GNU General Public License as published by132.13 + * the Free Software Foundation; either version 2 of the License, or132.14 + * (at your option) any later version.132.15 + *132.16 + * This program is distributed in the hope that it will be useful,132.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of132.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the132.19 + * GNU General Public License for more details.132.20 + */132.21 +132.22 #include <stdlib.h>132.23 #include <stdio.h>132.24 #include <string.h>
133.1 --- a/src/util.c Thu Dec 20 09:56:07 2007 +0000133.2 +++ b/src/util.c Tue Jan 15 20:50:23 2008 +0000133.3 @@ -1,5 +1,5 @@133.4 /**133.5 - * $Id: util.c,v 1.14 2007-11-08 11:54:16 nkeynes Exp $133.6 + * $Id$133.7 *133.8 * Miscellaneous utility functions.133.9 *133.10 @@ -31,7 +31,7 @@133.11 #include "dream.h"133.12 #include "display.h"133.13 #include "gui.h"133.14 -#include "sh4/sh4core.h"133.15 +#include "sh4/sh4.h"133.17 char *msg_levels[] = { "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" };133.18 int global_msg_level = EMIT_WARN;133.19 @@ -278,6 +278,30 @@133.20 return buffer;133.21 }133.23 +int get_log_level_from_string( const gchar *str )133.24 +{133.25 + switch( tolower(str[0]) ) {133.26 + case 'd': return EMIT_DEBUG;133.27 + case 'e': return EMIT_ERR;133.28 + case 'f': return EMIT_FATAL;133.29 + case 'i': return EMIT_INFO;133.30 + case 't': return EMIT_TRACE;133.31 + case 'w': return EMIT_WARN;133.32 + default: return -1;133.33 + }133.34 +}133.35 +133.36 +gboolean set_global_log_level( const gchar *str )133.37 +{133.38 + int l = get_log_level_from_string(str);133.39 + if( l == -1 ) {133.40 + return FALSE;133.41 + } else {133.42 + global_msg_level = l;133.43 + return TRUE;133.44 + }133.45 +}133.46 +133.47 void log_message( void *ptr, int level, const gchar *source, const char *msg, ... )133.48 {133.49 char buf[20];
134.1 --- a/src/watch.c Thu Dec 20 09:56:07 2007 +0000134.2 +++ b/src/watch.c Tue Jan 15 20:50:23 2008 +0000134.3 @@ -1,3 +1,21 @@134.4 +/**134.5 + * $Id$134.6 + *134.7 + * Watchpoint support (for debugging)134.8 + *134.9 + * Copyright (c) 2005 Nathan Keynes.134.10 + *134.11 + * This program is free software; you can redistribute it and/or modify134.12 + * it under the terms of the GNU General Public License as published by134.13 + * the Free Software Foundation; either version 2 of the License, or134.14 + * (at your option) any later version.134.15 + *134.16 + * This program is distributed in the hope that it will be useful,134.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of134.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the134.19 + * GNU General Public License for more details.134.20 + */134.21 +134.22 #include <stdlib.h>134.23 #include <string.h>134.24 #include "mem.h"
135.1 --- a/src/x86dasm/x86dasm.c Thu Dec 20 09:56:07 2007 +0000135.2 +++ b/src/x86dasm/x86dasm.c Tue Jan 15 20:50:23 2008 +0000135.3 @@ -1,5 +1,5 @@135.4 /**135.5 - * $Id: x86dasm.c,v 1.5 2007-10-31 11:53:35 nkeynes Exp $135.6 + * $Id$135.7 *135.8 * Wrapper around i386-dis to supply the same behaviour as the other135.9 * disassembly functions.135.10 @@ -22,7 +22,7 @@135.11 #include "x86dasm.h"135.12 #include "bfd.h"135.13 #include "dis-asm.h"135.14 -#include "sh4/sh4core.h"135.15 +#include "sh4/sh4.h"135.16 #include "sh4/sh4trans.h"135.18 extern const struct reg_desc_struct sh4_reg_map[];135.19 @@ -43,7 +43,7 @@135.21 void xlat_disasm_block( FILE *out, void *block )135.22 {135.23 - uint32_t buflen = xlat_get_block_size(block);135.24 + uint32_t buflen = xlat_get_code_size(block);135.25 x86_set_symtab( NULL, 0 );135.26 x86_disasm_block( out, block, buflen );135.27 }
136.1 --- a/src/x86dasm/x86dasm.h Thu Dec 20 09:56:07 2007 +0000136.2 +++ b/src/x86dasm/x86dasm.h Tue Jan 15 20:50:23 2008 +0000136.3 @@ -1,5 +1,5 @@136.4 /**136.5 - * $Id: x86dasm.h,v 1.5 2007-10-31 09:07:25 nkeynes Exp $136.6 + * $Id$136.7 *136.8 * Wrapper around i386-dis to supply the same behaviour as the other136.9 * disassembly functions.
137.1 --- a/test/Makefile.in Thu Dec 20 09:56:07 2007 +0000137.2 +++ b/test/Makefile.in Tue Jan 15 20:50:23 2008 +0000137.3 @@ -17,6 +17,7 @@137.4 ARMOBJCOPY = @ARMOBJCOPY@137.6 RUNTEST = ../src/lxdream -c ./lxdream.rc -puh -A null137.7 +RUNTESTX = ../src/lxdream -c ./lxdream.rc -xpuh -A null137.10 # cygwin137.11 @@ -62,10 +63,11 @@137.12 all: build-tests137.14 check: build-tests137.15 - cat testta.data testta2.data testta3.data testta4.data testta5.data | $(RUNTEST) testta137.16 $(RUNTEST) testsh4137.17 + $(RUNTESTX) testsh4137.18 $(RUNTEST) testmmu137.19 $(RUNTEST) testregs137.20 + cat testta.data testta2.data testta3.data testta4.data testta5.data | $(RUNTEST) testta137.21 # $(RUNTEST) testide -d ../disc/test.nrg137.24 @@ -78,7 +80,7 @@137.25 sh4/mac.s \137.26 sh4/rot.so sh4/shl.so sh4/shld.so sh4/sub.so sh4/subc.so \137.27 sh4/trapa.so sh4/tas.so sh4/xtrct.so \137.28 - sh4/excslot.so sh4/undef.so137.29 + sh4/excslot.so sh4/undef.so sh4/tlb.so137.30 $(SH4CC) $(SH4LDFLAGS) $^ -o $@ $(SH4LIBS)137.31 $(SH4OBJCOPY) testsh4 testsh4.bin
138.1 --- a/test/asic.c Thu Dec 20 09:56:07 2007 +0000138.2 +++ b/test/asic.c Tue Jan 15 20:50:23 2008 +0000138.3 @@ -1,5 +1,5 @@138.4 /**138.5 - * $Id: asic.c,v 1.2 2006-08-04 01:38:30 nkeynes Exp $138.6 + * $Id$138.7 *138.8 * General ASIC support code138.9 *
139.1 --- a/test/bin2c.c Thu Dec 20 09:56:07 2007 +0000139.2 +++ b/test/bin2c.c Tue Jan 15 20:50:23 2008 +0000139.3 @@ -3,7 +3,7 @@139.5 (c)2000 Dan Potter139.7 - $Id: bin2c.c,v 1.1 2006-07-11 01:35:23 nkeynes Exp $139.8 + $Id$139.9 Note: Licensed under the new BSD license, see README.KOS -NK139.10 */
140.1 --- a/test/dma.h Thu Dec 20 09:56:07 2007 +0000140.2 +++ b/test/dma.h Tue Jan 15 20:50:23 2008 +0000140.3 @@ -1,5 +1,5 @@140.4 /**140.5 - * $Id: dma.h,v 1.1 2006-07-11 01:35:23 nkeynes Exp $140.6 + * $Id$140.7 *140.8 * DMA support code140.9 *
141.1 --- a/test/dmac.c Thu Dec 20 09:56:07 2007 +0000141.2 +++ b/test/dmac.c Tue Jan 15 20:50:23 2008 +0000141.3 @@ -1,5 +1,5 @@141.4 /**141.5 - * $Id: dmac.c,v 1.2 2006-08-02 04:13:15 nkeynes Exp $141.6 + * $Id$141.7 *141.8 * DMA support code141.9 *
142.1 --- a/test/pvr.c Thu Dec 20 09:56:07 2007 +0000142.2 +++ b/test/pvr.c Tue Jan 15 20:50:23 2008 +0000142.3 @@ -1,5 +1,5 @@142.4 /**142.5 - * $Id: pvr.c,v 1.5 2007-01-24 08:13:18 nkeynes Exp $142.6 + * $Id$142.7 *142.8 * PVR support code142.9 *
143.1 --- a/test/pvr.h Thu Dec 20 09:56:07 2007 +0000143.2 +++ b/test/pvr.h Tue Jan 15 20:50:23 2008 +0000143.3 @@ -1,5 +1,5 @@143.4 /**143.5 - * $Id: pvr.h,v 1.3 2006-08-18 09:33:19 nkeynes Exp $143.6 + * $Id$143.7 *143.8 * PVR support code143.9 *
144.1 --- a/test/rendload.c Thu Dec 20 09:56:07 2007 +0000144.2 +++ b/test/rendload.c Tue Jan 15 20:50:23 2008 +0000144.3 @@ -1,5 +1,5 @@144.4 /**144.5 - * $Id: rendload.c,v 1.1 2007-01-16 11:09:39 nkeynes Exp $144.6 + * $Id$144.7 *144.8 * Scene-save loader support. This is the other side of rendsave.c144.9 *
145.1 --- a/test/sh4/inc.s Thu Dec 20 09:56:07 2007 +0000145.2 +++ b/test/sh4/inc.s Tue Jan 15 20:50:23 2008 +0000145.3 @@ -240,6 +240,24 @@145.4 L3:145.5 .endm145.7 +.macro assert_tlb_exc_caught testname, expectpc, expectvpn145.8 +LOCAL L1, L2, L3145.9 + mov.l L1, r3145.10 + mov.l \testname, r4145.11 + mov r12, r5145.12 + mov.l L2, r6145.13 + mov.l \expectvpn, r7145.14 + jsr @r3145.15 + nop145.16 + add r0, r13145.17 + bra L3145.18 + nop145.19 +.align 4145.20 +L1: .long _assert_exception_caught145.21 +L2: .long \expectpc145.22 +L3:145.23 +.endm145.24 +145.25 .align 2145.26 assert_t_set_message:145.27 .string "Expected T=1 but was 0"
146.1 --- a/test/sh4/testsh4.c Thu Dec 20 09:56:07 2007 +0000146.2 +++ b/test/sh4/testsh4.c Tue Jan 15 20:50:23 2008 +0000146.3 @@ -1,4 +1,5 @@146.4 #include <stdio.h>146.5 +#include "../lib.h"146.7 int total_tests = 0;146.8 int total_fails = 0;146.9 @@ -42,6 +43,29 @@146.10 }146.11 }146.13 +int assert_tlb_exception_caught( char *testname, int number, unsigned int expectedpc,146.14 + unsigned int vpn )146.15 +{146.16 + if( assert_exception_caught(testname, number, expectedpc) == 1 ) {146.17 + return 1;146.18 + }146.19 +146.20 + unsigned int pteh = long_read(0xFF000000);146.21 + if( (pteh & 0xFFFFFC00) != (vpn & 0xFFFFFC00) ) {146.22 + fprintf(stderr, "%s: Test %d failed: Expected PTEH.VPN = %08X, but was %08X\n",146.23 + testname, number, (vpn>>10), (pteh>>10) );146.24 + return 1;146.25 + }146.26 +146.27 + unsigned int tea = long_read(0xFF00000C);146.28 + if( tea != vpn ) {146.29 + fprintf(stderr, "%s: Test %d failed: Expected TEA = %08X, but was %08X\n",146.30 + testname, number, vpn, tea );146.31 + return 1;146.32 + }146.33 + return 0;146.34 +}146.35 +146.36 int main()146.37 {146.38 fprintf( stdout, "Instruction tests...\n" );146.39 @@ -77,6 +101,7 @@146.40 fprintf( stdout, "Exception tests...\n" );146.41 test_slot_illegal();146.42 test_undefined();146.43 + test_tlb();146.44 remove_interrupt_handler();146.46 fprintf( stdout, "Total: %d/%d tests passed (%d%%)\n", total_tests-total_fails,
147.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000147.2 +++ b/test/sh4/tlb.s Tue Jan 15 20:50:23 2008 +0000147.3 @@ -0,0 +1,165 @@147.4 +.section .text147.5 +.include "sh4/inc.s"147.6 +!147.7 +! Test for correct UTLB operation.147.8 +!147.9 +! Note we don't test triggering a TLB multiple-hit exception - it's a reset147.10 +! rather than a regular exception.147.11 +147.12 +.global _test_tlb147.13 +_test_tlb:147.14 + start_test147.15 +147.16 +! Turn on AT, and flush the current TLB (if any)147.17 +! Initialize to SV=0, SQMD=0, URB=URC=LRUI=0147.18 + mov.l test_tlb_mmucr, r0147.19 + mov #5, r1147.20 + mov.l r1, @r0147.21 +147.22 +! Privileged mode tests first (much easier)147.23 + add #1, r12147.24 + mov.l test_tlb1_pteh, r1147.25 + mov.l test_tlb_pteh, r2147.26 + mov.l r1, @r2147.27 + mov.l test_tlb1_ptel, r1147.28 + mov.l test_tlb_ptel, r2147.29 + mov.l r1, @r2147.30 + ldtlb147.31 +147.32 +! Simple read147.33 + mov.l test_tlb1_direct, r3147.34 + mov #42, r2147.35 + mov.l r2, @r3147.36 + mov.l test_tlb1_mmu, r0147.37 + mov.l @r0, r1147.38 + cmp/eq r1, r2147.39 + bt test_tlb_2147.40 + fail test_tlb_str_k147.41 + bra test_tlb_2147.42 + nop147.43 +test_tlb1_pteh:147.44 + .long 0x12345012147.45 +test_tlb1_ptel:147.46 + .long 0x005F8120147.47 +147.48 +test_tlb_2:147.49 + ! Trigger an initial-page-write exception147.50 + add #1, r12147.51 + expect_exc 0x00000080147.52 + mov.l test_tlb1_mmu, r0147.53 +test_tlb2_exc:147.54 + mov.l r0, @r0147.55 + assert_tlb_exc_caught test_tlb_str_k test_tlb2_exc test_tlb1_mmu147.56 +147.57 +test_tlb_3:147.58 + ! Trigger a missing page read exception by invalidation147.59 + add #1, r12147.60 + mov.l test_tlb3_addr, r1147.61 + mov.l test_tlb3_data, r2147.62 + mov.l r2, @r1147.63 +147.64 + expect_exc 0x00000040147.65 + mov.l test_tlb1_mmu, r0147.66 +test_tlb3_exc:147.67 + mov.l @r0, r2147.68 + assert_tlb_exc_caught test_tlb_str_k, test_tlb3_exc, test_tlb1_mmu147.69 + bra test_tlb_4147.70 + nop147.71 +147.72 +test_tlb3_addr:147.73 + .long 0xF6000F80147.74 +test_tlb3_data:147.75 + .long 0x12345212147.76 +147.77 +test_tlb_4:147.78 + ! Test missing page write exception on the same page147.79 + add #1, r12147.80 + expect_exc 0x00000060147.81 + mov.l test_tlb1_mmu, r0147.82 +test_tlb4_exc:147.83 + mov.l r2, @r0147.84 + assert_tlb_exc_caught test_tlb_str_k, test_tlb4_exc, test_tlb1_mmu147.85 +147.86 +test_tlb_5: ! Test initial write exception147.87 + add #1, r12147.88 +147.89 + mov.l test_tlb5_addr, r1147.90 + mov.l test_tlb5_data, r2147.91 + mov.l r2, @r1147.92 +147.93 + expect_exc 0x00000080147.94 + mov.l test_tlb1_mmu, r0147.95 + mov #63, r3147.96 +test_tlb5_exc:147.97 + mov.l r3, @r0147.98 + assert_tlb_exc_caught test_tlb_str_k, test_tlb5_exc, test_tlb1_mmu147.99 + mov.l test_tlb1_direct, r3147.100 + mov.l @r3, r4147.101 + mov #42, r2147.102 + cmp/eq r2, r4147.103 + bf test_tlb5_fail147.104 + mov.l test_tlb1_mmu, r0147.105 + mov.l @r0, r3147.106 + cmp/eq r2, r3147.107 + bt test_tlb_6147.108 +test_tlb5_fail:147.109 + fail test_tlb_str_k147.110 +147.111 +test_tlb5_addr:147.112 + .long 0xF6000000147.113 +test_tlb5_data:147.114 + .long 0x12345112147.115 +147.116 +test_tlb_6:! Test successful write.147.117 + add #1, r12147.118 +147.119 + mov.l test_tlb6_addr, r1147.120 + mov.l test_tlb6_data, r2147.121 + mov.l r2, @r1147.122 +147.123 + mov.l test_tlb1_mmu, r0147.124 + mov #77, r3147.125 + mov.l r3, @r0147.126 + mov.l test_tlb1_direct, r1147.127 + mov.l @r1, r2147.128 + cmp/eq r2, r3147.129 + bt test_tlb_7147.130 + fail test_tlb_str_k147.131 + bra test_tlb_7147.132 + nop147.133 +147.134 +test_tlb_7:147.135 + bra test_tlb_end147.136 + nop147.137 +147.138 +test_tlb6_addr:147.139 + .long 0xF6000F80147.140 +test_tlb6_data:147.141 + .long 0x12345312147.142 +147.143 +147.144 +test_tlb1_mmu:147.145 + .long 0x12345040147.146 +test_tlb1_direct:147.147 + .long 0xA05F8040 ! Display border colour147.148 +147.149 +test_tlb_end:147.150 + xor r0, r0147.151 + mov.l test_tlb_mmucr, r1147.152 + mov.l r0, @r1147.153 +147.154 + end_test test_tlb_str_k147.155 +147.156 +test_tlb_mmucr:147.157 + .long 0xFF000010147.158 +test_tlb_pteh:147.159 + .long 0xFF000000147.160 +test_tlb_ptel:147.161 + .long 0xFF000004147.162 +test_tlb_tea:147.163 + .long 0xFF00000C147.164 +test_tlb_str:147.165 + .string "TLB"147.166 +.align 4147.167 +test_tlb_str_k:147.168 + .long test_tlb_str
148.1 --- a/test/testdata.c Thu Dec 20 09:56:07 2007 +0000148.2 +++ b/test/testdata.c Tue Jan 15 20:50:23 2008 +0000148.3 @@ -1,5 +1,5 @@148.4 /**148.5 - * $Id: testdata.c,v 1.5 2007-01-31 11:01:58 nkeynes Exp $148.6 + * $Id$148.7 *148.8 * Test data loader.148.9 *
149.1 --- a/test/testdata.h Thu Dec 20 09:56:07 2007 +0000149.2 +++ b/test/testdata.h Tue Jan 15 20:50:23 2008 +0000149.3 @@ -1,5 +1,5 @@149.4 /*149.5 - * $Id: testdata.h,v 1.3 2007-01-03 09:05:13 nkeynes Exp $149.6 + * $Id$149.7 *149.8 * Test data loader149.9 *
150.1 --- a/test/testdisp.c Thu Dec 20 09:56:07 2007 +0000150.2 +++ b/test/testdisp.c Tue Jan 15 20:50:23 2008 +0000150.3 @@ -1,5 +1,5 @@150.4 /**150.5 - * $Id: testdisp.c,v 1.3 2007-01-11 06:53:31 nkeynes Exp $150.6 + * $Id$150.7 *150.8 * Display (2D) tests. Mainly tests video timing / sync (obviously150.9 * it can't actually test display output since there's no way of
151.1 --- a/test/testide.c Thu Dec 20 09:56:07 2007 +0000151.2 +++ b/test/testide.c Tue Jan 15 20:50:23 2008 +0000151.3 @@ -1,5 +1,5 @@151.4 /**151.5 - * $Id: testide.c,v 1.6 2007-01-03 09:05:13 nkeynes Exp $151.6 + * $Id$151.7 *151.8 * IDE interface test cases. Covers all (known) IDE registers in the151.9 * 5F7000 - 5F74FF range including DMA, but does not cover any GD-Rom
152.1 --- a/test/testregs.c Thu Dec 20 09:56:07 2007 +0000152.2 +++ b/test/testregs.c Tue Jan 15 20:50:23 2008 +0000152.3 @@ -1,5 +1,5 @@152.4 /**152.5 - * $Id: testregs.c,v 1.4 2007-01-31 11:00:25 nkeynes Exp $152.6 + * $Id$152.7 *152.8 * Register mask tests. These are simple "write value to register and check152.9 * that we read back what we expect" tests.
153.1 --- a/test/testrend.c Thu Dec 20 09:56:07 2007 +0000153.2 +++ b/test/testrend.c Tue Jan 15 20:50:23 2008 +0000153.3 @@ -1,5 +1,5 @@153.4 /**153.5 - * $Id: testrend.c,v 1.4 2007-01-31 11:02:50 nkeynes Exp $153.6 + * $Id$153.7 *153.8 * Renderer test cases153.9 *
.