Search
lxdream.org :: lxdream :: r586:2a3ba82cf243
lxdream 0.9.1
released Jun 29
Download Now
changeset586:2a3ba82cf243
parent553:4e6166258c22
child587:739a3136f269
authornkeynes
dateTue Jan 15 20:50:23 2008 +0000 (16 years ago)
Merged lxdream-mmu r570:596 to trunk
Makefile.in
aclocal.m4
config.h.in
configure
configure.in
src/Makefile.am
src/Makefile.in
src/aica/aica.c
src/aica/aica.h
src/aica/armcore.c
src/aica/armcore.h
src/aica/armdasm.c
src/aica/armdasm.h
src/aica/armmem.c
src/aica/audio.c
src/aica/audio.h
src/asic.c
src/asic.h
src/bios.c
src/bootstrap.c
src/bootstrap.h
src/clock.h
src/config.c
src/config.h
src/cpu.h
src/dcload.c
src/display.c
src/display.h
src/dream.h
src/dreamcast.c
src/dreamcast.h
src/drivers/audio_esd.c
src/drivers/audio_null.c
src/drivers/cd_linux.c
src/drivers/cd_none.c
src/drivers/gl_common.c
src/drivers/gl_common.h
src/drivers/gl_fbo.c
src/drivers/gl_sl.c
src/drivers/video_glx.c
src/drivers/video_glx.h
src/drivers/video_gtk.c
src/drivers/video_null.c
src/eventq.c
src/eventq.h
src/gdrom/cdi.c
src/gdrom/cdi.h
src/gdrom/gdi.c
src/gdrom/gdimage.c
src/gdrom/gdrom.c
src/gdrom/gdrom.h
src/gdrom/ide.c
src/gdrom/ide.h
src/gdrom/nrg.c
src/gdrom/packet.h
src/gtkui/ctrl_dlg.c
src/gtkui/debug_win.c
src/gtkui/dump_win.c
src/gtkui/gdrom_menu.c
src/gtkui/gtkcb.c
src/gtkui/gtkui.c
src/gtkui/gtkui.h
src/gtkui/main_win.c
src/gtkui/mmio_win.c
src/gtkui/path_dlg.c
src/gui.h
src/loader.c
src/loader.h
src/lxdream.h
src/main.c
src/maple/controller.c
src/maple/controller.h
src/maple/maple.c
src/maple/maple.h
src/mem.c
src/mem.h
src/mmio.h
src/pvr2/pvr2.c
src/pvr2/pvr2.h
src/pvr2/pvr2mem.c
src/pvr2/pvr2mmio.h
src/pvr2/rendbkg.c
src/pvr2/rendcore.c
src/pvr2/render.c
src/pvr2/rendsave.c
src/pvr2/rendsort.c
src/pvr2/tacore.c
src/pvr2/texcache.c
src/pvr2/yuv.c
src/serial.h
src/sh4/Makefile
src/sh4/dmac.c
src/sh4/dmac.h
src/sh4/ia32abi.h
src/sh4/ia32mac.h
src/sh4/ia64abi.h
src/sh4/ia64asm.s
src/sh4/intc.c
src/sh4/intc.h
src/sh4/mmu.c
src/sh4/scif.c
src/sh4/sh4.c
src/sh4/sh4.h
src/sh4/sh4core.c
src/sh4/sh4core.h
src/sh4/sh4core.in
src/sh4/sh4dasm.c
src/sh4/sh4dasm.h
src/sh4/sh4dasm.in
src/sh4/sh4mem.c
src/sh4/sh4mmio.c
src/sh4/sh4mmio.h
src/sh4/sh4stat.c
src/sh4/sh4stat.h
src/sh4/sh4stat.in
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.c
src/sh4/sh4x86.in
src/sh4/timer.c
src/sh4/x86op.h
src/sh4/xltcache.c
src/sh4/xltcache.h
src/syscall.c
src/syscall.h
src/test/testsh4x86.c
src/test/testxlt.c
src/tools/actparse.c
src/tools/gendec.c
src/tools/gendec.h
src/tools/genglsl.c
src/tools/insparse.c
src/util.c
src/watch.c
src/x86dasm/x86dasm.c
src/x86dasm/x86dasm.h
test/Makefile.in
test/asic.c
test/bin2c.c
test/dma.h
test/dmac.c
test/pvr.c
test/pvr.h
test/rendload.c
test/sh4/inc.s
test/sh4/testsh4.c
test/sh4/tlb.s
test/testdata.c
test/testdata.h
test/testdisp.c
test/testide.c
test/testregs.c
test/testrend.c
test/testta.c
test/testyuv.c
1.1 --- a/Makefile.in Thu Dec 20 09:56:07 2007 +0000
1.2 +++ b/Makefile.in Tue Jan 15 20:50:23 2008 +0000
1.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 +0000
2.2 +++ b/aclocal.m4 Tue Jan 15 20:50:23 2008 +0000
2.3 @@ -1006,6 +1006,38 @@
2.4
2.5 AU_DEFUN([fp_PROG_CC_STDC], [AM_PROG_CC_STDC])
2.6
2.7 +# Figure out how to run the assembler. -*- Autoconf -*-
2.8 +
2.9 +# serial 2
2.10 +
2.11 +# Copyright 2001 Free Software Foundation, Inc.
2.12 +
2.13 +# This program is free software; you can redistribute it and/or modify
2.14 +# it under the terms of the GNU General Public License as published by
2.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 of
2.20 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.21 +# GNU General Public License for more details.
2.22 +
2.23 +# You should have received a copy of the GNU General Public License
2.24 +# along with this program; if not, write to the Free Software
2.25 +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
2.26 +# 02111-1307, USA.
2.27 +
2.28 +# AM_PROG_AS
2.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.43
2.44 _PKG_TEXT
2.45 ])],
2.46 - [$4])
2.47 + [AC_MSG_RESULT([no])
2.48 + $4])
2.49 elif test $pkg_failed = untried; then
2.50 ifelse([$4], , [AC_MSG_FAILURE(dnl
2.51 [The pkg-config script could not be found or is too old. Make sure it
2.52 @@ -1266,7 +1299,8 @@
2.53 #-----------------
2.54 glib_DEFUN([GLIB_WITH_NLS],
2.55 dnl NLS is obligatory
2.56 - [USE_NLS=yes
2.57 + [AC_REQUIRE([AC_CANONICAL_HOST])dnl
2.58 + USE_NLS=yes
2.59 AC_SUBST(USE_NLS)
2.60
2.61 gt_cv_have_gettext=no
2.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])dnl
2.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_prefix
2.89 test "x$exec_prefix" = xNONE && exec_prefix=$prefix
2.90 +datarootdir=`eval echo "${datarootdir}"`
2.91 if test "x$CATOBJEXT" = "x.mo" ; then
2.92 localedir=`eval echo "${libdir}/locale"`
2.93 else
2.94 @@ -1550,6 +1600,7 @@
2.95 fi
2.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 ])dnl
2.105
2.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 the
2.109 +# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with
2.110 +# 0 and perform ACTION-IF-FAIL for any other exit status.
2.111 +AC_DEFUN([GLIB_RUN_PROG],
2.112 +[cat >conftest.foo <<_ACEOF
2.113 +$2
2.114 +_ACEOF
2.115 +if AC_RUN_LOG([$1 conftest.foo]); then
2.116 + m4_ifval([$3], [$3], [:])
2.117 +m4_ifvaln([$4], [else $4])dnl
2.118 +echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD
2.119 +sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD
2.120 +fi])
2.121 +
2.122 +
3.1 --- a/config.h.in Thu Dec 20 09:56:07 2007 +0000
3.2 +++ b/config.h.in Tue Jan 15 20:50:23 2008 +0000
3.3 @@ -13,6 +13,12 @@
3.4 /* always defined to indicate that i18n is enabled */
3.5 #undef ENABLE_NLS
3.6
3.7 +/* Enable IO tracing */
3.8 +#undef ENABLE_TRACE_IO
3.9 +
3.10 +/* Enable watchpoints */
3.11 +#undef ENABLE_WATCH
3.12 +
3.13 /* translation domain */
3.14 #undef GETTEXT_PACKAGE
3.15
4.1 --- a/configure Thu Dec 20 09:56:07 2007 +0000
4.2 +++ b/configure Tue Jan 15 20:50:23 2008 +0000
4.3 @@ -687,6 +687,8 @@
4.4 CCDEPMODE
4.5 am__fastdepCC_TRUE
4.6 am__fastdepCC_FALSE
4.7 +CCAS
4.8 +CCASFLAGS
4.9 CPP
4.10 GREP
4.11 EGREP
4.12 @@ -709,6 +711,8 @@
4.13 GUI_GTK_FALSE
4.14 BUILD_SH4X86_TRUE
4.15 BUILD_SH4X86_FALSE
4.16 +BUILD_X86_64_TRUE
4.17 +BUILD_X86_64_FALSE
4.18 ESOUND_CFLAGS
4.19 ESOUND_LIBS
4.20 AUDIO_ESOUND_TRUE
4.21 @@ -728,6 +732,7 @@
4.22 GETTEXT_PACKAGE
4.23 USE_NLS
4.24 MSGFMT
4.25 +MSGFMT_OPTS
4.26 GMSGFMT
4.27 XGETTEXT
4.28 CATALOGS
4.29 @@ -1341,6 +1346,10 @@
4.30 (and sometimes confusing) to the casual installer
4.31 --disable-dependency-tracking Speeds up one-time builds
4.32 --enable-dependency-tracking Do not reject slow dependency extractors
4.33 + --enable-trace Enable generation of IO traces (warning: hurts
4.34 + performance)
4.35 + --enable-watch Enable watchpoints in the debugger (warning: hurts
4.36 + performance)
4.37
4.38 Some influential environment variables:
4.39 CC C compiler command
4.40 @@ -4293,6 +4302,13 @@
4.41 *) CC="$CC $am_cv_prog_cc_stdc" ;;
4.42 esac
4.43
4.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=c
4.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'`;; esac
4.56
4.57
4.58 +# Check whether --enable-trace was given.
4.59 +if test "${enable_trace+set}" = set; then
4.60 + enableval=$enable_trace; if test "$enableval" == "yes"; then
4.61 +
4.62 +cat >>confdefs.h <<\_ACEOF
4.63 +#define ENABLE_TRACE_IO 1
4.64 +_ACEOF
4.65 +
4.66 + fi
4.67 +fi
4.68 +
4.69 +# Check whether --enable-watch was given.
4.70 +if test "${enable_watch+set}" = set; then
4.71 + enableval=$enable_watch; if test "$enableval" == "yes"; then
4.72 +
4.73 +cat >>confdefs.h <<\_ACEOF
4.74 +#define ENABLE_WATCH 1
4.75 +_ACEOF
4.76 +
4.77 + fi
4.78 +fi
4.79
4.80 # On IRIX 5.3, sys/types and inttypes.h are conflicting.
4.81
4.82 @@ -5848,6 +5885,16 @@
4.83
4.84
4.85
4.86 +if test "$SH4_TRANSLATOR" = "x86_64"; then
4.87 + BUILD_X86_64_TRUE=
4.88 + BUILD_X86_64_FALSE='#'
4.89 +else
4.90 + BUILD_X86_64_TRUE='#'
4.91 + BUILD_X86_64_FALSE=
4.92 +fi
4.93 +
4.94 +
4.95 +
4.96 pkg_failed=no
4.97 { echo "$as_me:$LINENO: checking for ESOUND" >&5
4.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 belongs
4.101 echo "$ESOUND_PKG_ERRORS" >&5
4.102
4.103 - echo "Warning: esound not found - building without audio support"
4.104 + { echo "$as_me:$LINENO: result: no" >&5
4.105 +echo "${ECHO_T}no" >&6; }
4.106 + echo "Warning: esound not found - building without audio support"
4.107 elif test $pkg_failed = untried; then
4.108 echo "Warning: esound not found - building without audio support"
4.109 else
4.110 @@ -6562,7 +6611,7 @@
4.111
4.112 fi
4.113 fi
4.114 - USE_NLS=yes
4.115 + USE_NLS=yes
4.116
4.117
4.118 gt_cv_have_gettext=no
4.119 @@ -7517,6 +7566,35 @@
4.120 fi
4.121 done
4.122
4.123 + MSGFMT_OPTS=
4.124 + { echo "$as_me:$LINENO: checking if msgfmt accepts -c" >&5
4.125 +echo $ECHO_N "checking if msgfmt accepts -c... $ECHO_C" >&6; }
4.126 + cat >conftest.foo <<_ACEOF
4.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 +_ACEOF
4.139 +if { (echo "$as_me:$LINENO: \$MSGFMT -c -o /dev/null conftest.foo") >&5
4.140 + ($MSGFMT -c -o /dev/null conftest.foo) 2>&5
4.141 + ac_status=$?
4.142 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
4.143 + (exit $ac_status); }; then
4.144 + MSGFMT_OPTS=-c; { echo "$as_me:$LINENO: result: yes" >&5
4.145 +echo "${ECHO_T}yes" >&6; }
4.146 +else { echo "$as_me:$LINENO: result: no" >&5
4.147 +echo "${ECHO_T}no" >&6; }
4.148 +echo "$as_me: failed input was:" >&5
4.149 +sed 's/^/| /' conftest.foo >&5
4.150 +fi
4.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=$2
4.154 { echo "$as_me:$LINENO: checking for $ac_word" >&5
4.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 fi
4.159 +if test -z "${BUILD_X86_64_TRUE}" && test -z "${BUILD_X86_64_FALSE}"; then
4.160 + { { echo "$as_me:$LINENO: error: conditional \"BUILD_X86_64\" was never defined.
4.161 +Usually this means the macro was only invoked conditionally." >&5
4.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 +fi
4.166 if test -z "${AUDIO_ESOUND_TRUE}" && test -z "${AUDIO_ESOUND_FALSE}"; then
4.167 { { echo "$as_me:$LINENO: error: conditional \"AUDIO_ESOUND\" was never defined.
4.168 Usually this means the macro was only invoked conditionally." >&5
4.169 @@ -8634,6 +8719,8 @@
4.170 CCDEPMODE!$CCDEPMODE$ac_delim
4.171 am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
4.172 am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
4.173 +CCAS!$CCAS$ac_delim
4.174 +CCASFLAGS!$CCASFLAGS$ac_delim
4.175 CPP!$CPP$ac_delim
4.176 GREP!$GREP$ac_delim
4.177 EGREP!$EGREP$ac_delim
4.178 @@ -8655,8 +8742,6 @@
4.179 GUI_GTK_TRUE!$GUI_GTK_TRUE$ac_delim
4.180 GUI_GTK_FALSE!$GUI_GTK_FALSE$ac_delim
4.181 BUILD_SH4X86_TRUE!$BUILD_SH4X86_TRUE$ac_delim
4.182 -BUILD_SH4X86_FALSE!$BUILD_SH4X86_FALSE$ac_delim
4.183 -ESOUND_CFLAGS!$ESOUND_CFLAGS$ac_delim
4.184 _ACEOF
4.185
4.186 if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
4.187 @@ -8698,6 +8783,10 @@
4.188 ac_delim='%!_!# '
4.189 for ac_last_try in false false false false false :; do
4.190 cat >conf$$subs.sed <<_ACEOF
4.191 +BUILD_SH4X86_FALSE!$BUILD_SH4X86_FALSE$ac_delim
4.192 +BUILD_X86_64_TRUE!$BUILD_X86_64_TRUE$ac_delim
4.193 +BUILD_X86_64_FALSE!$BUILD_X86_64_FALSE$ac_delim
4.194 +ESOUND_CFLAGS!$ESOUND_CFLAGS$ac_delim
4.195 ESOUND_LIBS!$ESOUND_LIBS$ac_delim
4.196 AUDIO_ESOUND_TRUE!$AUDIO_ESOUND_TRUE$ac_delim
4.197 AUDIO_ESOUND_FALSE!$AUDIO_ESOUND_FALSE$ac_delim
4.198 @@ -8716,6 +8805,7 @@
4.199 GETTEXT_PACKAGE!$GETTEXT_PACKAGE$ac_delim
4.200 USE_NLS!$USE_NLS$ac_delim
4.201 MSGFMT!$MSGFMT$ac_delim
4.202 +MSGFMT_OPTS!$MSGFMT_OPTS$ac_delim
4.203 GMSGFMT!$GMSGFMT$ac_delim
4.204 XGETTEXT!$XGETTEXT$ac_delim
4.205 CATALOGS!$CATALOGS$ac_delim
4.206 @@ -8733,7 +8823,7 @@
4.207 LTLIBOBJS!$LTLIBOBJS$ac_delim
4.208 _ACEOF
4.209
4.210 - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 33; then
4.211 + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 38; then
4.212 break
4.213 elif $ac_last_try; then
4.214 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
5.1 --- a/configure.in Thu Dec 20 09:56:07 2007 +0000
5.2 +++ b/configure.in Tue Jan 15 20:50:23 2008 +0000
5.3 @@ -8,10 +8,20 @@
5.4 AC_ISC_POSIX
5.5 AC_PROG_CC
5.6 AM_PROG_CC_STDC
5.7 +AM_PROG_AS
5.8 AC_HEADER_STDC
5.9 AC_CANONICAL_BUILD
5.10 AC_CANONICAL_HOST
5.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"; then
5.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"; then
5.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 esac
5.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.30
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 +0000
6.2 +++ b/src/Makefile.am Tue Jan 15 20:50:23 2008 +0000
6.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.c
6.17 + x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
6.18
6.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.c
6.25 -test_testsh4x86_LDADD = @GTK_LIBS@
6.26 + sh4/xltcache.h mem.c util.c sh4/mmu.c
6.27
6.28 check_PROGRAMS += test/testsh4x86
6.29 -
6.30 endif
6.31
6.32 if GUI_GTK
7.1 --- a/src/Makefile.in Thu Dec 20 09:56:07 2007 +0000
7.2 +++ b/src/Makefile.in Tue Jan 15 20:50:23 2008 +0000
7.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.c
7.8 +@BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c
7.9
7.10 @BUILD_SH4X86_TRUE@am__append_2 = test/testsh4x86
7.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.46
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.c
7.53 +@BUILD_SH4X86_TRUE@ sh4/xltcache.h mem.c util.c sh4/mmu.c
7.54
7.55 -@BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @GTK_LIBS@
7.56
7.57 lxdream_LDADD = @GTK_LIBS@ @LIBPNG_LIBS@ @ESOUND_LIBS@ $(INTLLIBS)
7.58
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.c
7.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.c
7.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.c
7.109 + sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/mmu.c
7.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 +0000
8.2 +++ b/src/aica/aica.c Tue Jan 15 20:50:23 2008 +0000
8.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 well
8.9 * as providing the core AICA module to the system.
9.1 --- a/src/aica/aica.h Thu Dec 20 09:56:07 2007 +0000
9.2 +++ b/src/aica/aica.h Tue Jan 15 20:50:23 2008 +0000
9.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 defined
9.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 +0000
10.2 +++ b/src/aica/armcore.c Tue Jan 15 20:50:23 2008 +0000
10.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.13
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.21
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;
10.26
11.1 --- a/src/aica/armcore.h Thu Dec 20 09:56:07 2007 +0000
11.2 +++ b/src/aica/armcore.h Tue Jan 15 20:50:23 2008 +0000
11.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_H
11.12 #define dream_armcore_H 1
11.13
11.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.19
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.29
11.30 /* ARM Memory */
12.1 --- a/src/aica/armdasm.c Thu Dec 20 09:56:07 2007 +0000
12.2 +++ b/src/aica/armdasm.c Tue Jan 15 20:50:23 2008 +0000
12.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) disassembler
12.9 *
13.1 --- a/src/aica/armdasm.h Thu Dec 20 09:56:07 2007 +0000
13.2 +++ b/src/aica/armdasm.h Tue Jan 15 20:50:23 2008 +0000
13.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 declarations
13.9 *
14.1 --- a/src/aica/armmem.c Thu Dec 20 09:56:07 2007 +0000
14.2 +++ b/src/aica/armmem.c Tue Jan 15 20:50:23 2008 +0000
14.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 +0000
15.2 +++ b/src/aica/audio.c Tue Jan 15 20:50:23 2008 +0000
15.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 sound
15.9 * buffer for output.
16.1 --- a/src/aica/audio.h Thu Dec 20 09:56:07 2007 +0000
16.2 +++ b/src/aica/audio.h Tue Jan 15 20:50:23 2008 +0000
16.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 +0000
17.2 +++ b/src/asic.c Tue Jan 15 20:50:23 2008 +0000
17.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 +0000
18.2 +++ b/src/asic.h Tue Jan 15 20:50:23 2008 +0000
18.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 +0000
19.2 +++ b/src/bios.c Tue Jan 15 20:50:23 2008 +0000
19.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.16
19.17 #define COMMAND_QUEUE_LENGTH 16
19.18
20.1 --- a/src/bootstrap.c Thu Dec 20 09:56:07 2007 +0000
20.2 +++ b/src/bootstrap.c Tue Jan 15 20:50:23 2008 +0000
20.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 +0000
21.2 +++ b/src/bootstrap.h Tue Jan 15 20:50:23 2008 +0000
21.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 +0000
22.2 +++ b/src/clock.h Tue Jan 15 20:50:23 2008 +0000
22.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 by
22.8 * sh4/scif.c
22.9 *
23.1 --- a/src/config.c Thu Dec 20 09:56:07 2007 +0000
23.2 +++ b/src/config.c Tue Jan 15 20:50:23 2008 +0000
23.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 support
23.9 *
24.1 --- a/src/config.h Thu Dec 20 09:56:07 2007 +0000
24.2 +++ b/src/config.h Tue Jan 15 20:50:23 2008 +0000
24.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 support
24.9 *
25.1 --- a/src/cpu.h Thu Dec 20 09:56:07 2007 +0000
25.2 +++ b/src/cpu.h Tue Jan 15 20:50:23 2008 +0000
25.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_H
25.12 #define dream_cpu_H 1
25.13
25.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.19
25.20 #ifdef __cplusplus
25.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 +0000
26.2 +++ b/src/dcload.c Tue Jan 15 20:50:23 2008 +0000
26.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.16
26.17 #define SYS_READ 0
26.18 #define SYS_WRITE 1
27.1 --- a/src/display.c Thu Dec 20 09:56:07 2007 +0000
27.2 +++ b/src/display.c Tue Jan 15 20:50:23 2008 +0000
27.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 display
27.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 +0000
28.2 +++ b/src/display.h Tue Jan 15 20:50:23 2008 +0000
28.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 +0000
29.2 +++ b/src/dream.h Tue Jan 15 20:50:23 2008 +0000
29.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 +0000
30.2 +++ b/src/dreamcast.c Tue Jan 15 20:50:23 2008 +0000
30.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 modules
30.8 * together into some kind of coherent structure. This is also where you'd
30.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.15
30.16 /**
30.17 * Current state of the DC virtual machine
30.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.29
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 +0000
31.2 +++ b/src/dreamcast.h Tue Jan 15 20:50:23 2008 +0000
31.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 modules
31.10 @@ -60,7 +60,7 @@
31.11 void dreamcast_program_loaded( const gchar *name, sh4addr_t entry_point );
31.12
31.13 #define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"
31.14 -#define DREAMCAST_SAVE_VERSION 0x00010002
31.15 +#define DREAMCAST_SAVE_VERSION 0x00010003
31.16
31.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 +0000
32.2 +++ b/src/drivers/audio_esd.c Tue Jan 15 20:50:23 2008 +0000
32.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 driver
32.9 *
33.1 --- a/src/drivers/audio_null.c Thu Dec 20 09:56:07 2007 +0000
33.2 +++ b/src/drivers/audio_null.c Tue Jan 15 20:50:23 2008 +0000
33.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 even
33.9 * looking at it.
34.1 --- a/src/drivers/cd_linux.c Thu Dec 20 09:56:07 2007 +0000
34.2 +++ b/src/drivers/cd_linux.c Tue Jan 15 20:50:23 2008 +0000
34.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 +0000
35.2 +++ b/src/drivers/cd_none.c Tue Jan 15 20:50:23 2008 +0000
35.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 +0000
36.2 +++ b/src/drivers/gl_common.c Tue Jan 15 20:50:23 2008 +0000
36.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 implementation
36.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.24
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 +0000
37.2 +++ b/src/drivers/gl_common.h Tue Jan 15 20:50:23 2008 +0000
37.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 +0000
38.2 +++ b/src/drivers/gl_fbo.c Tue Jan 15 20:50:23 2008 +0000
38.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_object
38.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 +0000
39.2 +++ b/src/drivers/gl_sl.c Tue Jan 15 20:50:23 2008 +0000
39.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 exactly
39.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 +0000
40.2 +++ b/src/drivers/video_glx.c Tue Jan 15 20:50:23 2008 +0000
40.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.13
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.24
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 +0000
41.2 +++ b/src/drivers/video_glx.h Tue Jan 15 20:50:23 2008 +0000
41.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 +0000
42.2 +++ b/src/drivers/video_gtk.c Tue Jan 15 20:50:23 2008 +0000
42.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.16
42.17 static GtkWidget *video_win = NULL;
43.1 --- a/src/drivers/video_null.c Thu Dec 20 09:56:07 2007 +0000
43.2 +++ b/src/drivers/video_null.c Tue Jan 15 20:50:23 2008 +0000
43.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 +0000
44.2 +++ b/src/eventq.c Tue Jan 15 20:50:23 2008 +0000
44.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 IO
44.9 * devices to wait until a particular time before completing. We expect
44.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.16
44.17 #define LONG_SCAN_PERIOD 1000000000 /* 1 second */
44.18
45.1 --- a/src/eventq.h Thu Dec 20 09:56:07 2007 +0000
45.2 +++ b/src/eventq.h Tue Jan 15 20:50:23 2008 +0000
45.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 IO
45.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 +0000
46.2 +++ b/src/gdrom/cdi.c Tue Jan 15 20:50:23 2008 +0000
46.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 support
46.9 *
47.1 --- a/src/gdrom/cdi.h Thu Dec 20 09:56:07 2007 +0000
47.2 +++ b/src/gdrom/cdi.h Tue Jan 15 20:50:23 2008 +0000
47.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 support
47.9 *
48.1 --- a/src/gdrom/gdi.c Thu Dec 20 09:56:07 2007 +0000
48.2 +++ b/src/gdrom/gdi.c Tue Jan 15 20:50:23 2008 +0000
48.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 format
48.9 *
49.1 --- a/src/gdrom/gdimage.c Thu Dec 20 09:56:07 2007 +0000
49.2 +++ b/src/gdrom/gdimage.c Tue Jan 15 20:50:23 2008 +0000
49.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 +0000
50.2 +++ b/src/gdrom/gdrom.c Tue Jan 15 20:50:23 2008 +0000
50.3 @@ -1,6 +1,6 @@
50.4
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 +0000
51.2 +++ b/src/gdrom/gdrom.h Tue Jan 15 20:50:23 2008 +0000
51.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-Rom
51.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 +0000
52.2 +++ b/src/gdrom/ide.c Tue Jan 15 20:50:23 2008 +0000
52.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 implementation
52.9 *
53.1 --- a/src/gdrom/ide.h Thu Dec 20 09:56:07 2007 +0000
53.2 +++ b/src/gdrom/ide.h Tue Jan 15 20:50:23 2008 +0000
53.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 IDE
53.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 +0000
54.2 +++ b/src/gdrom/nrg.c Tue Jan 15 20:50:23 2008 +0000
54.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 from
54.9 * libcdio.
55.1 --- a/src/gdrom/packet.h Thu Dec 20 09:56:07 2007 +0000
55.2 +++ b/src/gdrom/packet.h Tue Jan 15 20:50:23 2008 +0000
55.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 the
55.9 * GD-Rom ATAPI packet commands.
56.1 --- a/src/gtkui/ctrl_dlg.c Thu Dec 20 09:56:07 2007 +0000
56.2 +++ b/src/gtkui/ctrl_dlg.c Tue Jan 15 20:50:23 2008 +0000
56.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 +0000
57.2 +++ b/src/gtkui/debug_win.c Tue Jan 15 20:50:23 2008 +0000
57.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.12
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.18
57.19 @@ -79,7 +79,7 @@
57.20 data->statusbar = gtk_statusbar_new();
57.21
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.25
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 +0000
58.2 +++ b/src/gtkui/dump_win.c Tue Jan 15 20:50:23 2008 +0000
58.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 +0000
59.2 +++ b/src/gtkui/gdrom_menu.c Tue Jan 15 20:50:23 2008 +0000
59.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 +0000
60.2 +++ b/src/gtkui/gtkcb.c Tue Jan 15 20:50:23 2008 +0000
60.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 window
60.9 *
61.1 --- a/src/gtkui/gtkui.c Thu Dec 20 09:56:07 2007 +0000
61.2 +++ b/src/gtkui/gtkui.c Tue Jan 15 20:50:23 2008 +0000
61.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 interface
61.9 *
62.1 --- a/src/gtkui/gtkui.h Thu Dec 20 09:56:07 2007 +0000
62.2 +++ b/src/gtkui/gtkui.h Tue Jan 15 20:50:23 2008 +0000
62.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 interface
62.9 *
63.1 --- a/src/gtkui/main_win.c Thu Dec 20 09:56:07 2007 +0000
63.2 +++ b/src/gtkui/main_win.c Tue Jan 15 20:50:23 2008 +0000
63.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 +0000
64.2 +++ b/src/gtkui/mmio_win.c Tue Jan 15 20:50:23 2008 +0000
64.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 window
64.9 *
64.10 @@ -121,6 +121,10 @@
64.11 gtk_container_add( GTK_CONTAINER(vbox), GTK_WIDGET(scroll) );
64.12
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 +0000
65.2 +++ b/src/gtkui/path_dlg.c Tue Jan 15 20:50:23 2008 +0000
65.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 +0000
66.2 +++ b/src/gui.h Tue Jan 15 20:50:23 2008 +0000
66.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 +0000
67.2 +++ b/src/loader.c Tue Jan 15 20:50:23 2008 +0000
67.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 the
67.9 * whole procedure of making a CD image for them.
68.1 --- a/src/loader.h Thu Dec 20 09:56:07 2007 +0000
68.2 +++ b/src/loader.h Tue Jan 15 20:50:23 2008 +0000
68.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 +0000
69.2 +++ b/src/lxdream.h Tue Jan 15 20:50:23 2008 +0000
69.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 declarations
69.9 *
69.10 @@ -39,9 +39,15 @@
69.11 #endif
69.12
69.13 /**
69.14 - * A 32-bit address in SH4 space
69.15 + * A 29-bit address in SH4 external address space
69.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 memory
69.26 */
69.27 @@ -67,6 +73,7 @@
69.28 #define MODULE_NAME "*****"
69.29 #endif
69.30
69.31 +gboolean set_global_log_level( const gchar *level );
69.32 void log_message( void *, int level, const char *source, const char *msg, ... );
69.33
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 +0000
70.2 +++ b/src/main.c Tue Jan 15 20:50:23 2008 +0000
70.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 to
70.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.16
70.17 #define S3M_PLAYER "s3mplay.bin"
70.18
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.72
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.84
70.85 if( disc_file != NULL ) {
71.1 --- a/src/maple/controller.c Thu Dec 20 09:56:07 2007 +0000
71.2 +++ b/src/maple/controller.c Tue Jan 15 20:50:23 2008 +0000
71.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 controller
71.9 *
72.1 --- a/src/maple/controller.h Thu Dec 20 09:56:07 2007 +0000
72.2 +++ b/src/maple/controller.h Tue Jan 15 20:50:23 2008 +0000
72.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 device
72.9 *
73.1 --- a/src/maple/maple.c Thu Dec 20 09:56:07 2007 +0000
73.2 +++ b/src/maple/maple.c Tue Jan 15 20:50:23 2008 +0000
73.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 +0000
74.2 +++ b/src/maple/maple.h Tue Jan 15 20:50:23 2008 +0000
74.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 definitions
74.9 *
75.1 --- a/src/mem.c Thu Dec 20 09:56:07 2007 +0000
75.2 +++ b/src/mem.c Tue Jan 15 20:50:23 2008 +0000
75.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 memory
75.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.30
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.45
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 everything
75.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 +0000
76.2 +++ b/src/mem.h Tue Jan 15 20:50:23 2008 +0000
76.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 memory
76.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.20
76.21 #define ENABLE_DEBUG_MODE 1
76.22
76.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.30
76.31 #define MAX_BREAKPOINTS 32
76.32 -#define BREAK_NONE 0
76.33 -#define BREAK_ONESHOT 1
76.34 -#define BREAK_KEEP 2
76.35
76.36 -#undef ENABLE_WATCH
76.37 +
76.38 +#define MEM_FLAG_ROM 4 /* Mem region is ROM-based */
76.39 +#define MEM_FLAG_RAM 6
76.40
76.41 #define WATCH_WRITE 1
76.42 #define WATCH_READ 2
76.43 #define WATCH_EXEC 3 /* AKA Breakpoint :) */
76.44
76.45 -#define MEM_FLAG_ROM 4 /* Mem region is ROM-based */
76.46 -#define MEM_FLAG_RAM 6
76.47 -
76.48 typedef struct watch_point *watch_point_t;
76.49
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 +0000
77.2 +++ b/src/mmio.h Tue Jan 15 20:50:23 2008 +0000
77.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 the
77.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 +0000
78.2 +++ b/src/pvr2/pvr2.c Tue Jan 15 20:50:23 2008 +0000
78.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_IMPL
78.17 #include "pvr2/pvr2mmio.h"
78.18
79.1 --- a/src/pvr2/pvr2.h Thu Dec 20 09:56:07 2007 +0000
79.2 +++ b/src/pvr2/pvr2.h Tue Jan 15 20:50:23 2008 +0000
79.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 +0000
80.2 +++ b/src/pvr2/pvr2mem.c Tue Jan 15 20:50:23 2008 +0000
80.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 +0000
81.2 +++ b/src/pvr2/pvr2mmio.h Tue Jan 15 20:50:23 2008 +0000
81.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 +0000
82.2 +++ b/src/pvr2/rendbkg.c Tue Jan 15 20:50:23 2008 +0000
82.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 +0000
83.2 +++ b/src/pvr2/rendcore.c Tue Jan 15 20:50:23 2008 +0000
83.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 +0000
84.2 +++ b/src/pvr2/render.c Tue Jan 15 20:50:23 2008 +0000
84.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 primarily
84.9 *
85.1 --- a/src/pvr2/rendsave.c Thu Dec 20 09:56:07 2007 +0000
85.2 +++ b/src/pvr2/rendsave.c Tue Jan 15 20:50:23 2008 +0000
85.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 +0000
86.2 +++ b/src/pvr2/rendsort.c Tue Jan 15 20:50:23 2008 +0000
86.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 polygons
86.9 *
87.1 --- a/src/pvr2/tacore.c Thu Dec 20 09:56:07 2007 +0000
87.2 +++ b/src/pvr2/tacore.c Tue Jan 15 20:50:23 2008 +0000
87.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 implementation
87.9 *
88.1 --- a/src/pvr2/texcache.c Thu Dec 20 09:56:07 2007 +0000
88.2 +++ b/src/pvr2/texcache.c Tue Jan 15 20:50:23 2008 +0000
88.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 OpenGL
88.9 * textures.
89.1 --- a/src/pvr2/yuv.c Thu Dec 20 09:56:07 2007 +0000
89.2 +++ b/src/pvr2/yuv.c Tue Jan 15 20:50:23 2008 +0000
89.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 decoding
89.9 *
90.1 --- a/src/serial.h Thu Dec 20 09:56:07 2007 +0000
90.2 +++ b/src/serial.h Tue Jan 15 20:50:23 2008 +0000
90.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 by
90.8 * sh4/scif.c
90.9 *
91.1 --- a/src/sh4/Makefile Thu Dec 20 09:56:07 2007 +0000
91.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91.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, 2003
91.8 -# Free Software Foundation, Inc.
91.9 -# This Makefile.in is free software; the Free Software Foundation
91.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; without
91.15 -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
91.16 -# PARTICULAR PURPOSE.
91.17 -
91.18 -
91.19 -
91.20 -srcdir = .
91.21 -top_srcdir = ../..
91.22 -
91.23 -pkgdatadir = $(datadir)/DreamOn
91.24 -pkglibdir = $(libdir)/DreamOn
91.25 -pkgincludedir = $(includedir)/DreamOn
91.26 -top_builddir = ../..
91.27 -
91.28 -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
91.29 -INSTALL = /usr/bin/install -c
91.30 -install_sh_DATA = $(install_sh) -c -m 644
91.31 -install_sh_PROGRAM = $(install_sh) -c
91.32 -install_sh_SCRIPT = $(install_sh) -c
91.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-gnu
91.42 -ACLOCAL = ${SHELL} /usr/home/nkeynes/src/dream/missing --run aclocal-1.7 -I macros
91.43 -ALLOCA =
91.44 -AMDEP_FALSE = #
91.45 -AMDEP_TRUE =
91.46 -AMTAR = ${SHELL} /usr/home/nkeynes/src/dream/missing --run tar
91.47 -AUTOCONF = ${SHELL} /usr/home/nkeynes/src/dream/missing --run autoconf
91.48 -AUTOHEADER = ${SHELL} /usr/home/nkeynes/src/dream/missing --run autoheader
91.49 -AUTOMAKE = ${SHELL} /usr/home/nkeynes/src/dream/missing --run automake-1.7
91.50 -AWK = gawk
91.51 -BUILD_INCLUDED_LIBINTL = no
91.52 -CATOBJEXT = .gmo
91.53 -CC = gcc
91.54 -CCDEPMODE = depmode=gcc3
91.55 -CFLAGS = -g -O2 -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations
91.56 -CPP = gcc -E
91.57 -CPPFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include
91.58 -CYGPATH_W = echo
91.59 -DATADIRNAME = share
91.60 -DEFS = -DHAVE_CONFIG_H
91.61 -DEPDIR = .deps
91.62 -ECHO_C =
91.63 -ECHO_N = -n
91.64 -ECHO_T =
91.65 -EGREP = grep -E
91.66 -EXEEXT =
91.67 -GENCAT = gencat
91.68 -GLIBC21 = yes
91.69 -GMSGFMT = /usr/bin/msgfmt
91.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 -lglib
91.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 -lglib
91.72 -GNOME_APPLETS_LIBS =
91.73 -GNOME_CAPPLET_LIBS =
91.74 -GNOME_CONFIG = /usr/bin/gnome-config
91.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.2
91.77 -GNOME_LIBDIR = -rdynamic -L/usr/lib -L/usr/X11R6/lib
91.78 -GNOME_LIBS = -lgnome -lgnomesupport -lesd -laudiofile -lm -ldb-3 -lglib
91.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.2
91.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 -lglib
91.81 -GTKXMHTML_LIBS = -rdynamic -lgtkxmhtml -lXpm -ljpeg -lpng10 -lz -lSM -lICE -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
91.82 -GTK_CFLAGS = -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include
91.83 -GTK_CONFIG = /usr/bin/gtk-config
91.84 -GTK_LIBS = -lSM -lICE -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
91.85 -HAVE_ASPRINTF = 1
91.86 -HAVE_GNORBA_FALSE = #
91.87 -HAVE_GNORBA_TRUE =
91.88 -HAVE_ORBIT_FALSE = #
91.89 -HAVE_ORBIT_TRUE =
91.90 -HAVE_POSIX_PRINTF = 1
91.91 -HAVE_SNPRINTF = 1
91.92 -HAVE_WPRINTF = 0
91.93 -INSIDE_GNOME_COMMON_FALSE =
91.94 -INSIDE_GNOME_COMMON_TRUE = #
91.95 -INSTALL_DATA = ${INSTALL} -m 644
91.96 -INSTALL_PROGRAM = ${INSTALL}
91.97 -INSTALL_SCRIPT = ${INSTALL}
91.98 -INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
91.99 -INSTOBJEXT = .mo
91.100 -INTLBISON = bison
91.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 makeinfo
91.113 -MKINSTALLDIRS = $(top_builddir)/./mkinstalldirs
91.114 -MSGFMT = /usr/bin/msgfmt
91.115 -MSGMERGE = /usr/bin/msgmerge
91.116 -OBJEXT = o
91.117 -ORBIT_CFLAGS = -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/include/orbit-1.0
91.118 -ORBIT_CONFIG = /usr/bin/orbit-config
91.119 -ORBIT_IDL = /usr/bin/orbit-idl
91.120 -ORBIT_LIBS = -L/usr/lib -lORBitCosNaming -lORBit -lIIOP -lORBitutil -lglib -lm
91.121 -PACKAGE = DreamOn
91.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 = po
91.129 -PTHREAD_LIB = -lpthread
91.130 -RANLIB = ranlib
91.131 -SET_MAKE =
91.132 -SHELL = /bin/sh
91.133 -STRIP =
91.134 -USE_INCLUDED_LIBINTL = no
91.135 -USE_NLS = yes
91.136 -VERSION = 0.01
91.137 -XGETTEXT = /usr/bin/xgettext
91.138 -XPM_LIBS = -lXpm
91.139 -ZVT_LIBS = -rdynamic -lzvt -lutil -lSM -lICE -lgdk_imlib -lgtk -lgdk -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
91.140 -ac_ct_CC = gcc
91.141 -ac_ct_RANLIB = ranlib
91.142 -ac_ct_STRIP =
91.143 -am__fastdepCC_FALSE = #
91.144 -am__fastdepCC_TRUE =
91.145 -am__include = include
91.146 -am__leading_dot = .
91.147 -am__quote =
91.148 -bindir = ${exec_prefix}/bin
91.149 -build = i686-pc-linux-gnu
91.150 -build_alias =
91.151 -build_cpu = i686
91.152 -build_os = linux-gnu
91.153 -build_vendor = pc
91.154 -cflags_set = yes
91.155 -datadir = ${prefix}/share
91.156 -exec_prefix = ${prefix}
91.157 -host = i686-pc-linux-gnu
91.158 -host_alias =
91.159 -host_cpu = i686
91.160 -host_os = linux-gnu
91.161 -host_vendor = pc
91.162 -includedir = ${prefix}/include
91.163 -infodir = ${prefix}/info
91.164 -install_sh = /usr/home/nkeynes/src/dream/install-sh
91.165 -libdir = ${exec_prefix}/lib
91.166 -libexecdir = ${exec_prefix}/libexec
91.167 -localstatedir = ${prefix}/var
91.168 -mandir = ${prefix}/man
91.169 -oldincludedir = /usr/include
91.170 -prefix = /usr/local
91.171 -program_transform_name = s,x,x,
91.172 -sbindir = ${exec_prefix}/sbin
91.173 -sharedstatedir = ${prefix}/com
91.174 -sysconfdir = ${prefix}/etc
91.175 -target_alias =
91.176 -
91.177 -INCLUDES = \
91.178 - -I$(top_srcdir)/intl -I$(top_srcdir)/src
91.179 -
91.180 -
91.181 -noinst_LIBRARIES = libsh4.a
91.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.h
91.184 -
91.185 -
91.186 -AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE
91.187 -subdir = src/sh4
91.188 -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
91.189 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
91.190 -CONFIG_HEADER = $(top_builddir)/config.h
91.191 -CONFIG_CLEAN_FILES =
91.192 -LIBRARIES = $(noinst_LIBRARIES)
91.193 -
91.194 -libsh4_a_AR = $(AR) cru
91.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)/depcomp
91.202 -am__depfiles_maybe = depfiles
91.203 -DEP_FILES = ./$(DEPDIR)/intc.Po ./$(DEPDIR)/mem.Po \
91.204 - ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \
91.205 - ./$(DEPDIR)/sh4mmio.Po
91.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.am
91.212 -SOURCES = $(libsh4_a_SOURCES)
91.213 -
91.214 -all: all-am
91.215 -
91.216 -.SUFFIXES:
91.217 -.SUFFIXES: .c .o .obj
91.218 -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
91.219 - cd $(top_srcdir) && \
91.220 - $(AUTOMAKE) --gnu src/sh4/Makefile
91.221 -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
91.222 - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
91.223 -
91.224 -AR = ar
91.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.a
91.230 - $(libsh4_a_AR) libsh4.a $(libsh4_a_OBJECTS) $(libsh4_a_LIBADD)
91.231 - $(RANLIB) libsh4.a
91.232 -
91.233 -mostlyclean-compile:
91.234 - -rm -f *.$(OBJEXT) core *.core
91.235 -
91.236 -distclean-compile:
91.237 - -rm -f *.tab.c
91.238 -
91.239 -include ./$(DEPDIR)/intc.Po
91.240 -include ./$(DEPDIR)/mem.Po
91.241 -include ./$(DEPDIR)/sh4core.Po
91.242 -include ./$(DEPDIR)/sh4dasm.Po
91.243 -include ./$(DEPDIR)/sh4mmio.Po
91.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 - fi
91.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 - fi
91.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 = etags
91.269 -ETAGSFLAGS =
91.270 -
91.271 -CTAGS = ctags
91.272 -CTAGSFLAGS =
91.273 -
91.274 -tags: TAGS
91.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 $$unique
91.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 $$unique
91.298 -
91.299 -ctags: CTAGS
91.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 $$unique
91.313 -
91.314 -GTAGS:
91.315 - here=`$(am__cd) $(top_builddir) && pwd` \
91.316 - && cd $(top_srcdir) \
91.317 - && gtags -i $(GTAGS_ARGS) $$here
91.318 -
91.319 -distclean-tags:
91.320 - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
91.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 - done
91.353 -check-am: all-am
91.354 -check: check-am
91.355 -all-am: Makefile $(LIBRARIES)
91.356 -
91.357 -installdirs:
91.358 -install: install-am
91.359 -install-exec: install-exec-am
91.360 -install-data: install-data-am
91.361 -uninstall: uninstall-am
91.362 -
91.363 -install-am: all-am
91.364 - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
91.365 -
91.366 -installcheck: installcheck-am
91.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)'"` install
91.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-am
91.383 -
91.384 -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
91.385 -
91.386 -distclean: distclean-am
91.387 - -rm -rf ./$(DEPDIR)
91.388 - -rm -f Makefile
91.389 -distclean-am: clean-am distclean-compile distclean-generic \
91.390 - distclean-tags
91.391 -
91.392 -dvi: dvi-am
91.393 -
91.394 -dvi-am:
91.395 -
91.396 -info: info-am
91.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-am
91.405 -
91.406 -install-man:
91.407 -
91.408 -installcheck-am:
91.409 -
91.410 -maintainer-clean: maintainer-clean-am
91.411 - -rm -rf ./$(DEPDIR)
91.412 - -rm -f Makefile
91.413 -maintainer-clean-am: distclean-am maintainer-clean-generic
91.414 -
91.415 -mostlyclean: mostlyclean-am
91.416 -
91.417 -mostlyclean-am: mostlyclean-compile mostlyclean-generic
91.418 -
91.419 -pdf: pdf-am
91.420 -
91.421 -pdf-am:
91.422 -
91.423 -ps: ps-am
91.424 -
91.425 -ps-am:
91.426 -
91.427 -uninstall-am: uninstall-info-am
91.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-am
91.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 +0000
92.2 +++ b/src/sh4/dmac.c Tue Jan 15 20:50:23 2008 +0000
92.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 +0000
93.2 +++ b/src/sh4/dmac.h Tue Jan 15 20:50:23 2008 +0000
93.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 +0000
94.2 +++ b/src/sh4/ia32abi.h Tue Jan 15 20:50:23 2008 +0000
94.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, and
94.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.26
94.27 -#define EXIT_BLOCK_SIZE 29
94.28 -
94.29 -
94.30 /**
94.31 * Emit the 'start of block' assembly. Sets up the stack frame and save
94.32 * SI/DI as required
94.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_ALIGN
94.42 sh4_x86.stack_posn = 8;
94.43 @@ -119,16 +118,23 @@
94.44 * Exit the block with sh4r.pc already written
94.45 * Bytes: 15
94.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 ); // 5
94.51 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
94.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.62
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 PC
94.68 */
94.69 @@ -136,7 +142,37 @@
94.70 {
94.71 load_imm32( R_ECX, pc ); // 5
94.72 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
94.73 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
94.74 + if( IS_IN_ICACHE(pc) ) {
94.75 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
94.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 ); // 3
94.82 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
94.83 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
94.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 PC
94.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 ); // 5
94.96 + ADD_sh4r_r32( R_PC, R_ECX );
94.97 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
94.98 + if( IS_IN_ICACHE(pc) ) {
94.99 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
94.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 ); // 3
94.106 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
94.107 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
94.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 here
94.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 exception
94.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 - // target
94.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 exception
94.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.147
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.160
94.161 - sh4_x86_do_backpatch( end_ptr );
94.162 + // Exception already raised - just cleanup
94.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.195
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
94.220
94.221
95.1 --- a/src/sh4/ia32mac.h Thu Dec 20 09:56:07 2007 +0000
95.2 +++ b/src/sh4/ia32mac.h Tue Jan 15 20:50:23 2008 +0000
95.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, and
95.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.28
95.29 -#define EXIT_BLOCK_SIZE 29
95.30 -
95.31 -
95.32 /**
95.33 * Emit the 'start of block' assembly. Sets up the stack frame and save
95.34 * SI/DI as required
95.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.45
95.46 @@ -142,16 +141,23 @@
95.47 * Exit the block with sh4r.pc already written
95.48 * Bytes: 15
95.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 ); // 5
95.54 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
95.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.65
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 PC
95.71 */
95.72 @@ -159,7 +165,37 @@
95.73 {
95.74 load_imm32( R_ECX, pc ); // 5
95.75 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
95.76 - MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
95.77 + if( IS_IN_ICACHE(pc) ) {
95.78 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
95.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 ); // 3
95.85 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
95.86 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
95.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 PC
95.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 ); // 5
95.99 + ADD_sh4r_r32( R_PC, R_ECX );
95.100 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
95.101 + if( IS_IN_ICACHE(pc) ) {
95.102 + MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
95.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 ); // 3
95.109 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
95.110 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
95.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 here
95.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 exception
95.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 - // target
95.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 exception
95.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.150
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.165
95.166 - sh4_x86_do_backpatch( end_ptr );
95.167 + // Exception already raised - just cleanup
95.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.200
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
95.226
95.227
96.1 --- a/src/sh4/ia64abi.h Thu Dec 20 09:56:07 2007 +0000
96.2 +++ b/src/sh4/ia64abi.h Tue Jan 15 20:50:23 2008 +0000
96.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, and
96.9 * calling conventions)
96.10 @@ -20,6 +20,7 @@
96.11 #ifndef __lxdream_x86_64abi_H
96.12 #define __lxdream_x86_64abi_H 1
96.13
96.14 +#include <unwind.h>
96.15
96.16 #define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );
96.17
96.18 @@ -50,7 +51,7 @@
96.19 call_func0(ptr);
96.20 }
96.21
96.22 -#define MEM_WRITE_DOUBLE_SIZE 39
96.23 +#define MEM_WRITE_DOUBLE_SIZE 35
96.24 /**
96.25 * Write a double (64-bit) value into memory, with the first word in arg2a, and
96.26 * the second in arg2b
96.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.40
96.41 #define MEM_READ_DOUBLE_SIZE 43
96.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.51
96.52 @@ -109,17 +112,21 @@
96.53 * Exit the block with sh4r.pc already written
96.54 * Bytes: 15
96.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 ); // 5
96.60 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
96.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.71
96.72 -#define EXIT_BLOCK_SIZE 35
96.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 PC
96.76 */
96.77 @@ -127,8 +134,14 @@
96.78 {
96.79 load_imm32( R_ECX, pc ); // 5
96.80 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
96.81 - REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
96.82 - REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
96.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 ); // 4
96.91 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
96.92 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
96.93 POP_r32(R_EBP);
96.94 @@ -136,51 +149,112 @@
96.95 }
96.96
96.97
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 PC
96.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 ); // 5
96.106 + ADD_sh4r_r32( R_PC, R_ECX );
96.107 + store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
96.108 + if( IS_IN_ICACHE(pc) ) {
96.109 + REXW(); MOV_moff32_EAX( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
96.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 ); // 4
96.116 + load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
96.117 + ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
96.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 here
96.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 exception
96.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 - // target
96.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 exception
96.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.163
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.175
96.176 - sh4_x86_do_backpatch( end_ptr );
96.177 + // Exception already raised - just cleanup
96.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.210
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 +0000
97.2 +++ b/src/sh4/ia64asm.s Tue Jan 15 20:50:23 2008 +0000
97.3 @@ -0,0 +1,34 @@
97.4 +#
97.5 +# Scan back through the stack until we hit the currently executing
97.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 find
97.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 the
97.11 +# saved %ebp.
97.12 +#
97.13 +# At most 8 stack frames are checked, to prevent infinite looping on a
97.14 +# corrupt stack.
97.15 +
97.16 +.global xlat_get_native_pc
97.17 +xlat_get_native_pc:
97.18 + mov %rbp, %rax
97.19 + mov $0x8, %ecx
97.20 + mov $sh4r, %rdx
97.21 +
97.22 +frame_loop:
97.23 + test %rax, %rax
97.24 + je frame_not_found
97.25 + cmpq (%rax), %rdx
97.26 + je frame_found
97.27 + sub $0x1, %ecx
97.28 + je frame_not_found
97.29 + movq (%rax), %rax
97.30 + jmp frame_loop
97.31 +
97.32 +frame_found:
97.33 + movl 0x4(%rax), %rax
97.34 + ret
97.35 +frame_not_found:
97.36 + xor %rax, %rax
97.37 + ret
98.1 --- a/src/sh4/intc.c Thu Dec 20 09:56:07 2007 +0000
98.2 +++ b/src/sh4/intc.c Tue Jan 15 20:50:23 2008 +0000
98.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) implementation
98.9 *
99.1 --- a/src/sh4/intc.h Thu Dec 20 09:56:07 2007 +0000
99.2 +++ b/src/sh4/intc.h Tue Jan 15 20:50:23 2008 +0000
99.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 +0000
100.2 +++ b/src/sh4/mmu.c Tue Jan 15 20:50:23 2008 +0000
100.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 implementation
100.9 *
100.10 @@ -22,6 +22,41 @@
100.11 #include "sh4/sh4core.h"
100.12 #include "mem.h"
100.13
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 exceptions
100.17 + * directly, with a return code indicating that one was raised and the caller
100.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 attempting
100.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.51
100.52 @@ -32,6 +67,7 @@
100.53 #define TLB_VALID 0x00000100
100.54 #define TLB_USERMODE 0x00000040
100.55 #define TLB_WRITABLE 0x00000020
100.56 +#define TLB_USERWRITABLE (TLB_WRITABLE|TLB_USERMODE)
100.57 #define TLB_SIZE_MASK 0x00000090
100.58 #define TLB_SIZE_1K 0x00000000
100.59 #define TLB_SIZE_4K 0x00000010
100.60 @@ -42,16 +78,22 @@
100.61 #define TLB_SHARE 0x00000002
100.62 #define TLB_WRITETHRU 0x00000001
100.63
100.64 +#define MASK_1K 0xFFFFFC00
100.65 +#define MASK_4K 0xFFFFF000
100.66 +#define MASK_64K 0xFFFF0000
100.67 +#define MASK_1M 0xFFF00000
100.68
100.69 struct itlb_entry {
100.70 sh4addr_t vpn; // Virtual Page Number
100.71 uint32_t asid; // Process ID
100.72 + uint32_t mask;
100.73 sh4addr_t ppn; // Physical Page Number
100.74 uint32_t flags;
100.75 };
100.76
100.77 struct utlb_entry {
100.78 sh4addr_t vpn; // Virtual Page Number
100.79 + uint32_t mask; // Page size mask
100.80 uint32_t asid; // Process ID
100.81 sh4addr_t ppn; // Physical Page Number
100.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 asid
100.88
100.89 static sh4ptr_t cache = NULL;
100.90
100.91 static void mmu_invalidate_tlb();
100.92
100.93
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.108
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 changed
100.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 bets
100.129 + // are off now. We also need to force an immediate exit from the
100.130 + // current block
100.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.143
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.154
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.174
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 read
100.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 queue
100.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 read
100.212 - }
100.213 - }
100.214 + mmu_utlb[mmu_urc].mask = get_mask_for_flags(mmu_utlb[mmu_urc].flags);
100.215 }
100.216
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.224
100.225 #define UTLB_ENTRY(addr) ((addr>>8)&0x3F)
100.226 @@ -273,9 +323,70 @@
100.227 }
100.228 }
100.229
100.230 +/**
100.231 + * Find a UTLB entry for the associative TLB write - same as the normal
100.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 normal
100.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.304
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 a
100.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 found
100.323 + * -1 No match - raise a tlb data miss exception
100.324 + * -2 Multiple matches - raise a multi-hit exception (reset)
100.325 + * @param vpn virtual address to resolve
100.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 only
100.353 + * Possible utcomes are:
100.354 + * 0..63 Single match - good, return entry found
100.355 + * -1 No match - raise a tlb data miss exception
100.356 + * -2 Multiple matches - raise a multi-hit exception (reset)
100.357 + * @param vpn virtual address to resolve
100.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 too
100.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 protection
100.415 + * Possible utcomes are:
100.416 + * 0..63 Single match - good, return entry found
100.417 + * -1 No match - raise a tlb data miss exception
100.418 + * -2 Multiple matches - raise a multi-hit exception (reset)
100.419 + * @param vpn virtual address to resolve
100.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 only
100.459 + * Possible utcomes are:
100.460 + * 0..63 Single match - good, return entry found
100.461 + * -1 No match - raise a tlb data miss exception
100.462 + * -2 Multiple matches - raise a multi-hit exception (reset)
100.463 + * @param vpn virtual address to resolve
100.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 address
100.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 the
100.640 + * given vma. If the address does not reference a RAM/ROM region, the icache
100.641 + * will be invalidated instead.
100.642 + * If AT is on, this method will raise TLB exceptions normally
100.643 + * (hence this method should only be used immediately prior to execution of
100.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 in
100.646 + * the icache.
100.647 + * @return TRUE if the update completed (successfully or otherwise), FALSE
100.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 +0000
101.2 +++ b/src/sh4/scif.c Tue Jan 15 20:50:23 2008 +0000
101.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 the
101.8 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs
101.9 * external serial port
102.1 --- a/src/sh4/sh4.c Thu Dec 20 09:56:07 2007 +0000
102.2 +++ b/src/sh4/sh4.c Tue Jan 15 20:50:23 2008 +0000
102.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 peripheral
102.9 * modules.
102.10 @@ -30,10 +30,6 @@
102.11 #include "clock.h"
102.12 #include "syscall.h"
102.13
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.29
102.30 void sh4_set_use_xlat( gboolean use )
102.31 {
102.32 @@ -70,6 +67,11 @@
102.33 #endif
102.34 }
102.35
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.46
102.47
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.58
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.63
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.75
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.88
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.110
102.111 gboolean sh4_raise_slot_exception( int normal_code, int slot_code ) {
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
103.2 +++ b/src/sh4/sh4.h Tue Jan 15 20:50:23 2008 +0000
103.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 SH4
103.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 modify
103.13 + * it under the terms of the GNU General Public License as published by
103.14 + * the Free Software Foundation; either version 2 of the License, or
103.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 of
103.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
103.20 + * GNU General Public License for more details.
103.21 + */
103.22 +
103.23 +#ifndef lxdream_sh4_H
103.24 +#define lxdream_sh4_H 1
103.25 +
103.26 +#include "lxdream.h"
103.27 +#include "mem.h"
103.28 +
103.29 +#ifdef __cplusplus
103.30 +extern "C" {
103.31 +#endif
103.32 +
103.33 +
103.34 +/**
103.35 + * SH4 is running normally
103.36 + */
103.37 +#define SH4_STATE_RUNNING 1
103.38 +/**
103.39 + * SH4 is not executing instructions but all peripheral modules are still
103.40 + * running
103.41 + */
103.42 +#define SH4_STATE_SLEEP 2
103.43 +/**
103.44 + * SH4 is not executing instructions, DMAC is halted, but all other peripheral
103.45 + * modules are still running
103.46 + */
103.47 +#define SH4_STATE_DEEP_SLEEP 3
103.48 +/**
103.49 + * SH4 is not executing instructions and all peripheral modules are also
103.50 + * stopped. As close as you can get to powered-off without actually being
103.51 + * off.
103.52 + */
103.53 +#define SH4_STATE_STANDBY 4
103.54 +
103.55 +/**
103.56 + * sh4r.event_types flag indicating a pending IRQ
103.57 + */
103.58 +#define PENDING_IRQ 1
103.59 +
103.60 +/**
103.61 + * sh4r.event_types flag indicating a pending event (from the event queue)
103.62 + */
103.63 +#define PENDING_EVENT 2
103.64 +
103.65 +/**
103.66 + * SH4 register structure
103.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 FFFFFFFF
103.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 in
103.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 this
103.95 + * should only be used while the system is stopped. If the system was built
103.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 next
103.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 a
103.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 __cplusplus
103.125 +}
103.126 +#endif
103.127 +#endif /* !lxdream_sh4_H */
104.1 --- a/src/sh4/sh4core.c Thu Dec 20 09:56:07 2007 +0000
104.2 +++ b/src/sh4/sh4core.c Tue Jan 15 20:50:23 2008 +0000
104.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 peripheral
104.9 * modules.
104.10 @@ -18,6 +18,7 @@
104.11 */
104.12
104.13 #define MODULE sh4_module
104.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.19
104.20 /********************** SH4 Module Definition ****************************/
104.21
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 #endif
104.31
104.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.44
104.45 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
104.46
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 reads
104.52
104.53 #define R0 sh4r.r[0]
104.54 pc = sh4r.pc;
104.55 @@ -236,22 +235,20 @@
104.56 CHECKRALIGN16(pc);
104.57
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 IO
104.66 - * region, fallback on the full-blown memory read
104.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 handler
104.76 + if( !mmu_update_icache(sh4r.pc) ) {
104.77 + // double fault - halt
104.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 +0000
105.2 +++ b/src/sh4/sh4core.h Tue Jan 15 20:50:23 2008 +0000
105.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.h
105.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.15
105.16 #ifdef __cplusplus
105.17 extern "C" {
105.18 -#if 0
105.19 -}
105.20 -#endif
105.21 #endif
105.22
105.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.27
105.28 /**
105.29 - * SH4 is running normally
105.30 + * Cached direct pointer to the current instruction page. If AT is on, this
105.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 of
105.33 + * assumptions about the "current page" that we can't make in general for
105.34 + * arbitrary virtual addresses.
105.35 */
105.36 -#define SH4_STATE_RUNNING 1
105.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 page
105.41 + uint32_t mask; // page mask
105.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 still
105.47 - * running
105.48 + * Test if a given address is contained in the current icache entry
105.49 */
105.50 -#define SH4_STATE_SLEEP 2
105.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 peripheral
105.54 - * modules are still running
105.55 + * Return a pointer for the given vma, under the assumption that it is
105.56 + * actually contained in the current icache entry.
105.57 */
105.58 -#define SH4_STATE_DEEP_SLEEP 3
105.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 also
105.62 - * stopped. As close as you can get to powered-off without actually being
105.63 - * off.
105.64 + * Return the physical (external) address for the given vma, assuming that it is
105.65 + * actually contained in the current icache entry.
105.66 */
105.67 -#define SH4_STATE_STANDBY 4
105.68 +#define GET_ICACHE_PHYS(addr) (sh4_icache.page_ppa + ((addr)-sh4_icache.page_vma))
105.69
105.70 -#define PENDING_IRQ 1
105.71 -#define PENDING_EVENT 2
105.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 FFFFFFFF
105.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 in
105.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.145
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 0x8000000
105.157 +/**
105.158 + * Update the sh4_icache structure to contain the specified vma. If the vma
105.159 + * cannot be resolved, an MMU exception is raised and the function returns
105.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 be
105.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.166
105.167 -#define BREAK_ONESHOT 1
105.168 -#define BREAK_PERM 2
105.169 +/**
105.170 + * Resolve a virtual address through the TLB for a read operation, returning
105.171 + * the resultant P4 or external address. If the resolution fails, the
105.172 + * appropriate MMU exception is raised and the value MMU_VMA_ERROR is returned.
105.173 + * @return An external address (0x00000000-0x1FFFFFFF), a P4 address
105.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.178
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.189
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 0x080
105.199 +#define EXC_TLB_PROT_READ 0x0A0
105.200 +#define EXC_TLB_PROT_WRITE 0x0C0
105.201 +#define EXC_DATA_ADDR_READ 0x0E0
105.202 +#define EXC_DATA_ADDR_WRITE 0x100
105.203 +#define EXC_TLB_MULTI_HIT 0x140
105.204 +#define EXC_SLOT_ILLEGAL 0x1A0
105.205 +#define EXC_ILLEGAL 0x180
105.206 +#define EXC_TRAP 0x160
105.207 +#define EXC_FPU_DISABLED 0x800
105.208 +#define EXC_SLOT_FPU_DISABLED 0x820
105.209
105.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.244
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.252
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 0x700083F3
105.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.260
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.266
105.267 -/* CPU-generated exception code/vector pairs */
105.268 -#define EXC_POWER_RESET 0x000 /* vector special */
105.269 -#define EXC_MANUAL_RESET 0x020
105.270 -#define EXC_DATA_ADDR_READ 0x0E0
105.271 -#define EXC_DATA_ADDR_WRITE 0x100
105.272 -#define EXC_SLOT_ILLEGAL 0x1A0
105.273 -#define EXC_ILLEGAL 0x180
105.274 -#define EXC_TRAP 0x160
105.275 -#define EXC_FPU_DISABLED 0x800
105.276 -#define EXC_SLOT_FPU_DISABLED 0x820
105.277 -
105.278 -/* Exceptions (for use with sh4_raise_exception) */
105.279 -
105.280 -#define EX_ILLEGAL_INSTRUCTION 0x180, 0x100
105.281 -#define EX_SLOT_ILLEGAL 0x1A0, 0x100
105.282 -#define EX_TLB_MISS_READ 0x040, 0x400
105.283 -#define EX_TLB_MISS_WRITE 0x060, 0x400
105.284 -#define EX_INIT_PAGE_WRITE 0x080, 0x100
105.285 -#define EX_TLB_PROT_READ 0x0A0, 0x100
105.286 -#define EX_TLB_PROT_WRITE 0x0C0, 0x100
105.287 -#define EX_DATA_ADDR_READ 0x0E0, 0x100
105.288 -#define EX_DATA_ADDR_WRITE 0x100, 0x100
105.289 -#define EX_FPU_EXCEPTION 0x120, 0x100
105.290 -#define EX_TRAPA 0x160, 0x100
105.291 -#define EX_BREAKPOINT 0x1E0, 0x100
105.292 -#define EX_FPU_DISABLED 0x800, 0x100
105.293 -#define EX_SLOT_FPU_DISABLED 0x820, 0x100
105.294 -
105.295 #define SH4_WRITE_STORE_QUEUE(addr,val) sh4r.store_queue[(addr>>2)&0xF] = val;
105.296
105.297 #ifdef __cplusplus
106.1 --- a/src/sh4/sh4core.in Thu Dec 20 09:56:07 2007 +0000
106.2 +++ b/src/sh4/sh4core.in Tue Jan 15 20:50:23 2008 +0000
106.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 peripheral
106.9 * modules.
106.10 @@ -18,6 +18,7 @@
106.11 */
106.12
106.13 #define MODULE sh4_module
106.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.19
106.20 /********************** SH4 Module Definition ****************************/
106.21
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 #endif
106.31
106.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.44
106.45 #define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
106.46
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 reads
106.52
106.53 #define R0 sh4r.r[0]
106.54 pc = sh4r.pc;
106.55 @@ -236,41 +235,39 @@
106.56 CHECKRALIGN16(pc);
106.57
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 IO
106.66 - * region, fallback on the full-blown memory read
106.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 handler
106.76 + if( !mmu_update_icache(sh4r.pc) ) {
106.77 + // double fault - halt
106.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.112
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 +0000
107.2 +++ b/src/sh4/sh4dasm.c Tue Jan 15 20:50:23 2008 +0000
107.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 functions
107.9 *
107.10 @@ -1550,19 +1550,16 @@
107.11 }
107.12
107.13
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.21
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 +0000
108.2 +++ b/src/sh4/sh4dasm.h Tue Jan 15 20:50:23 2008 +0000
108.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 declarations
108.9 *
108.10 @@ -28,7 +28,7 @@
108.11 #include <stdio.h>
108.12
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.16
108.17 extern const struct cpu_desc_struct sh4_cpu_desc;
108.18
109.1 --- a/src/sh4/sh4dasm.in Thu Dec 20 09:56:07 2007 +0000
109.2 +++ b/src/sh4/sh4dasm.in Tue Jan 15 20:50:23 2008 +0000
109.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 functions
109.9 *
109.10 @@ -285,19 +285,16 @@
109.11 }
109.12
109.13
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.21
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 +0000
110.2 +++ b/src/sh4/sh4mem.c Tue Jan 15 20:50:23 2008 +0000
110.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 memory
110.8 * mapped I/O), using the page maps created in mem.c
110.9 *
110.10 @@ -17,7 +17,6 @@
110.11 */
110.12
110.13 #define MODULE sh4_module
110.14 -#define ENABLE_TRACE_IO 1
110.15
110.16 #include <string.h>
110.17 #include <zlib.h>
110.18 @@ -68,7 +67,6 @@
110.19
110.20 extern struct mem_region mem_rgn[];
110.21 extern struct mmio_region *P4_io[];
110.22 -sh4ptr_t sh4_main_ram;
110.23
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.28
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.49
110.50 @@ -195,9 +193,9 @@
110.51 CHECK_READ_WATCH(addr,2);
110.52
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.73
110.74 @@ -227,9 +225,9 @@
110.75 CHECK_READ_WATCH(addr,1);
110.76
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.97
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.105
110.106 if( addr >= 0xE0000000 ) {
110.107 @@ -425,12 +423,19 @@
110.108 }
110.109 }
110.110
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 +0000
111.2 +++ b/src/sh4/sh4mmio.c Tue Jan 15 20:50:23 2008 +0000
111.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. Also
111.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 +0000
112.2 +++ b/src/sh4/sh4mmio.h Tue Jan 15 20:50:23 2008 +0000
112.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 sh4
112.9 * module.
113.1 --- a/src/sh4/sh4stat.c Thu Dec 20 09:56:07 2007 +0000
113.2 +++ b/src/sh4/sh4stat.c Tue Jan 15 20:50:23 2008 +0000
113.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 stats
113.9 *
114.1 --- a/src/sh4/sh4stat.h Thu Dec 20 09:56:07 2007 +0000
114.2 +++ b/src/sh4/sh4stat.h Tue Jan 15 20:50:23 2008 +0000
114.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 stats
114.9 *
115.1 --- a/src/sh4/sh4stat.in Thu Dec 20 09:56:07 2007 +0000
115.2 +++ b/src/sh4/sh4stat.in Tue Jan 15 20:50:23 2008 +0000
115.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 stats
115.9 *
116.1 --- a/src/sh4/sh4trans.c Thu Dec 20 09:56:07 2007 +0000
116.2 +++ b/src/sh4/sh4trans.c Tue Jan 15 20:50:23 2008 +0000
116.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-specific
116.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.21
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 breakpoints
116.34 @@ -38,6 +49,23 @@
116.35 }
116.36 }
116.37
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.61
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.70
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.78
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.82
116.83 /**
116.84 * Translate a linear basic block, ie all instructions from the start address
116.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.96
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.128
116.129 /**
116.130 - * Translate a linear basic block to a temporary buffer, execute it, and return
116.131 - * the result of the execution. The translation is discarded.
116.132 + * "Execute" the supplied recovery record. Currently this only updates
116.133 + * sh4r.pc and sh4r.slice_cycle according to the currently executing
116.134 + * instruction. In future this may be more sophisticated (ie will
116.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.144
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.152
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 necessary
116.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_slice
116.165 + xlat_running = FALSE;
116.166 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
116.167 +}
116.168
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 translator
116.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 necessary
116.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_slice
116.187 + xlat_running = FALSE;
116.188 + longjmp(xlat_jmp_buf, exit_code);
116.189 +}
116.190
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 the
116.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 last
116.198 + * instruction in the block (ie it's in a delay slot), this function
116.199 + * returns to allow normal completion of the translation block. Otherwise
116.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 necessary
116.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 hook
116.230 + return NULL;
116.231 + }
116.232 + if( !mmu_update_icache(sh4r.pc) ) {
116.233 + // fault - off to the fault handler
116.234 + if( !mmu_update_icache(sh4r.pc) ) {
116.235 + // double fault - halt
116.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 +0000
117.2 +++ b/src/sh4/sh4trans.h Tue Jan 15 20:50:23 2008 +0000
117.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 module
117.9 *
117.10 @@ -16,6 +16,7 @@
117.11 * GNU General Public License for more details.
117.12 */
117.13
117.14 +#include "sh4/xltcache.h"
117.15 #include "dream.h"
117.16 #include "mem.h"
117.17
117.18 @@ -27,18 +28,53 @@
117.19 * allows a little room
117.20 */
117.21 #define EPILOGUE_SIZE 128
117.22 +
117.23 +/** Maximum number of recovery records for a translated block (2048 based on
117.24 + * 1 record per SH4 instruction in a 4K page).
117.25 + */
117.26 +#define MAX_RECOVERY_SIZE 2048
117.27 +
117.28 /**
117.29 + * Translation flag - exit the current block but continue (eg exception handling)
117.30 + */
117.31 +#define XLAT_EXIT_CONTINUE 1
117.32
117.33 +/**
117.34 + * Translation flag - exit the current block and halt immediately (eg fatal error)
117.35 + */
117.36 +#define XLAT_EXIT_HALT 2
117.37 +
117.38 +/**
117.39 + * Translation flag - exit the current block and halt immediately for a system
117.40 + * breakpoint.
117.41 + */
117.42 +#define XLAT_EXIT_BREAKPOINT 3
117.43 +
117.44 +/**
117.45 + * Translation flag - exit the current block and continue after performing a full
117.46 + * system reset (dreamcast_reset())
117.47 + */
117.48 +#define XLAT_EXIT_SYSRESET 4
117.49 +
117.50 +/**
117.51 */
117.52 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );
117.53
117.54 /**
117.55 + * Return true if translated code is currently running
117.56 + */
117.57 +gboolean sh4_xlat_is_running();
117.58 +
117.59 +/**
117.60 * Translate the specified block of code starting from the specified start
117.61 * address until the first branch/jump instruction.
117.62 */
117.63 void *sh4_translate_basic_block( sh4addr_t start );
117.64
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.69
117.70 /******************************************************************************
117.71 * Code generation - these methods must be provided by the
117.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) and
117.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 the
117.85 + * exception and generating the appropriate recovery block(s) - currently this means
117.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 returning
117.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 with
117.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 +0000
118.2 +++ b/src/sh4/sh4x86.c Tue Jan 15 20:50:23 2008 +0000
118.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 just
118.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
118.10 @@ -34,6 +34,14 @@
118.11
118.12 #define DEFAULT_BACKPATCH_SIZE 4096
118.13
118.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 2048
118.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() and
118.25 @@ -48,10 +56,15 @@
118.26 uint32_t stack_posn; /* Trace stack height for alignment purposes */
118.27 int tstate;
118.28
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.40
118.41 #define TSTATE_NONE -1
118.42 @@ -75,14 +88,6 @@
118.43 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
118.44 MARK_JMP(rel8, label)
118.45
118.46 -
118.47 -#define EXIT_DATA_ADDR_READ 0
118.48 -#define EXIT_DATA_ADDR_WRITE 7
118.49 -#define EXIT_ILLEGAL 14
118.50 -#define EXIT_SLOT_ILLEGAL 21
118.51 -#define EXIT_FPU_DISABLED 28
118.52 -#define EXIT_SLOT_FPU_DISABLED 35
118.53 -
118.54 static struct sh4_x86_state sh4_x86;
118.55
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.64
118.65
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.85
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.97
118.98 /**
118.99 @@ -266,86 +277,46 @@
118.100 }
118.101
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.104
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.119
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.149
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.165
118.166 -}
118.167 +#define check_walign16( x86reg ) \
118.168 + TEST_imm32_r32( 0x00000001, x86reg ); \
118.169 + JNE_exc(EXC_DATA_ADDR_WRITE);
118.170
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.179
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.199
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.205
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 turned
118.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 turned
118.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.217
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.225
118.226 /****** Import appropriate calling conventions ******/
118.227 #if SH4_TRANSLATOR == TARGET_X86_64
118.228 @@ -372,11 +355,18 @@
118.229 #endif
118.230 #endif
118.231
118.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.238
118.239 /**
118.240 * Translate a single instruction. Delayed branches are handled specially
118.241 * by translating both branch and delayed instruction as a single unit (as
118.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 block
118.246 * (eg a branch or
118.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 IO
118.259 - * region, fallback on the full-blown memory read
118.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 running
118.272 + * with MMU on, and we've gone past the end of the page. And since
118.273 + * sh4_translate_block is pretty careful about this, it means we're
118.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 in
118.277 + * at this point, inline a call to sh4_execute_instruction (with a few
118.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 worth
118.431 + // adding a page-boundary check to skip the second translation
118.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 worth
118.1122 + // adding a page-boundary check to skip the second translation
118.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 rel32
118.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 taken
118.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 rel32
118.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 taken
118.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), Rn
118.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's
118.1577 + // pretty safe to just ref it directly and circumvent the whole
118.1578 + // memory subsystem. (this is a big performance win)
118.1579 +
118.1580 + // FIXME: There's a corner-case that's not handled here when
118.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 SH4
118.1583 + // behaviour to confirm) Unlikely to be anyone depending on this
118.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 a
118.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 it
118.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 ); // 12
118.1672 + load_fr( R_EDX, R_ECX, FRm );
118.1673 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
118.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 it
118.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 it
118.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 ); // 12
118.1816 + load_fr( R_EDX, R_ECX, FRm );
118.1817 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
118.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 ); // 12
118.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 ); // 12
118.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 +0000
119.2 +++ b/src/sh4/sh4x86.in Tue Jan 15 20:50:23 2008 +0000
119.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 just
119.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
119.10 @@ -34,6 +34,14 @@
119.11
119.12 #define DEFAULT_BACKPATCH_SIZE 4096
119.13
119.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 2048
119.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() and
119.25 @@ -48,10 +56,15 @@
119.26 uint32_t stack_posn; /* Trace stack height for alignment purposes */
119.27 int tstate;
119.28
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.40
119.41 #define TSTATE_NONE -1
119.42 @@ -75,14 +88,6 @@
119.43 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
119.44 MARK_JMP(rel8, label)
119.45
119.46 -
119.47 -#define EXIT_DATA_ADDR_READ 0
119.48 -#define EXIT_DATA_ADDR_WRITE 7
119.49 -#define EXIT_ILLEGAL 14
119.50 -#define EXIT_SLOT_ILLEGAL 21
119.51 -#define EXIT_FPU_DISABLED 28
119.52 -#define EXIT_SLOT_FPU_DISABLED 35
119.53 -
119.54 static struct sh4_x86_state sh4_x86;
119.55
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.64
119.65
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.85
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.97
119.98 /**
119.99 @@ -266,86 +277,46 @@
119.100 }
119.101
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.104
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.119
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.149
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.165
119.166 -}
119.167 +#define check_walign16( x86reg ) \
119.168 + TEST_imm32_r32( 0x00000001, x86reg ); \
119.169 + JNE_exc(EXC_DATA_ADDR_WRITE);
119.170
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.179
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.199
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.205
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 turned
119.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 turned
119.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.217
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.225
119.226 /****** Import appropriate calling conventions ******/
119.227 #if SH4_TRANSLATOR == TARGET_X86_64
119.228 @@ -372,11 +355,18 @@
119.229 #endif
119.230 #endif
119.231
119.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.238
119.239 /**
119.240 * Translate a single instruction. Delayed branches are handled specially
119.241 * by translating both branch and delayed instruction as a single unit (as
119.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 block
119.246 * (eg a branch or
119.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 IO
119.259 - * region, fallback on the full-blown memory read
119.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 running
119.272 + * with MMU on, and we've gone past the end of the page. And since
119.273 + * sh4_translate_block is pretty careful about this, it means we're
119.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 in
119.277 + * at this point, inline a call to sh4_execute_instruction (with a few
119.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 worth
119.328 + // adding a page-boundary check to skip the second translation
119.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 worth
119.373 + // adding a page-boundary check to skip the second translation
119.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's
119.704 + // pretty safe to just ref it directly and circumvent the whole
119.705 + // memory subsystem. (this is a big performance win)
119.706 +
119.707 + // FIXME: There's a corner-case that's not handled here when
119.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 SH4
119.710 + // behaviour to confirm) Unlikely to be anyone depending on this
119.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 a
119.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), Rn
119.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.934
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 rel32
119.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 taken
119.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 rel32
119.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 taken
119.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 ); // 12
119.1032 + load_fr( R_EDX, R_ECX, FRm );
119.1033 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
119.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 it
119.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 ); // 12
119.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 ); // 12
119.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 it
119.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 ); // 12
119.1229 + load_fr( R_EDX, R_ECX, FRm );
119.1230 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
119.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 it
119.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 :}
119.1782
120.1 --- a/src/sh4/timer.c Thu Dec 20 09:56:07 2007 +0000
120.2 +++ b/src/sh4/timer.c Tue Jan 15 20:50:23 2008 +0000
120.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 to
120.9 * keep things simple (they intertwine a bit).
121.1 --- a/src/sh4/x86op.h Thu Dec 20 09:56:07 2007 +0000
121.2 +++ b/src/sh4/x86op.h Tue Jan 15 20:50:23 2008 +0000
121.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)+4
121.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.21
121.22 +/** JMP relative 8 or 32 depending on size of rel. rel offset
121.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.26
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.59
121.60
121.61 /* Conditional moves ebp-rel */
122.1 --- a/src/sh4/xltcache.c Thu Dec 20 09:56:07 2007 +0000
122.2 +++ b/src/sh4/xltcache.c Tue Jan 15 20:50:23 2008 +0000
122.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.12
122.13 #include "dreamcast.h"
122.14 +#include "sh4/sh4core.h"
122.15 #include "sh4/xltcache.h"
122.16 #include "x86dasm/x86dasm.h"
122.17
122.18 @@ -207,6 +208,35 @@
122.19 return result;
122.20 }
122.21
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 happen
122.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.57
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 data
122.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 +0000
123.2 +++ b/src/sh4/xltcache.h Tue Jan 15 20:50:23 2008 +0000
123.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.13
123.14 -typedef struct xlat_cache_block {
123.15 +#ifndef lxdream_xltcache_H
123.16 +#define lxdream_xltcache_H
123.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 more
123.21 + * detailed recovery may be required if the translator optimizes more
123.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) pc
123.29 + uint32_t sh4_icount; // instruction number of the corresponding SH4 instruction
123.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.44
123.45 /**
123.46 * Initialize the translation cache
123.47 @@ -74,18 +96,53 @@
123.48 void *xlat_get_code( sh4addr_t address );
123.49
123.50 /**
123.51 + * Retrieve the recovery record corresponding to the given
123.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 executing
123.55 + * @param recover_after If TRUE, return the first record after the given pc, otherwise
123.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 given
123.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 miss
123.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 the
123.71 * given SH4 address.
123.72 */
123.73 void **xlat_get_lut_entry( sh4addr_t address );
123.74
123.75 /**
123.76 - * Retrieve the size of the code block starting at the specified pointer. If the
123.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 translated
123.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 the
123.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.89
123.90 /**
123.91 + * Retrieve the size of the code in the block starting at the specified
123.92 + * pointer. Effectively this is xlat_get_block_size() minus the size of
123.93 + * the recovery table. If the pointer is not a valid code block, the
123.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 address
123.100 */
123.101 void xlat_flush_page( sh4addr_t address );
123.102 @@ -108,3 +165,5 @@
123.103 * Check the internal integrity of the cache
123.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 +0000
124.2 +++ b/src/syscall.c Tue Jan 15 20:50:23 2008 +0000
124.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 SH4
124.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.16
124.17
124.18 struct syscall_hook {
125.1 --- a/src/syscall.h Thu Dec 20 09:56:07 2007 +0000
125.2 +++ b/src/syscall.h Tue Jan 15 20:50:23 2008 +0000
125.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 out
125.9 * to the emu.
126.1 --- a/src/test/testsh4x86.c Thu Dec 20 09:56:07 2007 +0000
126.2 +++ b/src/test/testsh4x86.c Tue Jan 15 20:50:23 2008 +0000
126.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 as
126.9 * input a binary SH4 object (and VMA), generates the
126.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.19
126.20 #define MAX_INS_SIZE 32
126.21
126.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.28
126.29 char *inbuf;
126.30 @@ -64,30 +70,32 @@
126.31 // Stubs
126.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.67
126.68 void usage()
126.69 {
127.1 --- a/src/test/testxlt.c Thu Dec 20 09:56:07 2007 +0000
127.2 +++ b/src/test/testxlt.c Tue Jan 15 20:50:23 2008 +0000
127.3 @@ -1,3 +1,21 @@
127.4 +/**
127.5 + * $Id$
127.6 + *
127.7 + * Translation cache test functions
127.8 + *
127.9 + * Copyright (c) 2005 Nathan Keynes.
127.10 + *
127.11 + * This program is free software; you can redistribute it and/or modify
127.12 + * it under the terms of the GNU General Public License as published by
127.13 + * the Free Software Foundation; either version 2 of the License, or
127.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 of
127.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
127.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 +0000
128.2 +++ b/src/tools/actparse.c Tue Jan 15 20:50:23 2008 +0000
128.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 modify
128.12 + * it under the terms of the GNU General Public License as published by
128.13 + * the Free Software Foundation; either version 2 of the License, or
128.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 of
128.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128.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 +0000
129.2 +++ b/src/tools/gendec.c Tue Jan 15 20:50:23 2008 +0000
129.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 appropriate
129.9 * instruction decoder.
130.1 --- a/src/tools/gendec.h Thu Dec 20 09:56:07 2007 +0000
130.2 +++ b/src/tools/gendec.h Tue Jan 15 20:50:23 2008 +0000
130.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 memory
130.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 +0000
131.2 +++ b/src/tools/genglsl.c Tue Jan 15 20:50:23 2008 +0000
131.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 in
131.9 * a C file with appropriate escaping.
132.1 --- a/src/tools/insparse.c Thu Dec 20 09:56:07 2007 +0000
132.2 +++ b/src/tools/insparse.c Tue Jan 15 20:50:23 2008 +0000
132.3 @@ -1,3 +1,21 @@
132.4 +/**
132.5 + * $Id$
132.6 + *
132.7 + * gendec instruction definitions parser
132.8 + *
132.9 + * Copyright (c) 2005 Nathan Keynes.
132.10 + *
132.11 + * This program is free software; you can redistribute it and/or modify
132.12 + * it under the terms of the GNU General Public License as published by
132.13 + * the Free Software Foundation; either version 2 of the License, or
132.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 of
132.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
132.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 +0000
133.2 +++ b/src/util.c Tue Jan 15 20:50:23 2008 +0000
133.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.16
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.22
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 +0000
134.2 +++ b/src/watch.c Tue Jan 15 20:50:23 2008 +0000
134.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 modify
134.12 + * it under the terms of the GNU General Public License as published by
134.13 + * the Free Software Foundation; either version 2 of the License, or
134.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 of
134.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
134.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 +0000
135.2 +++ b/src/x86dasm/x86dasm.c Tue Jan 15 20:50:23 2008 +0000
135.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 other
135.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.17
135.18 extern const struct reg_desc_struct sh4_reg_map[];
135.19 @@ -43,7 +43,7 @@
135.20
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 +0000
136.2 +++ b/src/x86dasm/x86dasm.h Tue Jan 15 20:50:23 2008 +0000
136.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 other
136.9 * disassembly functions.
137.1 --- a/test/Makefile.in Thu Dec 20 09:56:07 2007 +0000
137.2 +++ b/test/Makefile.in Tue Jan 15 20:50:23 2008 +0000
137.3 @@ -17,6 +17,7 @@
137.4 ARMOBJCOPY = @ARMOBJCOPY@
137.5
137.6 RUNTEST = ../src/lxdream -c ./lxdream.rc -puh -A null
137.7 +RUNTESTX = ../src/lxdream -c ./lxdream.rc -xpuh -A null
137.8
137.9
137.10 # cygwin
137.11 @@ -62,10 +63,11 @@
137.12 all: build-tests
137.13
137.14 check: build-tests
137.15 - cat testta.data testta2.data testta3.data testta4.data testta5.data | $(RUNTEST) testta
137.16 $(RUNTEST) testsh4
137.17 + $(RUNTESTX) testsh4
137.18 $(RUNTEST) testmmu
137.19 $(RUNTEST) testregs
137.20 + cat testta.data testta2.data testta3.data testta4.data testta5.data | $(RUNTEST) testta
137.21 # $(RUNTEST) testide -d ../disc/test.nrg
137.22
137.23
137.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.so
137.29 + sh4/excslot.so sh4/undef.so sh4/tlb.so
137.30 $(SH4CC) $(SH4LDFLAGS) $^ -o $@ $(SH4LIBS)
137.31 $(SH4OBJCOPY) testsh4 testsh4.bin
137.32
138.1 --- a/test/asic.c Thu Dec 20 09:56:07 2007 +0000
138.2 +++ b/test/asic.c Tue Jan 15 20:50:23 2008 +0000
138.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 code
138.9 *
139.1 --- a/test/bin2c.c Thu Dec 20 09:56:07 2007 +0000
139.2 +++ b/test/bin2c.c Tue Jan 15 20:50:23 2008 +0000
139.3 @@ -3,7 +3,7 @@
139.4
139.5 (c)2000 Dan Potter
139.6
139.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 -NK
139.10 */
139.11
140.1 --- a/test/dma.h Thu Dec 20 09:56:07 2007 +0000
140.2 +++ b/test/dma.h Tue Jan 15 20:50:23 2008 +0000
140.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 code
140.9 *
141.1 --- a/test/dmac.c Thu Dec 20 09:56:07 2007 +0000
141.2 +++ b/test/dmac.c Tue Jan 15 20:50:23 2008 +0000
141.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 code
141.9 *
142.1 --- a/test/pvr.c Thu Dec 20 09:56:07 2007 +0000
142.2 +++ b/test/pvr.c Tue Jan 15 20:50:23 2008 +0000
142.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 code
142.9 *
143.1 --- a/test/pvr.h Thu Dec 20 09:56:07 2007 +0000
143.2 +++ b/test/pvr.h Tue Jan 15 20:50:23 2008 +0000
143.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 code
143.9 *
144.1 --- a/test/rendload.c Thu Dec 20 09:56:07 2007 +0000
144.2 +++ b/test/rendload.c Tue Jan 15 20:50:23 2008 +0000
144.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.c
144.9 *
145.1 --- a/test/sh4/inc.s Thu Dec 20 09:56:07 2007 +0000
145.2 +++ b/test/sh4/inc.s Tue Jan 15 20:50:23 2008 +0000
145.3 @@ -240,6 +240,24 @@
145.4 L3:
145.5 .endm
145.6
145.7 +.macro assert_tlb_exc_caught testname, expectpc, expectvpn
145.8 +LOCAL L1, L2, L3
145.9 + mov.l L1, r3
145.10 + mov.l \testname, r4
145.11 + mov r12, r5
145.12 + mov.l L2, r6
145.13 + mov.l \expectvpn, r7
145.14 + jsr @r3
145.15 + nop
145.16 + add r0, r13
145.17 + bra L3
145.18 + nop
145.19 +.align 4
145.20 +L1: .long _assert_exception_caught
145.21 +L2: .long \expectpc
145.22 +L3:
145.23 +.endm
145.24 +
145.25 .align 2
145.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 +0000
146.2 +++ b/test/sh4/testsh4.c Tue Jan 15 20:50:23 2008 +0000
146.3 @@ -1,4 +1,5 @@
146.4 #include <stdio.h>
146.5 +#include "../lib.h"
146.6
146.7 int total_tests = 0;
146.8 int total_fails = 0;
146.9 @@ -42,6 +43,29 @@
146.10 }
146.11 }
146.12
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.45
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 +0000
147.2 +++ b/test/sh4/tlb.s Tue Jan 15 20:50:23 2008 +0000
147.3 @@ -0,0 +1,165 @@
147.4 +.section .text
147.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 reset
147.10 +! rather than a regular exception.
147.11 +
147.12 +.global _test_tlb
147.13 +_test_tlb:
147.14 + start_test
147.15 +
147.16 +! Turn on AT, and flush the current TLB (if any)
147.17 +! Initialize to SV=0, SQMD=0, URB=URC=LRUI=0
147.18 + mov.l test_tlb_mmucr, r0
147.19 + mov #5, r1
147.20 + mov.l r1, @r0
147.21 +
147.22 +! Privileged mode tests first (much easier)
147.23 + add #1, r12
147.24 + mov.l test_tlb1_pteh, r1
147.25 + mov.l test_tlb_pteh, r2
147.26 + mov.l r1, @r2
147.27 + mov.l test_tlb1_ptel, r1
147.28 + mov.l test_tlb_ptel, r2
147.29 + mov.l r1, @r2
147.30 + ldtlb
147.31 +
147.32 +! Simple read
147.33 + mov.l test_tlb1_direct, r3
147.34 + mov #42, r2
147.35 + mov.l r2, @r3
147.36 + mov.l test_tlb1_mmu, r0
147.37 + mov.l @r0, r1
147.38 + cmp/eq r1, r2
147.39 + bt test_tlb_2
147.40 + fail test_tlb_str_k
147.41 + bra test_tlb_2
147.42 + nop
147.43 +test_tlb1_pteh:
147.44 + .long 0x12345012
147.45 +test_tlb1_ptel:
147.46 + .long 0x005F8120
147.47 +
147.48 +test_tlb_2:
147.49 + ! Trigger an initial-page-write exception
147.50 + add #1, r12
147.51 + expect_exc 0x00000080
147.52 + mov.l test_tlb1_mmu, r0
147.53 +test_tlb2_exc:
147.54 + mov.l r0, @r0
147.55 + assert_tlb_exc_caught test_tlb_str_k test_tlb2_exc test_tlb1_mmu
147.56 +
147.57 +test_tlb_3:
147.58 + ! Trigger a missing page read exception by invalidation
147.59 + add #1, r12
147.60 + mov.l test_tlb3_addr, r1
147.61 + mov.l test_tlb3_data, r2
147.62 + mov.l r2, @r1
147.63 +
147.64 + expect_exc 0x00000040
147.65 + mov.l test_tlb1_mmu, r0
147.66 +test_tlb3_exc:
147.67 + mov.l @r0, r2
147.68 + assert_tlb_exc_caught test_tlb_str_k, test_tlb3_exc, test_tlb1_mmu
147.69 + bra test_tlb_4
147.70 + nop
147.71 +
147.72 +test_tlb3_addr:
147.73 + .long 0xF6000F80
147.74 +test_tlb3_data:
147.75 + .long 0x12345212
147.76 +
147.77 +test_tlb_4:
147.78 + ! Test missing page write exception on the same page
147.79 + add #1, r12
147.80 + expect_exc 0x00000060
147.81 + mov.l test_tlb1_mmu, r0
147.82 +test_tlb4_exc:
147.83 + mov.l r2, @r0
147.84 + assert_tlb_exc_caught test_tlb_str_k, test_tlb4_exc, test_tlb1_mmu
147.85 +
147.86 +test_tlb_5: ! Test initial write exception
147.87 + add #1, r12
147.88 +
147.89 + mov.l test_tlb5_addr, r1
147.90 + mov.l test_tlb5_data, r2
147.91 + mov.l r2, @r1
147.92 +
147.93 + expect_exc 0x00000080
147.94 + mov.l test_tlb1_mmu, r0
147.95 + mov #63, r3
147.96 +test_tlb5_exc:
147.97 + mov.l r3, @r0
147.98 + assert_tlb_exc_caught test_tlb_str_k, test_tlb5_exc, test_tlb1_mmu
147.99 + mov.l test_tlb1_direct, r3
147.100 + mov.l @r3, r4
147.101 + mov #42, r2
147.102 + cmp/eq r2, r4
147.103 + bf test_tlb5_fail
147.104 + mov.l test_tlb1_mmu, r0
147.105 + mov.l @r0, r3
147.106 + cmp/eq r2, r3
147.107 + bt test_tlb_6
147.108 +test_tlb5_fail:
147.109 + fail test_tlb_str_k
147.110 +
147.111 +test_tlb5_addr:
147.112 + .long 0xF6000000
147.113 +test_tlb5_data:
147.114 + .long 0x12345112
147.115 +
147.116 +test_tlb_6:! Test successful write.
147.117 + add #1, r12
147.118 +
147.119 + mov.l test_tlb6_addr, r1
147.120 + mov.l test_tlb6_data, r2
147.121 + mov.l r2, @r1
147.122 +
147.123 + mov.l test_tlb1_mmu, r0
147.124 + mov #77, r3
147.125 + mov.l r3, @r0
147.126 + mov.l test_tlb1_direct, r1
147.127 + mov.l @r1, r2
147.128 + cmp/eq r2, r3
147.129 + bt test_tlb_7
147.130 + fail test_tlb_str_k
147.131 + bra test_tlb_7
147.132 + nop
147.133 +
147.134 +test_tlb_7:
147.135 + bra test_tlb_end
147.136 + nop
147.137 +
147.138 +test_tlb6_addr:
147.139 + .long 0xF6000F80
147.140 +test_tlb6_data:
147.141 + .long 0x12345312
147.142 +
147.143 +
147.144 +test_tlb1_mmu:
147.145 + .long 0x12345040
147.146 +test_tlb1_direct:
147.147 + .long 0xA05F8040 ! Display border colour
147.148 +
147.149 +test_tlb_end:
147.150 + xor r0, r0
147.151 + mov.l test_tlb_mmucr, r1
147.152 + mov.l r0, @r1
147.153 +
147.154 + end_test test_tlb_str_k
147.155 +
147.156 +test_tlb_mmucr:
147.157 + .long 0xFF000010
147.158 +test_tlb_pteh:
147.159 + .long 0xFF000000
147.160 +test_tlb_ptel:
147.161 + .long 0xFF000004
147.162 +test_tlb_tea:
147.163 + .long 0xFF00000C
147.164 +test_tlb_str:
147.165 + .string "TLB"
147.166 +.align 4
147.167 +test_tlb_str_k:
147.168 + .long test_tlb_str
148.1 --- a/test/testdata.c Thu Dec 20 09:56:07 2007 +0000
148.2 +++ b/test/testdata.c Tue Jan 15 20:50:23 2008 +0000
148.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 +0000
149.2 +++ b/test/testdata.h Tue Jan 15 20:50:23 2008 +0000
149.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 loader
149.9 *
150.1 --- a/test/testdisp.c Thu Dec 20 09:56:07 2007 +0000
150.2 +++ b/test/testdisp.c Tue Jan 15 20:50:23 2008 +0000
150.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 (obviously
150.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 +0000
151.2 +++ b/test/testide.c Tue Jan 15 20:50:23 2008 +0000
151.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 the
151.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 +0000
152.2 +++ b/test/testregs.c Tue Jan 15 20:50:23 2008 +0000
152.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 check
152.9 * that we read back what we expect" tests.
153.1 --- a/test/testrend.c Thu Dec 20 09:56:07 2007 +0000
153.2 +++ b/test/testrend.c Tue Jan 15 20:50:23 2008 +0000
153.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 cases
153.9 *
154.1 --- a/test/testta.c Thu Dec 20 09:56:07 2007 +0000
154.2 +++ b/test/testta.c Tue Jan 15 20:50:23 2008 +0000
154.3 @@ -1,5 +1,5 @@
154.4 /**
154.5 - * $Id: testta.c,v 1.4 2006-08-18 09:32:32 nkeynes Exp $
154.6 + * $Id$
154.7 *
154.8 * Tile Accelerator test cases
154.9 *
155.1 --- a/test/testyuv.c Thu Dec 20 09:56:07 2007 +0000
155.2 +++ b/test/testyuv.c Tue Jan 15 20:50:23 2008 +0000
155.3 @@ -1,5 +1,5 @@
155.4 /**
155.5 - * $Id: testyuv.c,v 1.2 2007-01-15 10:41:30 nkeynes Exp $
155.6 + * $Id$
155.7 *
155.8 * Renderer test cases
155.9 *
.