revision 577:a181aeacd6e8
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 577:a181aeacd6e8 |
parent | 576:4945fa2ed24f |
child | 578:5fbe050b0558 |
author | nkeynes |
date | Mon Jan 14 10:23:49 2008 +0000 (16 years ago) |
branch | lxdream-mmu |
Remove asm file and convert to inline (easier to cope with platform conventions)
Add breakpoint support
Add MMU store-queue support
Add breakpoint support
Add MMU store-queue support
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/sh4/ia32abi.h | view | annotate | diff | log | ||
src/sh4/ia32asm.s | view | annotate | diff | log | ||
src/sh4/ia32mac.h | view | annotate | diff | log | ||
src/sh4/ia64abi.h | view | annotate | diff | log | ||
src/sh4/mmu.c | view | annotate | diff | log | ||
src/sh4/sh4.c | view | annotate | diff | log | ||
src/sh4/sh4core.h | view | annotate | diff | log | ||
src/sh4/sh4mem.c | view | annotate | diff | log | ||
src/sh4/sh4trans.c | view | annotate | diff | log | ||
src/sh4/sh4trans.h | view | annotate | diff | log | ||
src/sh4/sh4x86.c | view | annotate | diff | log | ||
src/sh4/sh4x86.in | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Mon Jan 14 09:08:58 2008 +00001.2 +++ b/src/Makefile.am Mon Jan 14 10:23:49 2008 +00001.3 @@ -51,25 +51,13 @@1.4 x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c1.6 test_testsh4x86_LDADD = @GTK_LIBS@1.7 -1.8 -check_PROGRAMS += test/testsh4x861.9 -1.10 -if BUILD_X86_641.11 -lxdream_SOURCES += sh4/ia64asm.s1.12 test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \1.13 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \1.14 x86dasm/dis-buf.c \1.15 sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \1.16 - sh4/xltcache.h mem.c util.c sh4/ia64asm.s1.17 -else1.18 -lxdream_SOURCES += sh4/ia32asm.s1.19 -test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \1.20 - x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \1.21 - x86dasm/dis-buf.c \1.22 - sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \1.23 - sh4/xltcache.h mem.c util.c sh4/ia32asm.s1.24 -endif1.25 + sh4/xltcache.h mem.c util.c sh4/mmu.c1.27 +check_PROGRAMS += test/testsh4x861.28 endif1.30 if GUI_GTK
2.1 --- a/src/Makefile.in Mon Jan 14 09:08:58 2008 +00002.2 +++ b/src/Makefile.in Mon Jan 14 10:23:49 2008 +00002.3 @@ -43,18 +43,16 @@2.4 @BUILD_SH4X86_TRUE@ x86dasm/i386-dis.c x86dasm/dis-init.c x86dasm/dis-buf.c2.6 @BUILD_SH4X86_TRUE@am__append_2 = test/testsh4x862.7 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am__append_3 = sh4/ia64asm.s2.8 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am__append_4 = sh4/ia32asm.s2.9 -@GUI_GTK_TRUE@am__append_5 = gtkui/gtkui.c gtkui/gtkui.h \2.10 +@GUI_GTK_TRUE@am__append_3 = gtkui/gtkui.c gtkui/gtkui.h \2.11 @GUI_GTK_TRUE@ gtkui/main_win.c gtkui/gtkcb.c \2.12 @GUI_GTK_TRUE@ gtkui/mmio_win.c gtkui/debug_win.c gtkui/dump_win.c \2.13 @GUI_GTK_TRUE@ gtkui/ctrl_dlg.c gtkui/path_dlg.c gtkui/gdrom_menu.c \2.14 @GUI_GTK_TRUE@ drivers/video_gtk.c drivers/video_gtk.h \2.15 @GUI_GTK_TRUE@ drivers/video_glx.c drivers/video_glx.h2.17 -@CDROM_LINUX_TRUE@am__append_6 = drivers/cd_linux.c2.18 -@CDROM_LINUX_FALSE@am__append_7 = drivers/cd_none.c2.19 -@AUDIO_ESOUND_TRUE@am__append_8 = drivers/audio_esd.c2.20 +@CDROM_LINUX_TRUE@am__append_4 = drivers/cd_linux.c2.21 +@CDROM_LINUX_FALSE@am__append_5 = drivers/cd_none.c2.22 +@AUDIO_ESOUND_TRUE@am__append_6 = drivers/audio_esd.c2.23 ACLOCAL = @ACLOCAL@2.24 AMDEP_FALSE = @AMDEP_FALSE@2.25 AMDEP_TRUE = @AMDEP_TRUE@2.26 @@ -233,20 +231,14 @@2.27 drivers/audio_null.c drivers/video_null.c \2.28 drivers/gl_common.c drivers/gl_common.h drivers/gl_fbo.c \2.29 drivers/gl_sl.c drivers/gl_slsrc.c\2.30 -$(am__append_1) $(am__append_3) $(am__append_4) $(am__append_5) $(am__append_6) $(am__append_7) $(am__append_8)2.31 +$(am__append_1) $(am__append_3) $(am__append_4) $(am__append_5) $(am__append_6)2.33 @BUILD_SH4X86_TRUE@test_testsh4x86_LDADD = @GTK_LIBS@2.34 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \2.35 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.36 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm/dis-buf.c \2.37 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \2.38 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4/xltcache.h mem.c util.c sh4/ia32asm.s2.39 -2.40 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \2.41 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.42 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm/dis-buf.c \2.43 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \2.44 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4/xltcache.h mem.c util.c sh4/ia64asm.s2.45 +@BUILD_SH4X86_TRUE@test_testsh4x86_SOURCES = test/testsh4x86.c x86dasm/x86dasm.c \2.46 +@BUILD_SH4X86_TRUE@ x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.47 +@BUILD_SH4X86_TRUE@ x86dasm/dis-buf.c \2.48 +@BUILD_SH4X86_TRUE@ sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c sh4/xltcache.c \2.49 +@BUILD_SH4X86_TRUE@ sh4/xltcache.h mem.c util.c sh4/mmu.c2.52 lxdream_LDADD = @GTK_LIBS@ @LIBPNG_LIBS@ @ESOUND_LIBS@ $(INTLLIBS)2.53 @@ -297,26 +289,24 @@2.54 sh4/sh4x86.c sh4/x86op.h sh4/ia32abi.h sh4/ia32mac.h \2.55 sh4/ia64abi.h sh4/sh4trans.c sh4/sh4trans.h x86dasm/x86dasm.c \2.56 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.57 - x86dasm/dis-buf.c sh4/ia64asm.s sh4/ia32asm.s gtkui/gtkui.c \2.58 - gtkui/gtkui.h gtkui/main_win.c gtkui/gtkcb.c gtkui/mmio_win.c \2.59 - gtkui/debug_win.c gtkui/dump_win.c gtkui/ctrl_dlg.c \2.60 - gtkui/path_dlg.c gtkui/gdrom_menu.c drivers/video_gtk.c \2.61 - drivers/video_gtk.h drivers/video_glx.c drivers/video_glx.h \2.62 - drivers/cd_linux.c drivers/cd_none.c drivers/audio_esd.c2.63 + x86dasm/dis-buf.c gtkui/gtkui.c gtkui/gtkui.h gtkui/main_win.c \2.64 + gtkui/gtkcb.c gtkui/mmio_win.c gtkui/debug_win.c \2.65 + gtkui/dump_win.c gtkui/ctrl_dlg.c gtkui/path_dlg.c \2.66 + gtkui/gdrom_menu.c drivers/video_gtk.c drivers/video_gtk.h \2.67 + drivers/video_glx.c drivers/video_glx.h drivers/cd_linux.c \2.68 + drivers/cd_none.c drivers/audio_esd.c2.69 @BUILD_SH4X86_TRUE@am__objects_1 = sh4x86.$(OBJEXT) sh4trans.$(OBJEXT) \2.70 @BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \2.71 @BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT)2.72 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am__objects_2 = ia64asm.$(OBJEXT)2.73 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am__objects_3 = ia32asm.$(OBJEXT)2.74 -@GUI_GTK_TRUE@am__objects_4 = gtkui.$(OBJEXT) main_win.$(OBJEXT) \2.75 +@GUI_GTK_TRUE@am__objects_2 = gtkui.$(OBJEXT) main_win.$(OBJEXT) \2.76 @GUI_GTK_TRUE@ gtkcb.$(OBJEXT) mmio_win.$(OBJEXT) \2.77 @GUI_GTK_TRUE@ debug_win.$(OBJEXT) dump_win.$(OBJEXT) \2.78 @GUI_GTK_TRUE@ ctrl_dlg.$(OBJEXT) path_dlg.$(OBJEXT) \2.79 @GUI_GTK_TRUE@ gdrom_menu.$(OBJEXT) video_gtk.$(OBJEXT) \2.80 @GUI_GTK_TRUE@ video_glx.$(OBJEXT)2.81 -@CDROM_LINUX_TRUE@am__objects_5 = cd_linux.$(OBJEXT)2.82 -@CDROM_LINUX_FALSE@am__objects_6 = cd_none.$(OBJEXT)2.83 -@AUDIO_ESOUND_TRUE@am__objects_7 = audio_esd.$(OBJEXT)2.84 +@CDROM_LINUX_TRUE@am__objects_3 = cd_linux.$(OBJEXT)2.85 +@CDROM_LINUX_FALSE@am__objects_4 = cd_none.$(OBJEXT)2.86 +@AUDIO_ESOUND_TRUE@am__objects_5 = audio_esd.$(OBJEXT)2.87 am_lxdream_OBJECTS = main.$(OBJEXT) config.$(OBJEXT) mem.$(OBJEXT) \2.88 watch.$(OBJEXT) asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \2.89 dcload.$(OBJEXT) ide.$(OBJEXT) gdimage.$(OBJEXT) \2.90 @@ -335,42 +325,20 @@2.91 audio_null.$(OBJEXT) video_null.$(OBJEXT) gl_common.$(OBJEXT) \2.92 gl_fbo.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \2.93 $(am__objects_1) $(am__objects_2) $(am__objects_3) \2.94 - $(am__objects_4) $(am__objects_5) $(am__objects_6) \2.95 - $(am__objects_7)2.96 + $(am__objects_4) $(am__objects_5)2.97 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.98 lxdream_DEPENDENCIES =2.99 lxdream_LDFLAGS =2.100 am__test_testsh4x86_SOURCES_DIST = test/testsh4x86.c x86dasm/x86dasm.c \2.101 x86dasm/x86dasm.h x86dasm/i386-dis.c x86dasm/dis-init.c \2.102 x86dasm/dis-buf.c sh4/sh4dasm.c sh4/sh4trans.c sh4/sh4x86.c \2.103 - sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/ia32asm.s \2.104 - sh4/ia64asm.s2.105 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@am_test_testsh4x86_OBJECTS = \2.106 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ testsh4x86.$(OBJEXT) \2.107 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ x86dasm.$(OBJEXT) \2.108 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ i386-dis.$(OBJEXT) \2.109 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ dis-init.$(OBJEXT) \2.110 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ dis-buf.$(OBJEXT) \2.111 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4dasm.$(OBJEXT) \2.112 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4trans.$(OBJEXT) \2.113 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ sh4x86.$(OBJEXT) \2.114 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ xltcache.$(OBJEXT) \2.115 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ mem.$(OBJEXT) \2.116 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ util.$(OBJEXT) \2.117 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_TRUE@ ia64asm.$(OBJEXT)2.118 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@am_test_testsh4x86_OBJECTS = \2.119 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ testsh4x86.$(OBJEXT) \2.120 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ x86dasm.$(OBJEXT) \2.121 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ i386-dis.$(OBJEXT) \2.122 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ dis-init.$(OBJEXT) \2.123 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ dis-buf.$(OBJEXT) \2.124 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4dasm.$(OBJEXT) \2.125 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4trans.$(OBJEXT) \2.126 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ sh4x86.$(OBJEXT) \2.127 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ xltcache.$(OBJEXT) \2.128 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ mem.$(OBJEXT) \2.129 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ util.$(OBJEXT) \2.130 -@BUILD_SH4X86_TRUE@@BUILD_X86_64_FALSE@ ia32asm.$(OBJEXT)2.131 + sh4/xltcache.c sh4/xltcache.h mem.c util.c sh4/mmu.c2.132 +@BUILD_SH4X86_TRUE@am_test_testsh4x86_OBJECTS = testsh4x86.$(OBJEXT) \2.133 +@BUILD_SH4X86_TRUE@ x86dasm.$(OBJEXT) i386-dis.$(OBJEXT) \2.134 +@BUILD_SH4X86_TRUE@ dis-init.$(OBJEXT) dis-buf.$(OBJEXT) \2.135 +@BUILD_SH4X86_TRUE@ sh4dasm.$(OBJEXT) sh4trans.$(OBJEXT) \2.136 +@BUILD_SH4X86_TRUE@ sh4x86.$(OBJEXT) xltcache.$(OBJEXT) \2.137 +@BUILD_SH4X86_TRUE@ mem.$(OBJEXT) util.$(OBJEXT) mmu.$(OBJEXT)2.138 test_testsh4x86_OBJECTS = $(am_test_testsh4x86_OBJECTS)2.139 @BUILD_SH4X86_TRUE@test_testsh4x86_DEPENDENCIES =2.140 @BUILD_SH4X86_FALSE@test_testsh4x86_DEPENDENCIES =2.141 @@ -430,7 +398,6 @@2.142 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.143 CCLD = $(CC)2.144 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@2.145 -CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)2.146 DIST_SOURCES = $(gendec_SOURCES) $(genglsl_SOURCES) \2.147 $(am__lxdream_SOURCES_DIST) $(am__test_testsh4x86_SOURCES_DIST) \2.148 $(test_testxlt_SOURCES)2.149 @@ -441,7 +408,7 @@2.150 $(MAKE) $(AM_MAKEFLAGS) all-am2.152 .SUFFIXES:2.153 -.SUFFIXES: .c .o .obj .s2.154 +.SUFFIXES: .c .o .obj2.155 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)2.156 cd $(top_srcdir) && \2.157 $(AUTOMAKE) --gnu src/Makefile2.158 @@ -2079,24 +2046,6 @@2.159 @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/testxlt.Po' tmpdepfile='$(DEPDIR)/testxlt.TPo' @AMDEPBACKSLASH@2.160 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.161 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testxlt.obj `if test -f 'test/testxlt.c'; then $(CYGPATH_W) 'test/testxlt.c'; else $(CYGPATH_W) '$(srcdir)/test/testxlt.c'; fi`2.162 -2.163 -.s.o:2.164 - $(CCASCOMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<2.165 -2.166 -.s.obj:2.167 - $(CCASCOMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`2.168 -2.169 -ia64asm.o: sh4/ia64asm.s2.170 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia64asm.o `test -f 'sh4/ia64asm.s' || echo '$(srcdir)/'`sh4/ia64asm.s2.171 -2.172 -ia64asm.obj: sh4/ia64asm.s2.173 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia64asm.obj `if test -f 'sh4/ia64asm.s'; then $(CYGPATH_W) 'sh4/ia64asm.s'; else $(CYGPATH_W) '$(srcdir)/sh4/ia64asm.s'; fi`2.174 -2.175 -ia32asm.o: sh4/ia32asm.s2.176 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia32asm.o `test -f 'sh4/ia32asm.s' || echo '$(srcdir)/'`sh4/ia32asm.s2.177 -2.178 -ia32asm.obj: sh4/ia32asm.s2.179 - $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) -c -o ia32asm.obj `if test -f 'sh4/ia32asm.s'; then $(CYGPATH_W) 'sh4/ia32asm.s'; else $(CYGPATH_W) '$(srcdir)/sh4/ia32asm.s'; fi`2.180 uninstall-info-am:2.182 ETAGS = etags
3.1 --- a/src/sh4/ia32abi.h Mon Jan 14 09:08:58 2008 +00003.2 +++ b/src/sh4/ia32abi.h Mon Jan 14 10:23:49 2008 +00003.3 @@ -244,6 +244,29 @@3.4 }3.5 }3.7 +void *xlat_get_native_pc()3.8 +{3.9 + void *result = NULL;3.10 + asm(3.11 + "mov %%ebp, %%eax\n\t"3.12 + "mov $0x8, %%ecx\n\t"3.13 + "mov %1, %%edx\n"3.14 +"frame_loop: test %%eax, %%eax\n\t"3.15 + "je frame_not_found\n\t"3.16 + "cmp (%%eax), %%edx\n\t"3.17 + "je frame_found\n\t"3.18 + "sub $0x1, %%ecx\n\t"3.19 + "je frame_not_found\n\t"3.20 + "movl (%%eax), %%eax\n\t"3.21 + "jmp frame_loop\n"3.22 +"frame_found: movl 0x4(%%eax), %0\n"3.23 +"frame_not_found:"3.24 + : "=r" (result)3.25 + : "r" (&sh4r)3.26 + : "eax", "ecx", "edx" );3.27 + return result;3.28 +}3.29 +3.30 #endif
4.1 --- a/src/sh4/ia32asm.s Mon Jan 14 09:08:58 2008 +00004.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +00004.3 @@ -1,34 +0,0 @@4.4 -#4.5 -# Scan back through the stack until we hit the currently executing4.6 -# translation block, and find the call return address to that block.4.7 -#4.8 -# Implementation: iterate back through each stack frame until we find4.9 -# a frame that has a saved %ebp == sh4r (setup by the xlat blocks).4.10 -# The return address is then the stack value immediately before the4.11 -# saved %ebp.4.12 -#4.13 -# At most 8 stack frames are checked, to prevent infinite looping on a4.14 -# corrupt stack.4.15 -4.16 -.global xlat_get_native_pc4.17 -xlat_get_native_pc:4.18 - mov %ebp, %eax4.19 - mov $0x8, %ecx4.20 - mov $sh4r, %edx4.21 -4.22 -frame_loop:4.23 - test %eax, %eax4.24 - je frame_not_found4.25 - cmp (%eax), %edx4.26 - je frame_found4.27 - sub $0x1, %ecx4.28 - je frame_not_found4.29 - movl (%eax), %eax4.30 - jmp frame_loop4.31 -4.32 -frame_found:4.33 - movl 0x4(%eax), %eax4.34 - ret4.35 -frame_not_found:4.36 - xor %eax, %eax4.37 - ret
5.1 --- a/src/sh4/ia32mac.h Mon Jan 14 09:08:58 2008 +00005.2 +++ b/src/sh4/ia32mac.h Mon Jan 14 10:23:49 2008 +00005.3 @@ -267,6 +267,30 @@5.4 }5.5 }5.7 +void *xlat_get_native_pc()5.8 +{5.9 + void *result = NULL;5.10 + asm(5.11 + "mov %%ebp, %%eax\n\t"5.12 + "mov $0x8, %%ecx\n\t"5.13 + "mov %1, %%edx\n"5.14 +"frame_loop: test %%eax, %%eax\n\t"5.15 + "je frame_not_found\n\t"5.16 + "cmp (%%eax), %%edx\n\t"5.17 + "je frame_found\n\t"5.18 + "sub $0x1, %%ecx\n\t"5.19 + "je frame_not_found\n\t"5.20 + "movl (%%eax), %%eax\n\t"5.21 + "jmp frame_loop\n"5.22 +"frame_found: movl 0x4(%%eax), %0\n"5.23 +"frame_not_found:"5.24 + : "=r" (result)5.25 + : "r" (&sh4r)5.26 + : "eax", "ecx", "edx" );5.27 + return result;5.28 +}5.29 +5.30 +5.31 #endif
6.1 --- a/src/sh4/ia64abi.h Mon Jan 14 09:08:58 2008 +00006.2 +++ b/src/sh4/ia64abi.h Mon Jan 14 10:23:49 2008 +00006.3 @@ -235,4 +235,28 @@6.4 }6.5 }6.7 +6.8 +void *xlat_get_native_pc()6.9 +{6.10 + void *result = NULL;6.11 + asm(6.12 + "mov %%rbp, %%rax\n\t"6.13 + "mov $0x8, %%ecx\n\t"6.14 + "mov %1, %%rdx\n"6.15 +"frame_loop: test %%rax, %%rax\n\t"6.16 + "je frame_not_found\n\t"6.17 + "cmpq (%%rax), %%rdx\n\t"6.18 + "je frame_found\n\t"6.19 + "sub $0x1, %%ecx\n\t"6.20 + "je frame_not_found\n\t"6.21 + "movq (%%rax), %%rax\n\t"6.22 + "jmp frame_loop\n"6.23 +"frame_found: movq 0x4(%%rax), %0\n"6.24 +"frame_not_found:"6.25 + : "=r" (result)6.26 + : "r" (&sh4r)6.27 + : "rax", "rcx", "rdx" );6.28 + return result;6.29 +}6.30 +6.31 #endif
7.1 --- a/src/sh4/mmu.c Mon Jan 14 09:08:58 2008 +00007.2 +++ b/src/sh4/mmu.c Mon Jan 14 10:23:49 2008 +00007.3 @@ -845,3 +845,50 @@7.4 return TRUE;7.5 }7.6 }7.7 +7.8 +gboolean sh4_flush_store_queue( sh4addr_t addr )7.9 +{7.10 + uint32_t mmucr = MMIO_READ(MMU,MMUCR);7.11 + int queue = (addr&0x20)>>2;7.12 + sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];7.13 + sh4addr_t target;7.14 + /* Store queue operation */7.15 + if( mmucr & MMUCR_AT ) {7.16 + int entryNo;7.17 + if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {7.18 + entryNo = mmu_utlb_lookup_vpn_asid( addr );7.19 + } else {7.20 + entryNo = mmu_utlb_lookup_vpn( addr );7.21 + }7.22 + switch(entryNo) {7.23 + case -1:7.24 + MMU_TLB_WRITE_MISS_ERROR(addr);7.25 + return FALSE;7.26 + case -2:7.27 + MMU_TLB_MULTI_HIT_ERROR(addr);7.28 + return FALSE;7.29 + default:7.30 + if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)7.31 + : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {7.32 + /* protection violation */7.33 + MMU_TLB_WRITE_PROT_ERROR(addr);7.34 + return FALSE;7.35 + }7.36 +7.37 + if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {7.38 + MMU_TLB_INITIAL_WRITE_ERROR(addr);7.39 + return FALSE;7.40 + }7.41 +7.42 + /* finally generate the target address */7.43 + target = ((mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |7.44 + (addr & (~mmu_utlb[entryNo].mask))) & 0xFFFFFFE0;7.45 + }7.46 + } else {7.47 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;7.48 + target = (addr&0x03FFFFE0) | hi;7.49 + }7.50 + mem_copy_to_sh4( target, src, 32 );7.51 + return TRUE;7.52 +}7.53 +
8.1 --- a/src/sh4/sh4.c Mon Jan 14 09:08:58 2008 +00008.2 +++ b/src/sh4/sh4.c Mon Jan 14 10:23:49 2008 +00008.3 @@ -154,6 +154,9 @@8.4 {8.5 sh4_breakpoints[sh4_breakpoint_count].address = pc;8.6 sh4_breakpoints[sh4_breakpoint_count].type = type;8.7 + if( sh4_use_translator ) {8.8 + xlat_invalidate_word( pc );8.9 + }8.10 sh4_breakpoint_count++;8.11 }8.13 @@ -168,6 +171,9 @@8.14 sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;8.15 sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;8.16 }8.17 + if( sh4_use_translator ) {8.18 + xlat_invalidate_word( pc );8.19 + }8.20 sh4_breakpoint_count--;8.21 return TRUE;8.22 }
9.1 --- a/src/sh4/sh4core.h Mon Jan 14 09:08:58 2008 +00009.2 +++ b/src/sh4/sh4core.h Mon Jan 14 10:23:49 2008 +00009.3 @@ -135,7 +135,7 @@9.4 void sh4_write_word( sh4addr_t addr, uint32_t val );9.5 void sh4_write_byte( sh4addr_t addr, uint32_t val );9.6 int32_t sh4_read_phys_word( sh4addr_t addr );9.7 -void sh4_flush_store_queue( sh4addr_t addr );9.8 +gboolean sh4_flush_store_queue( sh4addr_t addr );9.10 /* SH4 Exceptions */9.11 #define EXC_POWER_RESET 0x000 /* reset vector */
10.1 --- a/src/sh4/sh4mem.c Mon Jan 14 09:08:58 2008 +000010.2 +++ b/src/sh4/sh4mem.c Mon Jan 14 10:23:49 2008 +000010.3 @@ -423,19 +423,6 @@10.4 }10.5 }10.7 -void sh4_flush_store_queue( sh4addr_t addr )10.8 -{10.9 - /* Store queue operation */10.10 - if( IS_MMU_ENABLED() ) {10.11 -10.12 - }10.13 - int queue = (addr&0x20)>>2;10.14 - sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];10.15 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;10.16 - uint32_t target = (addr&0x03FFFFE0) | hi;10.17 - mem_copy_to_sh4( target, src, 32 );10.18 -}10.19 -10.20 sh4ptr_t sh4_get_region_by_vma( sh4addr_t vma )10.21 {10.22 uint64_t ppa = mmu_vma_to_phys_read(vma);
11.1 --- a/src/sh4/sh4trans.c Mon Jan 14 09:08:58 2008 +000011.2 +++ b/src/sh4/sh4trans.c Mon Jan 14 10:23:49 2008 +000011.3 @@ -42,7 +42,19 @@11.4 }11.5 }11.7 - int jmp = setjmp(xlat_jmp_buf);11.8 + switch( setjmp(xlat_jmp_buf) ) {11.9 + case XLAT_EXIT_BREAKPOINT:11.10 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );11.11 + /* fallthrough */11.12 + case XLAT_EXIT_HALT:11.13 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {11.14 + TMU_run_slice( sh4r.slice_cycle );11.15 + SCIF_run_slice( sh4r.slice_cycle );11.16 + dreamcast_stop();11.17 + return sh4r.slice_cycle;11.18 + }11.19 + break;11.20 + }11.22 void * (*code)() = NULL;11.23 while( sh4r.slice_cycle < nanosecs ) {11.24 @@ -94,7 +106,7 @@11.25 {11.26 sh4addr_t pc = start;11.27 sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000;11.28 - int done;11.29 + int done, i;11.30 xlat_cache_block_t block = xlat_start_block( start );11.31 xlat_output = (uint8_t *)block->code;11.32 xlat_recovery_posn = 0;11.33 @@ -102,6 +114,13 @@11.34 sh4_translate_begin_block(pc);11.36 do {11.37 + /* check for breakpoints at this pc */11.38 + for( i=0; i<sh4_breakpoint_count; i++ ) {11.39 + if( sh4_breakpoints[i].address == pc ) {11.40 + sh4_translate_emit_breakpoint(pc);11.41 + break;11.42 + }11.43 + }11.44 if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {11.45 uint8_t *oldstart = block->code;11.46 block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE );11.47 @@ -139,32 +158,6 @@11.48 }11.50 /**11.51 - * Translate a linear basic block to a temporary buffer, execute it, and return11.52 - * the result of the execution. The translation is discarded.11.53 - */11.54 -void *sh4_translate_and_run( sh4addr_t start )11.55 -{11.56 - unsigned char buf[65536];11.57 -11.58 - sh4addr_t pc = start;11.59 - int done;11.60 - xlat_output = buf;11.61 - uint8_t *eob = xlat_output + sizeof(buf);11.62 -11.63 - sh4_translate_begin_block(pc);11.64 -11.65 - while( (done = sh4_translate_instruction( pc )) == 0 ) {11.66 - assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );11.67 - pc += 2;11.68 - }11.69 - pc+=2;11.70 - sh4_translate_end_block(pc);11.71 -11.72 - void * (*code)() = (void *)buf;11.73 - return code();11.74 -}11.75 -11.76 -/**11.77 * "Execute" the supplied recovery record. Currently this only updates11.78 * sh4r.pc and sh4r.slice_cycle according to the currently executing11.79 * instruction. In future this may be more sophisticated (ie will11.80 @@ -179,10 +172,8 @@11.81 void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk )11.82 {11.83 void *pc = xlat_get_native_pc();11.84 - if( pc == NULL ) {11.85 - // This should never happen - indicative of a bug somewhere.11.86 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");11.87 - }11.88 +11.89 + assert( pc != NULL );11.90 void *code = xlat_get_code( sh4r.pc );11.91 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);11.92 if( recover != NULL ) {11.93 @@ -193,9 +184,24 @@11.94 thunk();11.95 }11.96 // finally longjmp back into sh4_xlat_run_slice11.97 - longjmp(xlat_jmp_buf, 1);11.98 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);11.99 }11.101 +void sh4_translate_exit( int exit_code )11.102 +{11.103 + void *pc = xlat_get_native_pc();11.104 + assert(pc != NULL);11.105 +11.106 + void *code = xlat_get_code( sh4r.pc );11.107 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);11.108 + if( recover != NULL ) {11.109 + // Can be null if there is no recovery necessary11.110 + sh4_translate_run_recovery(recover);11.111 + }11.112 + // finally longjmp back into sh4_xlat_run_slice11.113 + longjmp(xlat_jmp_buf, exit_code);11.114 +}11.115 +11.116 /**11.117 * Exit the current block at the end of the current instruction, flush the11.118 * translation cache (completely) and return control to sh4_xlat_run_slice.11.119 @@ -210,17 +216,15 @@11.120 void sh4_translate_flush_cache()11.121 {11.122 void *pc = xlat_get_native_pc();11.123 - if( pc == NULL ) {11.124 - // This should never happen - indicative of a bug somewhere.11.125 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");11.126 - }11.127 + assert( pc != NULL );11.128 +11.129 void *code = xlat_get_code( sh4r.pc );11.130 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);11.131 if( recover != NULL ) {11.132 // Can be null if there is no recovery necessary11.133 sh4_translate_run_recovery(recover);11.134 xlat_flush_cache();11.135 - longjmp(xlat_jmp_buf, 1);11.136 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);11.137 } else {11.138 xlat_flush_cache();11.139 return;11.140 @@ -232,6 +236,10 @@11.141 void *result = NULL;11.143 if( !IS_IN_ICACHE(vma) ) {11.144 + if( vma > 0xFFFFFF00 ) {11.145 + // lxdream hook11.146 + return NULL;11.147 + }11.148 if( !mmu_update_icache(sh4r.pc) ) {11.149 // fault - off to the fault handler11.150 if( !mmu_update_icache(sh4r.pc) ) {
12.1 --- a/src/sh4/sh4trans.h Mon Jan 14 09:08:58 2008 +000012.2 +++ b/src/sh4/sh4trans.h Mon Jan 14 10:23:49 2008 +000012.3 @@ -35,6 +35,22 @@12.4 #define MAX_RECOVERY_SIZE 204812.6 /**12.7 + * Translation flag - exit the current block but continue (eg exception handling)12.8 + */12.9 +#define XLAT_EXIT_CONTINUE 112.10 +12.11 +/**12.12 + * Translation flag - exit the current block and halt immediately (eg fatal error)12.13 + */12.14 +#define XLAT_EXIT_HALT 212.15 +12.16 +/**12.17 + * Translation flag - exit the current block and halt immediately for a system12.18 + * breakpoint.12.19 + */12.20 +#define XLAT_EXIT_BREAKPOINT 312.21 +12.22 +/**12.23 */12.24 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );12.26 @@ -79,3 +95,9 @@12.27 * @return This method never returns.12.28 */12.29 void sh4_translate_unwind_stack( gboolean is_completion, unwind_thunk_t thunk );12.30 +12.31 +/**12.32 + * From within the translator, immediately exit the current translation block with12.33 + * the specified exit code (one of the XLAT_EXIT_* values).12.34 + */12.35 +void sh4_translate_exit( int exit_code );
13.1 --- a/src/sh4/sh4x86.c Mon Jan 14 09:08:58 2008 +000013.2 +++ b/src/sh4/sh4x86.c Mon Jan 14 10:23:49 2008 +000013.3 @@ -125,7 +125,7 @@13.4 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;13.5 xlat_recovery_posn++;13.6 }13.7 -13.8 +13.9 /**13.10 * Emit an instruction to load an SH4 reg into a real register13.11 */13.12 @@ -355,11 +355,18 @@13.13 #endif13.14 #endif13.16 +void sh4_translate_emit_breakpoint( sh4vma_t pc )13.17 +{13.18 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );13.19 + call_func1( sh4_translate_exit, R_EAX );13.20 +}13.21 +13.23 /**13.24 * Translate a single instruction. Delayed branches are handled specially13.25 * by translating both branch and delayed instruction as a single unit (as13.26 *13.27 + * The instruction MUST be in the icache (assert check)13.28 *13.29 * @return true if the instruction marks the end of a basic block13.30 * (eg a branch or13.31 @@ -367,12 +374,21 @@13.32 uint32_t sh4_translate_instruction( sh4addr_t pc )13.33 {13.34 uint32_t ir;13.35 - /* Read instruction */13.36 - if( IS_IN_ICACHE(pc) ) {13.37 - ir = *(uint16_t *)GET_ICACHE_PTR(pc);13.38 - } else {13.39 + /* Read instruction from icache */13.40 + assert( IS_IN_ICACHE(pc) );13.41 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);13.42 +13.43 + /* PC is not in the current icache - this usually means we're running13.44 + * with MMU on, and we've gone past the end of the page. And since13.45 + * sh4_translate_block is pretty careful about this, it means we're13.46 + * almost certainly in a delay slot.13.47 + *13.48 + * Since we can't assume the page is present (and we can't fault it in13.49 + * at this point, inline a call to sh4_execute_instruction (with a few13.50 + * small repairs to cope with the different environment).13.51 + */13.52 ir = sh4_read_word(pc);13.53 - }13.54 +13.55 if( !sh4_x86.in_delay_slot ) {13.56 sh4_x86_add_recovery(pc);13.57 }13.58 @@ -488,8 +504,10 @@13.59 MOV_r32_r32( R_EAX, R_ECX );13.60 AND_imm32_r32( 0xFC000000, R_EAX );13.61 CMP_imm32_r32( 0xE0000000, R_EAX );13.62 - JNE_rel8(CALL_FUNC1_SIZE, end);13.63 + JNE_rel8(8+CALL_FUNC1_SIZE, end);13.64 call_func1( sh4_flush_store_queue, R_ECX );13.65 + TEST_r32_r32( R_EAX, R_EAX );13.66 + JE_exc(-1);13.67 JMP_TARGET(end);13.68 sh4_x86.tstate = TSTATE_NONE;13.69 }
14.1 --- a/src/sh4/sh4x86.in Mon Jan 14 09:08:58 2008 +000014.2 +++ b/src/sh4/sh4x86.in Mon Jan 14 10:23:49 2008 +000014.3 @@ -125,7 +125,7 @@14.4 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;14.5 xlat_recovery_posn++;14.6 }14.7 -14.8 +14.9 /**14.10 * Emit an instruction to load an SH4 reg into a real register14.11 */14.12 @@ -355,11 +355,18 @@14.13 #endif14.14 #endif14.16 +void sh4_translate_emit_breakpoint( sh4vma_t pc )14.17 +{14.18 + load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );14.19 + call_func1( sh4_translate_exit, R_EAX );14.20 +}14.21 +14.23 /**14.24 * Translate a single instruction. Delayed branches are handled specially14.25 * by translating both branch and delayed instruction as a single unit (as14.26 *14.27 + * The instruction MUST be in the icache (assert check)14.28 *14.29 * @return true if the instruction marks the end of a basic block14.30 * (eg a branch or14.31 @@ -367,12 +374,21 @@14.32 uint32_t sh4_translate_instruction( sh4addr_t pc )14.33 {14.34 uint32_t ir;14.35 - /* Read instruction */14.36 - if( IS_IN_ICACHE(pc) ) {14.37 - ir = *(uint16_t *)GET_ICACHE_PTR(pc);14.38 - } else {14.39 + /* Read instruction from icache */14.40 + assert( IS_IN_ICACHE(pc) );14.41 + ir = *(uint16_t *)GET_ICACHE_PTR(pc);14.42 +14.43 + /* PC is not in the current icache - this usually means we're running14.44 + * with MMU on, and we've gone past the end of the page. And since14.45 + * sh4_translate_block is pretty careful about this, it means we're14.46 + * almost certainly in a delay slot.14.47 + *14.48 + * Since we can't assume the page is present (and we can't fault it in14.49 + * at this point, inline a call to sh4_execute_instruction (with a few14.50 + * small repairs to cope with the different environment).14.51 + */14.52 ir = sh4_read_word(pc);14.53 - }14.54 +14.55 if( !sh4_x86.in_delay_slot ) {14.56 sh4_x86_add_recovery(pc);14.57 }14.58 @@ -2425,8 +2441,10 @@14.59 MOV_r32_r32( R_EAX, R_ECX );14.60 AND_imm32_r32( 0xFC000000, R_EAX );14.61 CMP_imm32_r32( 0xE0000000, R_EAX );14.62 - JNE_rel8(CALL_FUNC1_SIZE, end);14.63 + JNE_rel8(8+CALL_FUNC1_SIZE, end);14.64 call_func1( sh4_flush_store_queue, R_ECX );14.65 + TEST_r32_r32( R_EAX, R_EAX );14.66 + JE_exc(-1);14.67 JMP_TARGET(end);14.68 sh4_x86.tstate = TSTATE_NONE;14.69 :}
.