revision 359:c588dce7ebde
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 359:c588dce7ebde |
parent | 358:65043a8f5785 |
child | 360:dff4a3bbac0c |
author | nkeynes |
date | Thu Aug 23 12:33:27 2007 +0000 (16 years ago) |
Commit decoder generator
Translator work in progress
Fix mac.l, mac.w in emu core
Translator work in progress
Fix mac.l, mac.w in emu core
1.1 --- a/src/Makefile.am Thu Aug 23 12:31:31 2007 +00001.2 +++ b/src/Makefile.am Thu Aug 23 12:33:27 2007 +00001.3 @@ -6,7 +6,11 @@1.4 -Ish4 \1.5 @PACKAGE_CFLAGS@1.7 -bin_PROGRAMS = lxdream1.8 +bin_PROGRAMS = gendec lxdream1.9 +1.10 +BUILT_SOURCES = sh4/sh4core.c sh4/sh4dasm.c sh4/sh4x86.c1.11 +1.12 +gendec_SOURCES = tools/gendec.c tools/gendec.h tools/insparse.c tools/actparse.c1.14 lxdream_SOURCES = \1.15 main.c \1.16 @@ -18,7 +22,8 @@1.17 dreamcast.c dreamcast.h eventq.c eventq.h \1.18 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \1.19 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \1.20 - sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \1.21 + sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c sh4/xltcache.c sh4/xltcache.h \1.22 + sh4/sh4trans.c sh4/sh4trans.h sh4/sh4x86.c \1.23 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \1.24 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \1.25 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \1.26 @@ -40,4 +45,19 @@1.28 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd1.30 +gendec_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)1.31 +1.32 +TESTS = test/testxlt1.33 +1.34 +check_PROGRAMS = test/testxlt1.35 +1.36 +test_testxlt_SOURCES = test/testxlt.c sh4/xltcache.c sh4/xltcache.h1.37 +1.38 AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE1.39 +1.40 +sh4/sh4core.c: gendec sh4/sh4.def sh4/sh4core.in1.41 + ./gendec sh4/sh4.def sh4/sh4core.in -o sh4/sh4core.c1.42 +sh4/sh4dasm.c: gendec sh4/sh4.def sh4/sh4dasm.in1.43 + ./gendec sh4/sh4.def sh4/sh4dasm.in -o sh4/sh4dasm.c1.44 +sh4/sh4x86.c: gendec sh4/sh4.def sh4/sh4x86.in1.45 + ./gendec sh4/sh4.def sh4/sh4x86.in -o sh4/sh4x86.c
2.1 --- a/src/Makefile.in Thu Aug 23 12:31:31 2007 +00002.2 +++ b/src/Makefile.in Thu Aug 23 12:33:27 2007 +00002.3 @@ -140,7 +140,11 @@2.4 @PACKAGE_CFLAGS@2.7 -bin_PROGRAMS = lxdream2.8 +bin_PROGRAMS = gendec lxdream2.9 +2.10 +BUILT_SOURCES = sh4/sh4core.c sh4/sh4dasm.c sh4/sh4x86.c2.11 +2.12 +gendec_SOURCES = tools/gendec.c tools/gendec.h tools/insparse.c tools/actparse.c2.14 lxdream_SOURCES = \2.15 main.c \2.16 @@ -152,7 +156,8 @@2.17 dreamcast.c dreamcast.h eventq.c eventq.h \2.18 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \2.19 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \2.20 - sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c \2.21 + sh4/sh4mmio.c sh4/sh4mmio.h sh4/scif.c sh4/xltcache.c sh4/xltcache.h \2.22 + sh4/sh4trans.c sh4/sh4trans.h sh4/sh4x86.c \2.23 aica/armcore.c aica/armcore.h aica/armdasm.c aica/armmem.c \2.24 aica/aica.c aica/aica.h aica/audio.c aica/audio.h \2.25 pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \2.26 @@ -175,15 +180,29 @@2.28 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd2.30 +gendec_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)2.31 +2.32 +TESTS = test/testxlt2.33 +2.34 +check_PROGRAMS = test/testxlt2.35 +2.36 +test_testxlt_SOURCES = test/testxlt.c sh4/xltcache.c sh4/xltcache.h2.37 +2.38 AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE2.39 subdir = src2.40 ACLOCAL_M4 = $(top_srcdir)/aclocal.m42.41 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs2.42 CONFIG_HEADER = $(top_builddir)/config.h2.43 CONFIG_CLEAN_FILES =2.44 -bin_PROGRAMS = lxdream$(EXEEXT)2.45 +bin_PROGRAMS = gendec$(EXEEXT) lxdream$(EXEEXT)2.46 +check_PROGRAMS = test/testxlt$(EXEEXT)2.47 PROGRAMS = $(bin_PROGRAMS)2.49 +am_gendec_OBJECTS = gendec.$(OBJEXT) insparse.$(OBJEXT) \2.50 + actparse.$(OBJEXT)2.51 +gendec_OBJECTS = $(am_gendec_OBJECTS)2.52 +gendec_DEPENDENCIES =2.53 +gendec_LDFLAGS =2.54 am_lxdream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \2.55 asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \2.56 dcload.$(OBJEXT) ide.$(OBJEXT) gdimage.$(OBJEXT) \2.57 @@ -191,7 +210,8 @@2.58 dreamcast.$(OBJEXT) eventq.$(OBJEXT) intc.$(OBJEXT) \2.59 sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.60 sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \2.61 - scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.62 + scif.$(OBJEXT) xltcache.$(OBJEXT) sh4trans.$(OBJEXT) \2.63 + sh4x86.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.64 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.65 pvr2mem.$(OBJEXT) tacore.$(OBJEXT) render.$(OBJEXT) \2.66 rendcore.$(OBJEXT) rendbkg.$(OBJEXT) rendsort.$(OBJEXT) \2.67 @@ -206,48 +226,60 @@2.68 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.69 lxdream_DEPENDENCIES =2.70 lxdream_LDFLAGS =2.71 +am_test_testxlt_OBJECTS = testxlt.$(OBJEXT) xltcache.$(OBJEXT)2.72 +test_testxlt_OBJECTS = $(am_test_testxlt_OBJECTS)2.73 +test_testxlt_LDADD = $(LDADD)2.74 +test_testxlt_DEPENDENCIES =2.75 +test_testxlt_LDFLAGS =2.76 +am__dirstamp = $(am__leading_dot)dirstamp2.78 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)2.79 depcomp = $(SHELL) $(top_srcdir)/depcomp2.80 am__depfiles_maybe = depfiles2.81 -@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/aica.Po ./$(DEPDIR)/armcore.Po \2.82 -@AMDEP_TRUE@ ./$(DEPDIR)/armdasm.Po ./$(DEPDIR)/armmem.Po \2.83 -@AMDEP_TRUE@ ./$(DEPDIR)/asic.Po ./$(DEPDIR)/audio.Po \2.84 -@AMDEP_TRUE@ ./$(DEPDIR)/audio_esd.Po ./$(DEPDIR)/audio_null.Po \2.85 -@AMDEP_TRUE@ ./$(DEPDIR)/bios.Po ./$(DEPDIR)/bootstrap.Po \2.86 -@AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/cdi.Po \2.87 -@AMDEP_TRUE@ ./$(DEPDIR)/controller.Po ./$(DEPDIR)/dcload.Po \2.88 -@AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/display.Po \2.89 -@AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \2.90 -@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/eventq.Po \2.91 -@AMDEP_TRUE@ ./$(DEPDIR)/gdimage.Po ./$(DEPDIR)/gdrom.Po \2.92 +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/actparse.Po ./$(DEPDIR)/aica.Po \2.93 +@AMDEP_TRUE@ ./$(DEPDIR)/armcore.Po ./$(DEPDIR)/armdasm.Po \2.94 +@AMDEP_TRUE@ ./$(DEPDIR)/armmem.Po ./$(DEPDIR)/asic.Po \2.95 +@AMDEP_TRUE@ ./$(DEPDIR)/audio.Po ./$(DEPDIR)/audio_esd.Po \2.96 +@AMDEP_TRUE@ ./$(DEPDIR)/audio_null.Po ./$(DEPDIR)/bios.Po \2.97 +@AMDEP_TRUE@ ./$(DEPDIR)/bootstrap.Po ./$(DEPDIR)/callbacks.Po \2.98 +@AMDEP_TRUE@ ./$(DEPDIR)/cdi.Po ./$(DEPDIR)/controller.Po \2.99 +@AMDEP_TRUE@ ./$(DEPDIR)/dcload.Po ./$(DEPDIR)/debug_win.Po \2.100 +@AMDEP_TRUE@ ./$(DEPDIR)/display.Po ./$(DEPDIR)/dmac.Po \2.101 +@AMDEP_TRUE@ ./$(DEPDIR)/dreamcast.Po ./$(DEPDIR)/dump_win.Po \2.102 +@AMDEP_TRUE@ ./$(DEPDIR)/eventq.Po ./$(DEPDIR)/gdimage.Po \2.103 +@AMDEP_TRUE@ ./$(DEPDIR)/gdrom.Po ./$(DEPDIR)/gendec.Po \2.104 @AMDEP_TRUE@ ./$(DEPDIR)/gl_common.Po ./$(DEPDIR)/gl_fbo.Po \2.105 @AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \2.106 -@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \2.107 -@AMDEP_TRUE@ ./$(DEPDIR)/linux.Po ./$(DEPDIR)/loader.Po \2.108 -@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \2.109 -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \2.110 -@AMDEP_TRUE@ ./$(DEPDIR)/nrg.Po ./$(DEPDIR)/pvr2.Po \2.111 -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \2.112 -@AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \2.113 -@AMDEP_TRUE@ ./$(DEPDIR)/rendsave.Po ./$(DEPDIR)/rendsort.Po \2.114 -@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.115 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.116 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.117 -@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \2.118 +@AMDEP_TRUE@ ./$(DEPDIR)/insparse.Po ./$(DEPDIR)/intc.Po \2.119 +@AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/linux.Po \2.120 +@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \2.121 +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \2.122 +@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \2.123 +@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/pvr2mem.Po \2.124 +@AMDEP_TRUE@ ./$(DEPDIR)/rendbkg.Po ./$(DEPDIR)/rendcore.Po \2.125 +@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsave.Po \2.126 +@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scif.Po \2.127 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \2.128 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \2.129 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4trans.Po ./$(DEPDIR)/sh4x86.Po \2.130 +@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \2.131 +@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/testxlt.Po \2.132 @AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.133 @AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \2.134 @AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.135 -@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/yuv.Po2.136 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/xltcache.Po \2.137 +@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po2.138 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.139 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.140 CCLD = $(CC)2.141 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@2.142 -DIST_SOURCES = $(lxdream_SOURCES)2.143 +DIST_SOURCES = $(gendec_SOURCES) $(lxdream_SOURCES) \2.144 + $(test_testxlt_SOURCES)2.145 DIST_COMMON = $(srcdir)/Makefile.in Makefile.am2.146 -SOURCES = $(lxdream_SOURCES)2.147 +SOURCES = $(gendec_SOURCES) $(lxdream_SOURCES) $(test_testxlt_SOURCES)2.149 -all: all-am2.150 +all: $(BUILT_SOURCES)2.151 + $(MAKE) $(AM_MAKEFLAGS) all-am2.153 .SUFFIXES:2.154 .SUFFIXES: .c .o .obj2.155 @@ -280,9 +312,21 @@2.157 clean-binPROGRAMS:2.158 -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)2.159 +2.160 +clean-checkPROGRAMS:2.161 + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)2.162 +gendec$(EXEEXT): $(gendec_OBJECTS) $(gendec_DEPENDENCIES)2.163 + @rm -f gendec$(EXEEXT)2.164 + $(LINK) $(gendec_LDFLAGS) $(gendec_OBJECTS) $(gendec_LDADD) $(LIBS)2.165 lxdream$(EXEEXT): $(lxdream_OBJECTS) $(lxdream_DEPENDENCIES)2.166 @rm -f lxdream$(EXEEXT)2.167 $(LINK) $(lxdream_LDFLAGS) $(lxdream_OBJECTS) $(lxdream_LDADD) $(LIBS)2.168 +test/$(am__dirstamp):2.169 + @$(mkinstalldirs) test2.170 + @: > test/$(am__dirstamp)2.171 +test/testxlt$(EXEEXT): $(test_testxlt_OBJECTS) $(test_testxlt_DEPENDENCIES) test/$(am__dirstamp)2.172 + @rm -f test/testxlt$(EXEEXT)2.173 + $(LINK) $(test_testxlt_LDFLAGS) $(test_testxlt_OBJECTS) $(test_testxlt_LDADD) $(LIBS)2.175 mostlyclean-compile:2.176 -rm -f *.$(OBJEXT) core *.core2.177 @@ -290,6 +334,7 @@2.178 distclean-compile:2.179 -rm -f *.tab.c2.181 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/actparse.Po@am__quote@2.182 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aica.Po@am__quote@2.183 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/armcore.Po@am__quote@2.184 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/armdasm.Po@am__quote@2.185 @@ -312,10 +357,12 @@2.186 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventq.Po@am__quote@2.187 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdimage.Po@am__quote@2.188 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdrom.Po@am__quote@2.189 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gendec.Po@am__quote@2.190 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_common.Po@am__quote@2.191 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_fbo.Po@am__quote@2.192 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@2.193 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@2.194 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insparse.Po@am__quote@2.195 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@2.196 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Po@am__quote@2.197 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux.Po@am__quote@2.198 @@ -337,9 +384,12 @@2.199 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4dasm.Po@am__quote@2.200 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mem.Po@am__quote@2.201 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4mmio.Po@am__quote@2.202 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4trans.Po@am__quote@2.203 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh4x86.Po@am__quote@2.204 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Po@am__quote@2.205 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/syscall.Po@am__quote@2.206 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tacore.Po@am__quote@2.207 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testxlt.Po@am__quote@2.208 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/texcache.Po@am__quote@2.209 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timer.Po@am__quote@2.210 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@2.211 @@ -347,6 +397,7 @@2.212 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_null.Po@am__quote@2.213 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/video_x11.Po@am__quote@2.214 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@2.215 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xltcache.Po@am__quote@2.216 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yuv.Po@am__quote@2.218 .c.o:2.219 @@ -371,6 +422,72 @@2.220 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.221 @am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`2.223 +gendec.o: tools/gendec.c2.224 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gendec.o -MD -MP -MF "$(DEPDIR)/gendec.Tpo" \2.225 +@am__fastdepCC_TRUE@ -c -o gendec.o `test -f 'tools/gendec.c' || echo '$(srcdir)/'`tools/gendec.c; \2.226 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gendec.Tpo" "$(DEPDIR)/gendec.Po"; \2.227 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gendec.Tpo"; exit 1; \2.228 +@am__fastdepCC_TRUE@ fi2.229 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/gendec.c' object='gendec.o' libtool=no @AMDEPBACKSLASH@2.230 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gendec.Po' tmpdepfile='$(DEPDIR)/gendec.TPo' @AMDEPBACKSLASH@2.231 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.232 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gendec.o `test -f 'tools/gendec.c' || echo '$(srcdir)/'`tools/gendec.c2.233 +2.234 +gendec.obj: tools/gendec.c2.235 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gendec.obj -MD -MP -MF "$(DEPDIR)/gendec.Tpo" \2.236 +@am__fastdepCC_TRUE@ -c -o gendec.obj `if test -f 'tools/gendec.c'; then $(CYGPATH_W) 'tools/gendec.c'; else $(CYGPATH_W) '$(srcdir)/tools/gendec.c'; fi`; \2.237 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gendec.Tpo" "$(DEPDIR)/gendec.Po"; \2.238 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gendec.Tpo"; exit 1; \2.239 +@am__fastdepCC_TRUE@ fi2.240 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/gendec.c' object='gendec.obj' libtool=no @AMDEPBACKSLASH@2.241 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gendec.Po' tmpdepfile='$(DEPDIR)/gendec.TPo' @AMDEPBACKSLASH@2.242 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.243 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gendec.obj `if test -f 'tools/gendec.c'; then $(CYGPATH_W) 'tools/gendec.c'; else $(CYGPATH_W) '$(srcdir)/tools/gendec.c'; fi`2.244 +2.245 +insparse.o: tools/insparse.c2.246 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT insparse.o -MD -MP -MF "$(DEPDIR)/insparse.Tpo" \2.247 +@am__fastdepCC_TRUE@ -c -o insparse.o `test -f 'tools/insparse.c' || echo '$(srcdir)/'`tools/insparse.c; \2.248 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/insparse.Tpo" "$(DEPDIR)/insparse.Po"; \2.249 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/insparse.Tpo"; exit 1; \2.250 +@am__fastdepCC_TRUE@ fi2.251 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/insparse.c' object='insparse.o' libtool=no @AMDEPBACKSLASH@2.252 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/insparse.Po' tmpdepfile='$(DEPDIR)/insparse.TPo' @AMDEPBACKSLASH@2.253 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.254 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o insparse.o `test -f 'tools/insparse.c' || echo '$(srcdir)/'`tools/insparse.c2.255 +2.256 +insparse.obj: tools/insparse.c2.257 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT insparse.obj -MD -MP -MF "$(DEPDIR)/insparse.Tpo" \2.258 +@am__fastdepCC_TRUE@ -c -o insparse.obj `if test -f 'tools/insparse.c'; then $(CYGPATH_W) 'tools/insparse.c'; else $(CYGPATH_W) '$(srcdir)/tools/insparse.c'; fi`; \2.259 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/insparse.Tpo" "$(DEPDIR)/insparse.Po"; \2.260 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/insparse.Tpo"; exit 1; \2.261 +@am__fastdepCC_TRUE@ fi2.262 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/insparse.c' object='insparse.obj' libtool=no @AMDEPBACKSLASH@2.263 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/insparse.Po' tmpdepfile='$(DEPDIR)/insparse.TPo' @AMDEPBACKSLASH@2.264 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.265 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o insparse.obj `if test -f 'tools/insparse.c'; then $(CYGPATH_W) 'tools/insparse.c'; else $(CYGPATH_W) '$(srcdir)/tools/insparse.c'; fi`2.266 +2.267 +actparse.o: tools/actparse.c2.268 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT actparse.o -MD -MP -MF "$(DEPDIR)/actparse.Tpo" \2.269 +@am__fastdepCC_TRUE@ -c -o actparse.o `test -f 'tools/actparse.c' || echo '$(srcdir)/'`tools/actparse.c; \2.270 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/actparse.Tpo" "$(DEPDIR)/actparse.Po"; \2.271 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/actparse.Tpo"; exit 1; \2.272 +@am__fastdepCC_TRUE@ fi2.273 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/actparse.c' object='actparse.o' libtool=no @AMDEPBACKSLASH@2.274 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/actparse.Po' tmpdepfile='$(DEPDIR)/actparse.TPo' @AMDEPBACKSLASH@2.275 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.276 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o actparse.o `test -f 'tools/actparse.c' || echo '$(srcdir)/'`tools/actparse.c2.277 +2.278 +actparse.obj: tools/actparse.c2.279 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT actparse.obj -MD -MP -MF "$(DEPDIR)/actparse.Tpo" \2.280 +@am__fastdepCC_TRUE@ -c -o actparse.obj `if test -f 'tools/actparse.c'; then $(CYGPATH_W) 'tools/actparse.c'; else $(CYGPATH_W) '$(srcdir)/tools/actparse.c'; fi`; \2.281 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/actparse.Tpo" "$(DEPDIR)/actparse.Po"; \2.282 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/actparse.Tpo"; exit 1; \2.283 +@am__fastdepCC_TRUE@ fi2.284 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tools/actparse.c' object='actparse.obj' libtool=no @AMDEPBACKSLASH@2.285 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/actparse.Po' tmpdepfile='$(DEPDIR)/actparse.TPo' @AMDEPBACKSLASH@2.286 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.287 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o actparse.obj `if test -f 'tools/actparse.c'; then $(CYGPATH_W) 'tools/actparse.c'; else $(CYGPATH_W) '$(srcdir)/tools/actparse.c'; fi`2.288 +2.289 ide.o: gdrom/ide.c2.290 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ide.o -MD -MP -MF "$(DEPDIR)/ide.Tpo" \2.291 @am__fastdepCC_TRUE@ -c -o ide.o `test -f 'gdrom/ide.c' || echo '$(srcdir)/'`gdrom/ide.c; \2.292 @@ -679,6 +796,72 @@2.293 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.294 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o scif.obj `if test -f 'sh4/scif.c'; then $(CYGPATH_W) 'sh4/scif.c'; else $(CYGPATH_W) '$(srcdir)/sh4/scif.c'; fi`2.296 +xltcache.o: sh4/xltcache.c2.297 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xltcache.o -MD -MP -MF "$(DEPDIR)/xltcache.Tpo" \2.298 +@am__fastdepCC_TRUE@ -c -o xltcache.o `test -f 'sh4/xltcache.c' || echo '$(srcdir)/'`sh4/xltcache.c; \2.299 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xltcache.Tpo" "$(DEPDIR)/xltcache.Po"; \2.300 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/xltcache.Tpo"; exit 1; \2.301 +@am__fastdepCC_TRUE@ fi2.302 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/xltcache.c' object='xltcache.o' libtool=no @AMDEPBACKSLASH@2.303 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/xltcache.Po' tmpdepfile='$(DEPDIR)/xltcache.TPo' @AMDEPBACKSLASH@2.304 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.305 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xltcache.o `test -f 'sh4/xltcache.c' || echo '$(srcdir)/'`sh4/xltcache.c2.306 +2.307 +xltcache.obj: sh4/xltcache.c2.308 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xltcache.obj -MD -MP -MF "$(DEPDIR)/xltcache.Tpo" \2.309 +@am__fastdepCC_TRUE@ -c -o xltcache.obj `if test -f 'sh4/xltcache.c'; then $(CYGPATH_W) 'sh4/xltcache.c'; else $(CYGPATH_W) '$(srcdir)/sh4/xltcache.c'; fi`; \2.310 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/xltcache.Tpo" "$(DEPDIR)/xltcache.Po"; \2.311 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/xltcache.Tpo"; exit 1; \2.312 +@am__fastdepCC_TRUE@ fi2.313 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/xltcache.c' object='xltcache.obj' libtool=no @AMDEPBACKSLASH@2.314 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/xltcache.Po' tmpdepfile='$(DEPDIR)/xltcache.TPo' @AMDEPBACKSLASH@2.315 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.316 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xltcache.obj `if test -f 'sh4/xltcache.c'; then $(CYGPATH_W) 'sh4/xltcache.c'; else $(CYGPATH_W) '$(srcdir)/sh4/xltcache.c'; fi`2.317 +2.318 +sh4trans.o: sh4/sh4trans.c2.319 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4trans.o -MD -MP -MF "$(DEPDIR)/sh4trans.Tpo" \2.320 +@am__fastdepCC_TRUE@ -c -o sh4trans.o `test -f 'sh4/sh4trans.c' || echo '$(srcdir)/'`sh4/sh4trans.c; \2.321 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4trans.Tpo" "$(DEPDIR)/sh4trans.Po"; \2.322 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4trans.Tpo"; exit 1; \2.323 +@am__fastdepCC_TRUE@ fi2.324 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4trans.c' object='sh4trans.o' libtool=no @AMDEPBACKSLASH@2.325 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4trans.Po' tmpdepfile='$(DEPDIR)/sh4trans.TPo' @AMDEPBACKSLASH@2.326 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.327 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4trans.o `test -f 'sh4/sh4trans.c' || echo '$(srcdir)/'`sh4/sh4trans.c2.328 +2.329 +sh4trans.obj: sh4/sh4trans.c2.330 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4trans.obj -MD -MP -MF "$(DEPDIR)/sh4trans.Tpo" \2.331 +@am__fastdepCC_TRUE@ -c -o sh4trans.obj `if test -f 'sh4/sh4trans.c'; then $(CYGPATH_W) 'sh4/sh4trans.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4trans.c'; fi`; \2.332 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4trans.Tpo" "$(DEPDIR)/sh4trans.Po"; \2.333 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4trans.Tpo"; exit 1; \2.334 +@am__fastdepCC_TRUE@ fi2.335 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4trans.c' object='sh4trans.obj' libtool=no @AMDEPBACKSLASH@2.336 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4trans.Po' tmpdepfile='$(DEPDIR)/sh4trans.TPo' @AMDEPBACKSLASH@2.337 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.338 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4trans.obj `if test -f 'sh4/sh4trans.c'; then $(CYGPATH_W) 'sh4/sh4trans.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4trans.c'; fi`2.339 +2.340 +sh4x86.o: sh4/sh4x86.c2.341 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4x86.o -MD -MP -MF "$(DEPDIR)/sh4x86.Tpo" \2.342 +@am__fastdepCC_TRUE@ -c -o sh4x86.o `test -f 'sh4/sh4x86.c' || echo '$(srcdir)/'`sh4/sh4x86.c; \2.343 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4x86.Tpo" "$(DEPDIR)/sh4x86.Po"; \2.344 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4x86.Tpo"; exit 1; \2.345 +@am__fastdepCC_TRUE@ fi2.346 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4x86.c' object='sh4x86.o' libtool=no @AMDEPBACKSLASH@2.347 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4x86.Po' tmpdepfile='$(DEPDIR)/sh4x86.TPo' @AMDEPBACKSLASH@2.348 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.349 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4x86.o `test -f 'sh4/sh4x86.c' || echo '$(srcdir)/'`sh4/sh4x86.c2.350 +2.351 +sh4x86.obj: sh4/sh4x86.c2.352 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sh4x86.obj -MD -MP -MF "$(DEPDIR)/sh4x86.Tpo" \2.353 +@am__fastdepCC_TRUE@ -c -o sh4x86.obj `if test -f 'sh4/sh4x86.c'; then $(CYGPATH_W) 'sh4/sh4x86.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4x86.c'; fi`; \2.354 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/sh4x86.Tpo" "$(DEPDIR)/sh4x86.Po"; \2.355 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/sh4x86.Tpo"; exit 1; \2.356 +@am__fastdepCC_TRUE@ fi2.357 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sh4/sh4x86.c' object='sh4x86.obj' libtool=no @AMDEPBACKSLASH@2.358 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/sh4x86.Po' tmpdepfile='$(DEPDIR)/sh4x86.TPo' @AMDEPBACKSLASH@2.359 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.360 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sh4x86.obj `if test -f 'sh4/sh4x86.c'; then $(CYGPATH_W) 'sh4/sh4x86.c'; else $(CYGPATH_W) '$(srcdir)/sh4/sh4x86.c'; fi`2.361 +2.362 armcore.o: aica/armcore.c2.363 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT armcore.o -MD -MP -MF "$(DEPDIR)/armcore.Tpo" \2.364 @am__fastdepCC_TRUE@ -c -o armcore.o `test -f 'aica/armcore.c' || echo '$(srcdir)/'`aica/armcore.c; \2.365 @@ -1360,6 +1543,28 @@2.366 @AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gl_fbo.Po' tmpdepfile='$(DEPDIR)/gl_fbo.TPo' @AMDEPBACKSLASH@2.367 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.368 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gl_fbo.obj `if test -f 'drivers/gl_fbo.c'; then $(CYGPATH_W) 'drivers/gl_fbo.c'; else $(CYGPATH_W) '$(srcdir)/drivers/gl_fbo.c'; fi`2.369 +2.370 +testxlt.o: test/testxlt.c2.371 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testxlt.o -MD -MP -MF "$(DEPDIR)/testxlt.Tpo" \2.372 +@am__fastdepCC_TRUE@ -c -o testxlt.o `test -f 'test/testxlt.c' || echo '$(srcdir)/'`test/testxlt.c; \2.373 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/testxlt.Tpo" "$(DEPDIR)/testxlt.Po"; \2.374 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/testxlt.Tpo"; exit 1; \2.375 +@am__fastdepCC_TRUE@ fi2.376 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test/testxlt.c' object='testxlt.o' libtool=no @AMDEPBACKSLASH@2.377 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/testxlt.Po' tmpdepfile='$(DEPDIR)/testxlt.TPo' @AMDEPBACKSLASH@2.378 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.379 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o testxlt.o `test -f 'test/testxlt.c' || echo '$(srcdir)/'`test/testxlt.c2.380 +2.381 +testxlt.obj: test/testxlt.c2.382 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT testxlt.obj -MD -MP -MF "$(DEPDIR)/testxlt.Tpo" \2.383 +@am__fastdepCC_TRUE@ -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.384 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/testxlt.Tpo" "$(DEPDIR)/testxlt.Po"; \2.385 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/testxlt.Tpo"; exit 1; \2.386 +@am__fastdepCC_TRUE@ fi2.387 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test/testxlt.c' object='testxlt.obj' libtool=no @AMDEPBACKSLASH@2.388 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/testxlt.Po' tmpdepfile='$(DEPDIR)/testxlt.TPo' @AMDEPBACKSLASH@2.389 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.390 +@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.391 uninstall-info-am:2.393 ETAGS = etags2.394 @@ -1415,6 +1620,79 @@2.396 distclean-tags:2.397 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags2.398 +2.399 +check-TESTS: $(TESTS)2.400 + @failed=0; all=0; xfail=0; xpass=0; skip=0; \2.401 + srcdir=$(srcdir); export srcdir; \2.402 + list='$(TESTS)'; \2.403 + if test -n "$$list"; then \2.404 + for tst in $$list; do \2.405 + if test -f ./$$tst; then dir=./; \2.406 + elif test -f $$tst; then dir=; \2.407 + else dir="$(srcdir)/"; fi; \2.408 + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \2.409 + all=`expr $$all + 1`; \2.410 + case " $(XFAIL_TESTS) " in \2.411 + *" $$tst "*) \2.412 + xpass=`expr $$xpass + 1`; \2.413 + failed=`expr $$failed + 1`; \2.414 + echo "XPASS: $$tst"; \2.415 + ;; \2.416 + *) \2.417 + echo "PASS: $$tst"; \2.418 + ;; \2.419 + esac; \2.420 + elif test $$? -ne 77; then \2.421 + all=`expr $$all + 1`; \2.422 + case " $(XFAIL_TESTS) " in \2.423 + *" $$tst "*) \2.424 + xfail=`expr $$xfail + 1`; \2.425 + echo "XFAIL: $$tst"; \2.426 + ;; \2.427 + *) \2.428 + failed=`expr $$failed + 1`; \2.429 + echo "FAIL: $$tst"; \2.430 + ;; \2.431 + esac; \2.432 + else \2.433 + skip=`expr $$skip + 1`; \2.434 + echo "SKIP: $$tst"; \2.435 + fi; \2.436 + done; \2.437 + if test "$$failed" -eq 0; then \2.438 + if test "$$xfail" -eq 0; then \2.439 + banner="All $$all tests passed"; \2.440 + else \2.441 + banner="All $$all tests behaved as expected ($$xfail expected failures)"; \2.442 + fi; \2.443 + else \2.444 + if test "$$xpass" -eq 0; then \2.445 + banner="$$failed of $$all tests failed"; \2.446 + else \2.447 + banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \2.448 + fi; \2.449 + fi; \2.450 + dashes="$$banner"; \2.451 + skipped=""; \2.452 + if test "$$skip" -ne 0; then \2.453 + skipped="($$skip tests were not run)"; \2.454 + test `echo "$$skipped" | wc -c` -gt `echo "$$banner" | wc -c` && \2.455 + dashes="$$skipped"; \2.456 + fi; \2.457 + report=""; \2.458 + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \2.459 + report="Please report to $(PACKAGE_BUGREPORT)"; \2.460 + test `echo "$$report" | wc -c` -gt `echo "$$banner" | wc -c` && \2.461 + dashes="$$report"; \2.462 + fi; \2.463 + dashes=`echo "$$dashes" | sed s/./=/g`; \2.464 + echo "$$dashes"; \2.465 + echo "$$banner"; \2.466 + test -n "$$skipped" && echo "$$skipped"; \2.467 + test -n "$$report" && echo "$$report"; \2.468 + echo "$$dashes"; \2.469 + test "$$failed" -eq 0; \2.470 + else :; fi2.471 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)2.473 top_distdir = ..2.474 @@ -1448,12 +1726,16 @@2.475 fi; \2.476 done2.477 check-am: all-am2.478 -check: check-am2.479 + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)2.480 + $(MAKE) $(AM_MAKEFLAGS) check-TESTS2.481 +check: $(BUILT_SOURCES)2.482 + $(MAKE) $(AM_MAKEFLAGS) check-am2.483 all-am: Makefile $(PROGRAMS)2.485 installdirs:2.486 $(mkinstalldirs) $(DESTDIR)$(bindir)2.487 -install: install-am2.488 +install: $(BUILT_SOURCES)2.489 + $(MAKE) $(AM_MAKEFLAGS) install-am2.490 install-exec: install-exec-am2.491 install-data: install-data-am2.492 uninstall: uninstall-am2.493 @@ -1473,13 +1755,16 @@2.495 distclean-generic:2.496 -rm -f $(CONFIG_CLEAN_FILES)2.497 + -rm -f test/$(am__dirstamp)2.499 maintainer-clean-generic:2.500 @echo "This command is intended for maintainers to use"2.501 @echo "it deletes files that may require special tools to rebuild."2.502 + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)2.503 clean: clean-am2.505 -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am2.506 +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \2.507 + mostlyclean-am2.509 distclean: distclean-am2.510 -rm -rf ./$(DEPDIR)2.511 @@ -1524,17 +1809,25 @@2.513 uninstall-am: uninstall-binPROGRAMS uninstall-info-am2.515 -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \2.516 - clean-generic ctags distclean distclean-compile \2.517 - distclean-generic distclean-tags distdir dvi dvi-am info \2.518 - info-am install install-am install-binPROGRAMS install-data \2.519 - install-data-am install-exec install-exec-am install-info \2.520 - install-info-am install-man install-strip installcheck \2.521 - installcheck-am installdirs maintainer-clean \2.522 - maintainer-clean-generic mostlyclean mostlyclean-compile \2.523 - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \2.524 - uninstall-am uninstall-binPROGRAMS uninstall-info-am2.525 +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \2.526 + clean-binPROGRAMS clean-checkPROGRAMS clean-generic ctags \2.527 + distclean distclean-compile distclean-generic distclean-tags \2.528 + distdir dvi dvi-am info info-am install install-am \2.529 + install-binPROGRAMS install-data install-data-am install-exec \2.530 + install-exec-am install-info install-info-am install-man \2.531 + install-strip installcheck installcheck-am installdirs \2.532 + maintainer-clean maintainer-clean-generic mostlyclean \2.533 + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \2.534 + tags uninstall uninstall-am uninstall-binPROGRAMS \2.535 + uninstall-info-am2.537 +2.538 +sh4/sh4core.c: gendec sh4/sh4.def sh4/sh4core.in2.539 + ./gendec sh4/sh4.def sh4/sh4core.in -o sh4/sh4core.c2.540 +sh4/sh4dasm.c: gendec sh4/sh4.def sh4/sh4dasm.in2.541 + ./gendec sh4/sh4.def sh4/sh4dasm.in -o sh4/sh4dasm.c2.542 +sh4/sh4x86.c: gendec sh4/sh4.def sh4/sh4x86.in2.543 + ./gendec sh4/sh4.def sh4/sh4x86.in -o sh4/sh4x86.c2.544 # Tell versions [3.59,3.63) of GNU make to not export all variables.2.545 # Otherwise a system limit (for SysV at least) may be exceeded.2.546 .NOEXPORT:
3.1 --- a/src/dreamcast.h Thu Aug 23 12:31:31 2007 +00003.2 +++ b/src/dreamcast.h Thu Aug 23 12:33:27 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: dreamcast.h,v 1.12 2007-01-16 10:34:46 nkeynes Exp $3.6 + * $Id: dreamcast.h,v 1.13 2007-08-23 12:33:27 nkeynes Exp $3.7 *3.8 * Public interface for dreamcast.c -3.9 * Central switchboard for the system. This pulls all the individual modules3.10 @@ -30,6 +30,15 @@3.11 #endif3.13 #define DEFAULT_TIMESLICE_LENGTH 1000000 /* nanoseconds */3.14 +3.15 +#ifndef MB3.16 +#define MB *1024*10243.17 +#endif3.18 +3.19 +#define XLAT_NEW_CACHE_SIZE 8 MB3.20 +#define XLAT_TEMP_CACHE_SIZE 2 MB3.21 +#define XLAT_OLD_CACHE_SIZE 8 MB3.22 +3.23 #define CONFIG_TYPE_NONE 03.24 #define CONFIG_TYPE_FILE 13.25 #define CONFIG_TYPE_PATH 2
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00004.2 +++ b/src/sh4/sh4.def Thu Aug 23 12:33:27 2007 +00004.3 @@ -0,0 +1,236 @@4.4 +##4.5 +## Instruction file for the SH4 - from the SH4 manual.4.6 +## line ::= bitpattern WHITESPACE result NEWLINE4.7 +## bitpattern ::= { '0' | '1' | '(' operand ')' }4.8 +## operand ::= IDENTIFIER ':' NUMBER signspec4.9 +## signspec ::= 'u' | 's' |4.10 +## result ::= { IDENTIFIER | NON-IDENT-CHAR }4.11 +4.12 +registers {4.13 + uint32 Rm, Rn = r0..r154.14 + uint32 Rm_BANK, Rn_BANK = r8_bank..r15_bank4.15 + float Frm, Frn = fr0..fr154.16 + float XFm, XFn = xf0..xf154.17 + double Drm, Drn = dr0..dr8 overlaps fr0..fr15 swapped4.18 + double XDm, XDn = xd0..xd8 overlaps xf0..xf15 swapped4.19 + float[4] FVm, FVn = fv0..fv3 overlaps fr0..fr154.20 + float[16] XMTRX = xmtrx overlaps xf0..xf154.21 +4.22 +## Special registers4.23 + uint32 GBR, SR, VBR, SSR, SGR SPC, DBR4.24 + uint32 FPSCR, FPUL, MACH, MACL, PR, PC4.25 +4.26 +}4.27 +4.28 +0011(Rn:4)(Rm:4)1100 ADD Rm, Rn4.29 +0111(Rn:4)(imm:8s) ADD #imm, Rn4.30 +0011(Rn:4)(Rm:4)1110 ADDC Rm, Rn4.31 +0011(Rn:4)(Rm:4)1111 ADDV Rm, Rn4.32 +0010(Rn:4)(Rm:4)1001 AND Rm, Rn4.33 +11001001(imm:8u) AND #imm, R04.34 +11001101(imm:8u) AND.B #imm, @(R0, GBR)4.35 +10001011(disp:8s<<1) BF disp4.36 +10001111(disp:8s<<1) BF/S disp4.37 +1010(disp:12s<<1) BRA disp4.38 +0000(Rn:4)00100011 BRAF Rn4.39 +1011(disp:12s<<1) BSR disp4.40 +0000(Rn:4)00000011 BSRF Rn4.41 +10001001(disp:8s<<1) BT disp4.42 +10001101(disp:8s<<1) BT/S disp4.43 +0000000000101000 CLRMAC4.44 +0000000001001000 CLRS4.45 +0000000000001000 CLRT4.46 +0011(Rn:4)(Rm:4)0000 CMP/EQ Rm, Rn4.47 +10001000(imm:8s) CMP/EQ #imm, R04.48 +0011(Rn:4)(Rm:4)0011 CMP/GE Rm, Rn4.49 +0011(Rn:4)(Rm:4)0111 CMP/GT Rm, Rn4.50 +0011(Rn:4)(Rm:4)0110 CMP/HI Rm, Rn4.51 +0011(Rn:4)(Rm:4)0010 CMP/HS Rm, Rn4.52 +0100(Rn:4)00010101 CMP/PL Rn4.53 +0100(Rn:4)00010001 CMP/PZ Rn4.54 +0010(Rn:4)(Rm:4)1100 CMP/STR Rm, Rn4.55 +0010(Rn:4)(Rm:4)0111 DIV0S Rm, Rn4.56 +0000000000011001 DIV0U4.57 +0011(Rn:4)(Rm:4)0100 DIV1 Rm, Rn4.58 +0011(Rn:4)(Rm:4)1101 DMULS.L Rm, Rn4.59 +0011(Rn:4)(Rm:4)0101 DMULU.L Rm, Rn4.60 +0100(Rn:4)00010000 DT Rn4.61 +0110(Rn:4)(Rm:4)1110 EXTS.B Rm, Rn4.62 +0110(Rn:4)(Rm:4)1111 EXTS.W Rm, Rn4.63 +0110(Rn:4)(Rm:4)1100 EXTU.B Rm, Rn4.64 +0110(Rn:4)(Rm:4)1101 EXTU.W Rm, Rn4.65 +1111(FRn:4)01011101 FABS FRn4.66 +1111(FRn:4)(FRm:4)0000 FADD FRm, FRn4.67 +1111(FRn:4)(FRm:4)0100 FCMP/EQ FRm, FRn4.68 +1111(FRn:4)(FRm:4)0101 FCMP/GT FRm, FRn4.69 +1111(FRm:4)10111101 FCNVDS FRm, FPUL4.70 +1111(FRn:4)10101101 FCNVSD FPUL, FRn4.71 +1111(FRn:4)(FRm:4)0011 FDIV FRm, FRn4.72 +1111(FVn:2)(FVm:2)11101101 FIPR FVm, FVn4.73 +1111(FRm:4)00011101 FLDS FRm, FPUL4.74 +1111(FRn:4)10001101 FLDI0 FRn4.75 +1111(FRn:4)10011101 FLDI1 FRn4.76 +1111(FRn:4)00101101 FLOAT FPUL, FRn4.77 +1111(FRn:4)(FRm:4)1110 FMAC FR0, FRm, FRn4.78 +1111(FRn:4)(FRm:4)1100 FMOV FRm, FRn4.79 +1111(Rn:4)(FRm:4)1010 FMOV FRm, @Rn4.80 +1111(Rn:4)(FRm:4)1011 FMOV FRm, @-Rn4.81 +1111(Rn:4)(FRm:4)0111 FMOV FRm, @(R0, Rn)4.82 +1111(FRn:4)(Rm:4)1000 FMOV @Rm, FRn4.83 +1111(FRn:4)(Rm:4)1001 FMOV @Rm+, FRn4.84 +1111(FRn:4)(Rm:4)0110 FMOV @(R0, Rm), FRn4.85 +1111(FRn:4)(FRm:4)0010 FMUL FRm, FRn4.86 +1111(FRn:4)01001101 FNEG FRn4.87 +1111101111111101 FRCHG4.88 +1111(FRn:3<<1)011111101 FSCA FPUL, FRn4.89 +1111001111111101 FSCHG4.90 +1111(FRn:4)01101101 FSQRT FRn4.91 +1111(FRn:4)01111101 FSRRA FRn4.92 +1111(FRn:4)00001101 FSTS FPUL, FRn4.93 +1111(FRn:4)(FRm:4)0001 FSUB FRm, FRn4.94 +1111(FRm:4)00111101 FTRC FRm, FPUL4.95 +1111(FVn:2)0111111101 FTRV XMTRX, FVn4.96 +0100(Rn:4)00101011 JMP @Rn4.97 +0100(Rn:4)00001011 JSR @Rn4.98 +0100(Rm:4)00011110 LDC Rm, GBR4.99 +0100(Rm:4)00001110 LDC Rm, SR4.100 +0100(Rm:4)00101110 LDC Rm, VBR4.101 +0100(Rm:4)00111110 LDC Rm, SSR4.102 +0100(Rm:4)00111010 LDC Rm, SGR4.103 +0100(Rm:4)01001110 LDC Rm, SPC4.104 +0100(Rm:4)11111010 LDC Rm, DBR4.105 +0100(Rm:4)1(Rn_BANK:3)1110 LDC Rm, Rn_BANK4.106 +0100(Rm:4)00010111 LDC.L @Rm+, GBR4.107 +0100(Rm:4)00000111 LDC.L @Rm+, SR4.108 +0100(Rm:4)00100111 LDC.L @Rm+, VBR4.109 +0100(Rm:4)00110111 LDC.L @Rm+, SSR4.110 +0100(Rm:4)00110110 LDC.L @Rm+, SGR4.111 +0100(Rm:4)01000111 LDC.L @Rm+, SPC4.112 +0100(Rm:4)11110110 LDC.L @Rm+, DBR4.113 +0100(Rm:4)1(Rn_BANK:3)0111 LDC.L @Rm+, Rn_BANK4.114 +0100(Rm:4)01101010 LDS Rm, FPSCR4.115 +0100(Rm:4)01100110 LDS.L @Rm+, FPSCR4.116 +0100(Rm:4)01011010 LDS Rm, FPUL4.117 +0100(Rm:4)01010110 LDS.L @Rm+, FPUL4.118 +0100(Rm:4)00001010 LDS Rm, MACH4.119 +0100(Rm:4)00000110 LDS.L @Rm+, MACH4.120 +0100(Rm:4)00011010 LDS Rm, MACL4.121 +0100(Rm:4)00010110 LDS.L @Rm+, MACL4.122 +0100(Rm:4)00101010 LDS Rm, PR4.123 +0100(Rm:4)00100110 LDS.L @Rm+, PR4.124 +0000000000111000 LDTLB4.125 +0000(Rn:4)(Rm:4)1111 MAC.L @Rm+, @Rn+4.126 +0100(Rn:4)(Rm:4)1111 MAC.W @Rm+, @Rn+4.127 +0110(Rn:4)(Rm:4)0011 MOV Rm, Rn4.128 +1110(Rn:4)(imm:8s) MOV #imm, Rn4.129 +0010(Rn:4)(Rm:4)0000 MOV.B Rm, @Rn4.130 +0010(Rn:4)(Rm:4)0100 MOV.B Rm, @-Rn4.131 +0000(Rn:4)(Rm:4)0100 MOV.B Rm, @(R0, Rn)4.132 +11000000(disp:8) MOV.B R0, @(disp, GBR)4.133 +10000000(Rn:4)(disp:4) MOV.B R0, @(disp, Rn)4.134 +0110(Rn:4)(Rm:4)0000 MOV.B @Rm, Rn4.135 +0110(Rn:4)(Rm:4)0100 MOV.B @Rm+, Rn4.136 +0000(Rn:4)(Rm:4)1100 MOV.B @(R0, Rm), Rn4.137 +11000100(disp:8) MOV.B @(disp, GBR), R04.138 +10000100(Rm:4)(disp:4) MOV.B @(disp, Rm), R04.139 +0010(Rn:4)(Rm:4)0010 MOV.L Rm, @Rn4.140 +0010(Rn:4)(Rm:4)0110 MOV.L Rm, @-Rn4.141 +0000(Rn:4)(Rm:4)0110 MOV.L Rm, @(R0, Rn)4.142 +11000010(disp:8<<2) MOV.L R0, @(disp, GBR)4.143 +0001(Rn:4)(Rm:4)(disp:4<<2) MOV.L Rm, @(disp, Rn)4.144 +0110(Rn:4)(Rm:4)0010 MOV.L @Rm, Rn4.145 +0110(Rn:4)(Rm:4)0110 MOV.L @Rm+, Rn4.146 +0000(Rn:4)(Rm:4)1110 MOV.L @(R0, Rm), Rn4.147 +11000110(disp:8<<2) MOV.L @(disp, GBR), R04.148 +1101(Rn:4)(disp:8<<2) MOV.L @(disp, PC), Rn4.149 +0101(Rn:4)(Rm:4)(disp:4<<2) MOV.L @(disp, Rm), Rn4.150 +0010(Rn:4)(Rm:4)0001 MOV.W Rm, @Rn4.151 +0010(Rn:4)(Rm:4)0101 MOV.W Rm, @-Rn4.152 +0000(Rn:4)(Rm:4)0101 MOV.W Rm, @(R0, Rn)4.153 +11000001(disp:8<<1) MOV.W R0, @(disp, GBR)4.154 +10000001(Rn:4)(disp:4<<1) MOV.W R0, @(disp, Rn)4.155 +0110(Rn:4)(Rm:4)0001 MOV.W @Rm, Rn4.156 +0110(Rn:4)(Rm:4)0101 MOV.W @Rm+, Rn4.157 +0000(Rn:4)(Rm:4)1101 MOV.W @(R0, Rm), Rn4.158 +11000101(disp:8<<1) MOV.W @(disp, GBR), R04.159 +1001(Rn:4)(disp:8<<1) MOV.W @(disp, PC), Rn4.160 +10000101(Rm:4)(disp:4<<1) MOV.W @(disp, Rm), R04.161 +11000111(disp:8<<2) MOVA @(disp, PC), R04.162 +0000(Rn:4)11000011 MOVCA.L R0, @Rn4.163 +0000(Rn:4)00101001 MOVT Rn4.164 +0000(Rn:4)(Rm:4)0111 MUL.L Rm, Rn4.165 +0010(Rn:4)(Rm:4)1111 MULS.W Rm, Rn4.166 +0010(Rn:4)(Rm:4)1110 MULU.W Rm, Rn4.167 +0110(Rn:4)(Rm:4)1011 NEG Rm, Rn4.168 +0110(Rn:4)(Rm:4)1010 NEGC Rm, Rn4.169 +0000000000001001 NOP4.170 +0110(Rn:4)(Rm:4)0111 NOT Rm, Rn4.171 +0000(Rn:4)10010011 OCBI @Rn4.172 +0000(Rn:4)10100011 OCBP @Rn4.173 +0000(Rn:4)10110011 OCBWB @Rn4.174 +0010(Rn:4)(Rm:4)1011 OR Rm, Rn4.175 +11001011(imm:8) OR #imm, R04.176 +11001111(imm:8) OR.B #imm, @(R0, GBR)4.177 +0000(Rn:4)10000011 PREF @Rn4.178 +0100(Rn:4)00100100 ROTCL Rn4.179 +0100(Rn:4)00100101 ROTCR Rn4.180 +0100(Rn:4)00000100 ROTL Rn4.181 +0100(Rn:4)00000101 ROTR Rn4.182 +0000000000101011 RTE4.183 +0000000000001011 RTS4.184 +0000000001011000 SETS4.185 +0000000000011000 SETT4.186 +0100(Rn:4)(Rm:4)1100 SHAD Rm, Rn4.187 +0100(Rn:4)00100000 SHAL Rn4.188 +0100(Rn:4)00100001 SHAR Rn4.189 +0100(Rn:4)(Rm:4)1101 SHLD Rm, Rn4.190 +0100(Rn:4)00000000 SHLL Rn4.191 +0100(Rn:4)00001000 SHLL2 Rn4.192 +0100(Rn:4)00011000 SHLL8 Rn4.193 +0100(Rn:4)00101000 SHLL16 Rn4.194 +0100(Rn:4)00000001 SHLR Rn4.195 +0100(Rn:4)00001001 SHLR2 Rn4.196 +0100(Rn:4)00011001 SHLR8 Rn4.197 +0100(Rn:4)00101001 SHLR16 Rn4.198 +0000000000011011 SLEEP4.199 +0000(Rn:4)00000010 STC SR, Rn4.200 +0000(Rn:4)00010010 STC GBR, Rn4.201 +0000(Rn:4)00100010 STC VBR, Rn4.202 +0000(Rn:4)00110010 STC SSR, Rn4.203 +0000(Rn:4)01000010 STC SPC, Rn4.204 +0000(Rn:4)00111010 STC SGR, Rn4.205 +0000(Rn:4)11111010 STC DBR, Rn4.206 +0000(Rn:4)1(Rm_BANK:3)0010 STC Rm_BANK, Rn4.207 +0100(Rn:4)00000011 STC.L SR, @-Rn4.208 +0100(Rn:4)00100011 STC.L VBR, @-Rn4.209 +0100(Rn:4)00110011 STC.L SSR, @-Rn4.210 +0100(Rn:4)01000011 STC.L SPC, @-Rn4.211 +0100(Rn:4)00110010 STC.L SGR, @-Rn4.212 +0100(Rn:4)11110010 STC.L DBR, @-Rn4.213 +0100(Rn:4)1(Rm_BANK:3)0011 STC.L Rm_BANK, @-Rn4.214 +0100(Rn:4)00010011 STC.L GBR, @-Rn4.215 +0000(Rn:4)01101010 STS FPSCR, Rn4.216 +0100(Rn:4)01100010 STS.L FPSCR, @-Rn4.217 +0000(Rn:4)01011010 STS FPUL, Rn4.218 +0100(Rn:4)01010010 STS.L FPUL, @-Rn4.219 +0000(Rn:4)00001010 STS MACH, Rn4.220 +0100(Rn:4)00000010 STS.L MACH, @-Rn4.221 +0000(Rn:4)00011010 STS MACL, Rn4.222 +0100(Rn:4)00010010 STS.L MACL, @-Rn4.223 +0000(Rn:4)00101010 STS PR, Rn4.224 +0100(Rn:4)00100010 STS.L PR, @-Rn4.225 +0011(Rn:4)(Rm:4)1000 SUB Rm, Rn4.226 +0011(Rn:4)(Rm:4)1010 SUBC Rm, Rn4.227 +0011(Rn:4)(Rm:4)1011 SUBV Rm, Rn4.228 +0110(Rn:4)(Rm:4)1000 SWAP.B Rm, Rn4.229 +0110(Rn:4)(Rm:4)1001 SWAP.W Rm, Rn4.230 +0100(Rn:4)00011011 TAS.B @Rn4.231 +11000011(imm:8) TRAPA #imm4.232 +0010(Rn:4)(Rm:4)1000 TST Rm, Rn4.233 +11001000(imm:8) TST #imm, R04.234 +11001100(imm:8) TST.B #imm, @(R0, GBR)4.235 +0010(Rn:4)(Rm:4)1010 XOR Rm, Rn4.236 +11001010(imm:8) XOR #imm, R04.237 +11001110(imm:8) XOR.B #imm, @(R0, GBR)4.238 +0010(Rn:4)(Rm:4)1101 XTRCT Rm, Rn4.239 +1111111111111101 UNDEF
5.1 --- a/src/sh4/sh4core.c Thu Aug 23 12:31:31 2007 +00005.2 +++ b/src/sh4/sh4core.c Thu Aug 23 12:33:27 2007 +00005.3 @@ -1,5 +1,5 @@5.4 /**5.5 - * $Id: sh4core.c,v 1.40 2007-01-23 08:17:06 nkeynes Exp $5.6 + * $Id: sh4core.c,v 1.41 2007-08-23 12:33:27 nkeynes Exp $5.7 *5.8 * SH4 emulation core, and parent module for all the SH4 peripheral5.9 * modules.5.10 @@ -58,7 +58,7 @@5.11 void sh4_stop( void );5.12 void sh4_save_state( FILE *f );5.13 int sh4_load_state( FILE *f );5.14 -static void sh4_accept_interrupt( void );5.15 +void sh4_accept_interrupt( void );5.17 struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,5.18 NULL, sh4_run_slice, sh4_stop,5.19 @@ -327,7 +327,7 @@5.20 #define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )5.21 #define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )5.23 -#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE )5.24 +#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE ); } }5.25 #define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }5.26 #define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)5.28 @@ -415,7 +415,7 @@5.29 RAISE( code, EXV_TLBMISS );5.30 }5.32 -static void sh4_accept_interrupt( void )5.33 +void sh4_accept_interrupt( void )5.34 {5.35 uint32_t code = intc_accept_interrupt();5.36 sh4r.ssr = sh4_read_sr();5.37 @@ -433,39 +433,10 @@5.38 uint32_t pc;5.39 unsigned short ir;5.40 uint32_t tmp;5.41 - uint64_t tmpl;5.42 float ftmp;5.43 double dtmp;5.45 #define R0 sh4r.r[0]5.46 -#define FR0 FR(0)5.47 -#define DR0 DR(0)5.48 -#define RN(ir) sh4r.r[(ir&0x0F00)>>8]5.49 -#define RN_BANK(ir) sh4r.r_bank[(ir&0x0070)>>4]5.50 -#define RM(ir) sh4r.r[(ir&0x00F0)>>4]5.51 -#define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *NOT* sign-extended */5.52 -#define DISP8(ir) (ir&0x00FF)5.53 -#define PCDISP8(ir) SIGNEXT8(ir&0x00FF)5.54 -#define IMM8(ir) SIGNEXT8(ir&0x00FF)5.55 -#define UIMM8(ir) (ir&0x00FF) /* Unsigned immmediate */5.56 -#define DISP12(ir) SIGNEXT12(ir&0x0FFF)5.57 -#define FRNn(ir) ((ir&0x0F00)>>8)5.58 -#define FRMn(ir) ((ir&0x00F0)>>4)5.59 -#define DRNn(ir) ((ir&0x0E00)>>9)5.60 -#define DRMn(ir) ((ir&0x00E0)>>5)5.61 -#define FVN(ir) ((ir&0x0C00)>>8)5.62 -#define FVM(ir) ((ir&0x0300)>>6)5.63 -#define FRN(ir) FR(FRNn(ir))5.64 -#define FRM(ir) FR(FRMn(ir))5.65 -#define FRNi(ir) (*((uint32_t *)&FR(FRNn(ir))))5.66 -#define FRMi(ir) (*((uint32_t *)&FR(FRMn(ir))))5.67 -#define DRN(ir) DRb(DRNn(ir), ir&0x0100)5.68 -#define DRM(ir) DRb(DRMn(ir),ir&0x0010)5.69 -#define DRNi(ir) (*((uint64_t *)&DR(FRNn(ir))))5.70 -#define DRMi(ir) (*((uint64_t *)&DR(FRMn(ir))))5.71 -#define FPULf *((float *)&sh4r.fpul)5.72 -#define FPULi (sh4r.fpul)5.73 -5.74 pc = sh4r.pc;5.75 if( pc > 0xFFFFFF00 ) {5.76 /* SYSCALL Magic */5.77 @@ -493,1176 +464,1891 @@5.78 ir = sh4_icache[(pc&0xFFF)>>1];5.79 }5.80 }5.81 -5.82 - switch( (ir&0xF000)>>12 ) {5.83 - case 0: /* 0000nnnnmmmmxxxx */5.84 - switch( ir&0x000F ) {5.85 - case 2:5.86 - switch( (ir&0x00F0)>>4 ) {5.87 - case 0: /* STC SR, Rn */5.88 - CHECKPRIV();5.89 - RN(ir) = sh4_read_sr();5.90 - break;5.91 - case 1: /* STC GBR, Rn */5.92 - RN(ir) = sh4r.gbr;5.93 - break;5.94 - case 2: /* STC VBR, Rn */5.95 - CHECKPRIV();5.96 - RN(ir) = sh4r.vbr;5.97 - break;5.98 - case 3: /* STC SSR, Rn */5.99 - CHECKPRIV();5.100 - RN(ir) = sh4r.ssr;5.101 - break;5.102 - case 4: /* STC SPC, Rn */5.103 - CHECKPRIV();5.104 - RN(ir) = sh4r.spc;5.105 - break;5.106 - case 8: case 9: case 10: case 11: case 12: case 13:5.107 - case 14: case 15:/* STC Rm_bank, Rn */5.108 - CHECKPRIV();5.109 - RN(ir) = RN_BANK(ir);5.110 - break;5.111 - default: UNDEF(ir);5.112 - }5.113 - break;5.114 - case 3:5.115 - switch( (ir&0x00F0)>>4 ) {5.116 - case 0: /* BSRF Rn */5.117 - CHECKSLOTILLEGAL();5.118 - CHECKDEST( pc + 4 + RN(ir) );5.119 - sh4r.in_delay_slot = 1;5.120 - sh4r.pr = sh4r.pc + 4;5.121 - sh4r.pc = sh4r.new_pc;5.122 - sh4r.new_pc = pc + 4 + RN(ir);5.123 - TRACE_CALL( pc, sh4r.new_pc );5.124 + switch( (ir&0xF000) >> 12 ) {5.125 + case 0x0:5.126 + switch( ir&0xF ) {5.127 + case 0x2:5.128 + switch( (ir&0x80) >> 7 ) {5.129 + case 0x0:5.130 + switch( (ir&0x70) >> 4 ) {5.131 + case 0x0:5.132 + { /* STC SR, Rn */5.133 + uint32_t Rn = ((ir>>8)&0xF);5.134 + CHECKPRIV();5.135 + sh4r.r[Rn] = sh4_read_sr();5.136 + }5.137 + break;5.138 + case 0x1:5.139 + { /* STC GBR, Rn */5.140 + uint32_t Rn = ((ir>>8)&0xF);5.141 + CHECKPRIV();5.142 + sh4r.r[Rn] = sh4r.gbr;5.143 + }5.144 + break;5.145 + case 0x2:5.146 + { /* STC VBR, Rn */5.147 + uint32_t Rn = ((ir>>8)&0xF);5.148 + CHECKPRIV();5.149 + sh4r.r[Rn] = sh4r.vbr;5.150 + }5.151 + break;5.152 + case 0x3:5.153 + { /* STC SSR, Rn */5.154 + uint32_t Rn = ((ir>>8)&0xF);5.155 + CHECKPRIV();5.156 + sh4r.r[Rn] = sh4r.ssr;5.157 + }5.158 + break;5.159 + case 0x4:5.160 + { /* STC SPC, Rn */5.161 + uint32_t Rn = ((ir>>8)&0xF);5.162 + CHECKPRIV();5.163 + sh4r.r[Rn] = sh4r.spc;5.164 + }5.165 + break;5.166 + default:5.167 + UNDEF();5.168 + break;5.169 + }5.170 + break;5.171 + case 0x1:5.172 + { /* STC Rm_BANK, Rn */5.173 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);5.174 + CHECKPRIV();5.175 + sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];5.176 + }5.177 + break;5.178 + }5.179 + break;5.180 + case 0x3:5.181 + switch( (ir&0xF0) >> 4 ) {5.182 + case 0x0:5.183 + { /* BSRF Rn */5.184 + uint32_t Rn = ((ir>>8)&0xF);5.185 + CHECKSLOTILLEGAL();5.186 + CHECKDEST( pc + 4 + sh4r.r[Rn] );5.187 + sh4r.in_delay_slot = 1;5.188 + sh4r.pr = sh4r.pc + 4;5.189 + sh4r.pc = sh4r.new_pc;5.190 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];5.191 + TRACE_CALL( pc, sh4r.new_pc );5.192 + return TRUE;5.193 + }5.194 + break;5.195 + case 0x2:5.196 + { /* BRAF Rn */5.197 + uint32_t Rn = ((ir>>8)&0xF);5.198 + CHECKSLOTILLEGAL();5.199 + CHECKDEST( pc + 4 + sh4r.r[Rn] );5.200 + sh4r.in_delay_slot = 1;5.201 + sh4r.pc = sh4r.new_pc;5.202 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];5.203 + return TRUE;5.204 + }5.205 + break;5.206 + case 0x8:5.207 + { /* PREF @Rn */5.208 + uint32_t Rn = ((ir>>8)&0xF);5.209 + tmp = sh4r.r[Rn];5.210 + if( (tmp & 0xFC000000) == 0xE0000000 ) {5.211 + /* Store queue operation */5.212 + int queue = (tmp&0x20)>>2;5.213 + int32_t *src = &sh4r.store_queue[queue];5.214 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;5.215 + uint32_t target = tmp&0x03FFFFE0 | hi;5.216 + mem_copy_to_sh4( target, src, 32 );5.217 + }5.218 + }5.219 + break;5.220 + case 0x9:5.221 + { /* OCBI @Rn */5.222 + uint32_t Rn = ((ir>>8)&0xF);5.223 + }5.224 + break;5.225 + case 0xA:5.226 + { /* OCBP @Rn */5.227 + uint32_t Rn = ((ir>>8)&0xF);5.228 + }5.229 + break;5.230 + case 0xB:5.231 + { /* OCBWB @Rn */5.232 + uint32_t Rn = ((ir>>8)&0xF);5.233 + }5.234 + break;5.235 + case 0xC:5.236 + { /* MOVCA.L R0, @Rn */5.237 + uint32_t Rn = ((ir>>8)&0xF);5.238 + tmp = sh4r.r[Rn];5.239 + CHECKWALIGN32(tmp);5.240 + MEM_WRITE_LONG( tmp, R0 );5.241 + }5.242 + break;5.243 + default:5.244 + UNDEF();5.245 + break;5.246 + }5.247 + break;5.248 + case 0x4:5.249 + { /* MOV.B Rm, @(R0, Rn) */5.250 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.251 + MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] );5.252 + }5.253 + break;5.254 + case 0x5:5.255 + { /* MOV.W Rm, @(R0, Rn) */5.256 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.257 + CHECKWALIGN16( R0 + sh4r.r[Rn] );5.258 + MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );5.259 + }5.260 + break;5.261 + case 0x6:5.262 + { /* MOV.L Rm, @(R0, Rn) */5.263 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.264 + CHECKWALIGN32( R0 + sh4r.r[Rn] );5.265 + MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );5.266 + }5.267 + break;5.268 + case 0x7:5.269 + { /* MUL.L Rm, Rn */5.270 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.271 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.272 + (sh4r.r[Rm] * sh4r.r[Rn]);5.273 + }5.274 + break;5.275 + case 0x8:5.276 + switch( (ir&0xFF0) >> 4 ) {5.277 + case 0x0:5.278 + { /* CLRT */5.279 + sh4r.t = 0;5.280 + }5.281 + break;5.282 + case 0x1:5.283 + { /* SETT */5.284 + sh4r.t = 1;5.285 + }5.286 + break;5.287 + case 0x2:5.288 + { /* CLRMAC */5.289 + sh4r.mac = 0;5.290 + }5.291 + break;5.292 + case 0x3:5.293 + { /* LDTLB */5.294 + /* TODO */5.295 + }5.296 + break;5.297 + case 0x4:5.298 + { /* CLRS */5.299 + sh4r.s = 0;5.300 + }5.301 + break;5.302 + case 0x5:5.303 + { /* SETS */5.304 + sh4r.s = 1;5.305 + }5.306 + break;5.307 + default:5.308 + UNDEF();5.309 + break;5.310 + }5.311 + break;5.312 + case 0x9:5.313 + switch( (ir&0xF0) >> 4 ) {5.314 + case 0x0:5.315 + { /* NOP */5.316 + /* NOP */5.317 + }5.318 + break;5.319 + case 0x1:5.320 + { /* DIV0U */5.321 + sh4r.m = sh4r.q = sh4r.t = 0;5.322 + }5.323 + break;5.324 + case 0x2:5.325 + { /* MOVT Rn */5.326 + uint32_t Rn = ((ir>>8)&0xF);5.327 + sh4r.r[Rn] = sh4r.t;5.328 + }5.329 + break;5.330 + default:5.331 + UNDEF();5.332 + break;5.333 + }5.334 + break;5.335 + case 0xA:5.336 + switch( (ir&0xF0) >> 4 ) {5.337 + case 0x0:5.338 + { /* STS MACH, Rn */5.339 + uint32_t Rn = ((ir>>8)&0xF);5.340 + sh4r.r[Rn] = (sh4r.mac>>32);5.341 + }5.342 + break;5.343 + case 0x1:5.344 + { /* STS MACL, Rn */5.345 + uint32_t Rn = ((ir>>8)&0xF);5.346 + sh4r.r[Rn] = (uint32_t)sh4r.mac;5.347 + }5.348 + break;5.349 + case 0x2:5.350 + { /* STS PR, Rn */5.351 + uint32_t Rn = ((ir>>8)&0xF);5.352 + sh4r.r[Rn] = sh4r.pr;5.353 + }5.354 + break;5.355 + case 0x3:5.356 + { /* STC SGR, Rn */5.357 + uint32_t Rn = ((ir>>8)&0xF);5.358 + CHECKPRIV();5.359 + sh4r.r[Rn] = sh4r.sgr;5.360 + }5.361 + break;5.362 + case 0x5:5.363 + { /* STS FPUL, Rn */5.364 + uint32_t Rn = ((ir>>8)&0xF);5.365 + sh4r.r[Rn] = sh4r.fpul;5.366 + }5.367 + break;5.368 + case 0x6:5.369 + { /* STS FPSCR, Rn */5.370 + uint32_t Rn = ((ir>>8)&0xF);5.371 + sh4r.r[Rn] = sh4r.fpscr;5.372 + }5.373 + break;5.374 + case 0xF:5.375 + { /* STC DBR, Rn */5.376 + uint32_t Rn = ((ir>>8)&0xF);5.377 + CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr;5.378 + }5.379 + break;5.380 + default:5.381 + UNDEF();5.382 + break;5.383 + }5.384 + break;5.385 + case 0xB:5.386 + switch( (ir&0xFF0) >> 4 ) {5.387 + case 0x0:5.388 + { /* RTS */5.389 + CHECKSLOTILLEGAL();5.390 + CHECKDEST( sh4r.pr );5.391 + sh4r.in_delay_slot = 1;5.392 + sh4r.pc = sh4r.new_pc;5.393 + sh4r.new_pc = sh4r.pr;5.394 + TRACE_RETURN( pc, sh4r.new_pc );5.395 + return TRUE;5.396 + }5.397 + break;5.398 + case 0x1:5.399 + { /* SLEEP */5.400 + if( MMIO_READ( CPG, STBCR ) & 0x80 ) {5.401 + sh4r.sh4_state = SH4_STATE_STANDBY;5.402 + } else {5.403 + sh4r.sh4_state = SH4_STATE_SLEEP;5.404 + }5.405 + return FALSE; /* Halt CPU */5.406 + }5.407 + break;5.408 + case 0x2:5.409 + { /* RTE */5.410 + CHECKPRIV();5.411 + CHECKDEST( sh4r.spc );5.412 + CHECKSLOTILLEGAL();5.413 + sh4r.in_delay_slot = 1;5.414 + sh4r.pc = sh4r.new_pc;5.415 + sh4r.new_pc = sh4r.spc;5.416 + sh4_load_sr( sh4r.ssr );5.417 + return TRUE;5.418 + }5.419 + break;5.420 + default:5.421 + UNDEF();5.422 + break;5.423 + }5.424 + break;5.425 + case 0xC:5.426 + { /* MOV.B @(R0, Rm), Rn */5.427 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.428 + sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] );5.429 + }5.430 + break;5.431 + case 0xD:5.432 + { /* MOV.W @(R0, Rm), Rn */5.433 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.434 + CHECKRALIGN16( R0 + sh4r.r[Rm] );5.435 + sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );5.436 + }5.437 + break;5.438 + case 0xE:5.439 + { /* MOV.L @(R0, Rm), Rn */5.440 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.441 + CHECKRALIGN32( R0 + sh4r.r[Rm] );5.442 + sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );5.443 + }5.444 + break;5.445 + case 0xF:5.446 + { /* MAC.L @Rm+, @Rn+ */5.447 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.448 + CHECKRALIGN32( sh4r.r[Rm] );5.449 + CHECKRALIGN32( sh4r.r[Rn] );5.450 + int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));5.451 + sh4r.r[Rn] += 4;5.452 + tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;5.453 + sh4r.r[Rm] += 4;5.454 + if( sh4r.s ) {5.455 + /* 48-bit Saturation. Yuch */5.456 + if( tmpl < (int64_t)0xFFFF800000000000LL )5.457 + tmpl = 0xFFFF800000000000LL;5.458 + else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )5.459 + tmpl = 0x00007FFFFFFFFFFFLL;5.460 + }5.461 + sh4r.mac = tmpl;5.462 + }5.463 + break;5.464 + default:5.465 + UNDEF();5.466 + break;5.467 + }5.468 + break;5.469 + case 0x1:5.470 + { /* MOV.L Rm, @(disp, Rn) */5.471 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;5.472 + tmp = sh4r.r[Rn] + disp;5.473 + CHECKWALIGN32( tmp );5.474 + MEM_WRITE_LONG( tmp, sh4r.r[Rm] );5.475 + }5.476 + break;5.477 + case 0x2:5.478 + switch( ir&0xF ) {5.479 + case 0x0:5.480 + { /* MOV.B Rm, @Rn */5.481 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.482 + MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );5.483 + }5.484 + break;5.485 + case 0x1:5.486 + { /* MOV.W Rm, @Rn */5.487 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.488 + CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );5.489 + }5.490 + break;5.491 + case 0x2:5.492 + { /* MOV.L Rm, @Rn */5.493 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.494 + CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );5.495 + }5.496 + break;5.497 + case 0x4:5.498 + { /* MOV.B Rm, @-Rn */5.499 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.500 + sh4r.r[Rn] --; MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] );5.501 + }5.502 + break;5.503 + case 0x5:5.504 + { /* MOV.W Rm, @-Rn */5.505 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.506 + sh4r.r[Rn] -= 2; CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] );5.507 + }5.508 + break;5.509 + case 0x6:5.510 + { /* MOV.L Rm, @-Rn */5.511 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.512 + sh4r.r[Rn] -= 4; CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] );5.513 + }5.514 + break;5.515 + case 0x7:5.516 + { /* DIV0S Rm, Rn */5.517 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.518 + sh4r.q = sh4r.r[Rn]>>31;5.519 + sh4r.m = sh4r.r[Rm]>>31;5.520 + sh4r.t = sh4r.q ^ sh4r.m;5.521 + }5.522 + break;5.523 + case 0x8:5.524 + { /* TST Rm, Rn */5.525 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.526 + sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1);5.527 + }5.528 + break;5.529 + case 0x9:5.530 + { /* AND Rm, Rn */5.531 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.532 + sh4r.r[Rn] &= sh4r.r[Rm];5.533 + }5.534 + break;5.535 + case 0xA:5.536 + { /* XOR Rm, Rn */5.537 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.538 + sh4r.r[Rn] ^= sh4r.r[Rm];5.539 + }5.540 + break;5.541 + case 0xB:5.542 + { /* OR Rm, Rn */5.543 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.544 + sh4r.r[Rn] |= sh4r.r[Rm];5.545 + }5.546 + break;5.547 + case 0xC:5.548 + { /* CMP/STR Rm, Rn */5.549 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.550 + /* set T = 1 if any byte in RM & RN is the same */5.551 + tmp = sh4r.r[Rm] ^ sh4r.r[Rn];5.552 + sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||5.553 + (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;5.554 + }5.555 + break;5.556 + case 0xD:5.557 + { /* XTRCT Rm, Rn */5.558 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.559 + sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16);5.560 + }5.561 + break;5.562 + case 0xE:5.563 + { /* MULU.W Rm, Rn */5.564 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.565 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.566 + (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));5.567 + }5.568 + break;5.569 + case 0xF:5.570 + { /* MULS.W Rm, Rn */5.571 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.572 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.573 + (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));5.574 + }5.575 + break;5.576 + default:5.577 + UNDEF();5.578 + break;5.579 + }5.580 + break;5.581 + case 0x3:5.582 + switch( ir&0xF ) {5.583 + case 0x0:5.584 + { /* CMP/EQ Rm, Rn */5.585 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.586 + sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 );5.587 + }5.588 + break;5.589 + case 0x2:5.590 + { /* CMP/HS Rm, Rn */5.591 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.592 + sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 );5.593 + }5.594 + break;5.595 + case 0x3:5.596 + { /* CMP/GE Rm, Rn */5.597 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.598 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 );5.599 + }5.600 + break;5.601 + case 0x4:5.602 + { /* DIV1 Rm, Rn */5.603 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.604 + /* This is just from the sh4p manual with some5.605 + * simplifications (someone want to check it's correct? :)5.606 + * Why they couldn't just provide a real DIV instruction...5.607 + */5.608 + uint32_t tmp0, tmp1, tmp2, dir;5.609 +5.610 + dir = sh4r.q ^ sh4r.m;5.611 + sh4r.q = (sh4r.r[Rn] >> 31);5.612 + tmp2 = sh4r.r[Rm];5.613 + sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;5.614 + tmp0 = sh4r.r[Rn];5.615 + if( dir ) {5.616 + sh4r.r[Rn] += tmp2;5.617 + tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );5.618 + } else {5.619 + sh4r.r[Rn] -= tmp2;5.620 + tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );5.621 + }5.622 + sh4r.q ^= sh4r.m ^ tmp1;5.623 + sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );5.624 + }5.625 + break;5.626 + case 0x5:5.627 + { /* DMULU.L Rm, Rn */5.628 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.629 + sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]);5.630 + }5.631 + break;5.632 + case 0x6:5.633 + { /* CMP/HI Rm, Rn */5.634 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.635 + sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 );5.636 + }5.637 + break;5.638 + case 0x7:5.639 + { /* CMP/GT Rm, Rn */5.640 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.641 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 );5.642 + }5.643 + break;5.644 + case 0x8:5.645 + { /* SUB Rm, Rn */5.646 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.647 + sh4r.r[Rn] -= sh4r.r[Rm];5.648 + }5.649 + break;5.650 + case 0xA:5.651 + { /* SUBC Rm, Rn */5.652 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.653 + tmp = sh4r.r[Rn];5.654 + sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;5.655 + sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));5.656 + }5.657 + break;5.658 + case 0xB:5.659 + UNIMP(ir); /* SUBV Rm, Rn */5.660 + break;5.661 + case 0xC:5.662 + { /* ADD Rm, Rn */5.663 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.664 + sh4r.r[Rn] += sh4r.r[Rm];5.665 + }5.666 + break;5.667 + case 0xD:5.668 + { /* DMULS.L Rm, Rn */5.669 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.670 + sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]);5.671 + }5.672 + break;5.673 + case 0xE:5.674 + { /* ADDC Rm, Rn */5.675 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.676 + tmp = sh4r.r[Rn];5.677 + sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;5.678 + sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );5.679 + }5.680 + break;5.681 + case 0xF:5.682 + { /* ADDV Rm, Rn */5.683 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.684 + tmp = sh4r.r[Rn] + sh4r.r[Rm];5.685 + sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );5.686 + sh4r.r[Rn] = tmp;5.687 + }5.688 + break;5.689 + default:5.690 + UNDEF();5.691 + break;5.692 + }5.693 + break;5.694 + case 0x4:5.695 + switch( ir&0xF ) {5.696 + case 0x0:5.697 + switch( (ir&0xF0) >> 4 ) {5.698 + case 0x0:5.699 + { /* SHLL Rn */5.700 + uint32_t Rn = ((ir>>8)&0xF);5.701 + sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1;5.702 + }5.703 + break;5.704 + case 0x1:5.705 + { /* DT Rn */5.706 + uint32_t Rn = ((ir>>8)&0xF);5.707 + sh4r.r[Rn] --;5.708 + sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );5.709 + }5.710 + break;5.711 + case 0x2:5.712 + { /* SHAL Rn */5.713 + uint32_t Rn = ((ir>>8)&0xF);5.714 + sh4r.t = sh4r.r[Rn] >> 31;5.715 + sh4r.r[Rn] <<= 1;5.716 + }5.717 + break;5.718 + default:5.719 + UNDEF();5.720 + break;5.721 + }5.722 + break;5.723 + case 0x1:5.724 + switch( (ir&0xF0) >> 4 ) {5.725 + case 0x0:5.726 + { /* SHLR Rn */5.727 + uint32_t Rn = ((ir>>8)&0xF);5.728 + sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1;5.729 + }5.730 + break;5.731 + case 0x1:5.732 + { /* CMP/PZ Rn */5.733 + uint32_t Rn = ((ir>>8)&0xF);5.734 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 );5.735 + }5.736 + break;5.737 + case 0x2:5.738 + { /* SHAR Rn */5.739 + uint32_t Rn = ((ir>>8)&0xF);5.740 + sh4r.t = sh4r.r[Rn] & 0x00000001;5.741 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;5.742 + }5.743 + break;5.744 + default:5.745 + UNDEF();5.746 + break;5.747 + }5.748 + break;5.749 + case 0x2:5.750 + switch( (ir&0xF0) >> 4 ) {5.751 + case 0x0:5.752 + { /* STS.L MACH, @-Rn */5.753 + uint32_t Rn = ((ir>>8)&0xF);5.754 + sh4r.r[Rn] -= 4;5.755 + CHECKWALIGN32( sh4r.r[Rn] );5.756 + MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );5.757 + }5.758 + break;5.759 + case 0x1:5.760 + { /* STS.L MACL, @-Rn */5.761 + uint32_t Rn = ((ir>>8)&0xF);5.762 + sh4r.r[Rn] -= 4;5.763 + CHECKWALIGN32( sh4r.r[Rn] );5.764 + MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );5.765 + }5.766 + break;5.767 + case 0x2:5.768 + { /* STS.L PR, @-Rn */5.769 + uint32_t Rn = ((ir>>8)&0xF);5.770 + sh4r.r[Rn] -= 4;5.771 + CHECKWALIGN32( sh4r.r[Rn] );5.772 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );5.773 + }5.774 + break;5.775 + case 0x3:5.776 + { /* STC.L SGR, @-Rn */5.777 + uint32_t Rn = ((ir>>8)&0xF);5.778 + CHECKPRIV();5.779 + sh4r.r[Rn] -= 4;5.780 + CHECKWALIGN32( sh4r.r[Rn] );5.781 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );5.782 + }5.783 + break;5.784 + case 0x5:5.785 + { /* STS.L FPUL, @-Rn */5.786 + uint32_t Rn = ((ir>>8)&0xF);5.787 + sh4r.r[Rn] -= 4;5.788 + CHECKWALIGN32( sh4r.r[Rn] );5.789 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );5.790 + }5.791 + break;5.792 + case 0x6:5.793 + { /* STS.L FPSCR, @-Rn */5.794 + uint32_t Rn = ((ir>>8)&0xF);5.795 + sh4r.r[Rn] -= 4;5.796 + CHECKWALIGN32( sh4r.r[Rn] );5.797 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );5.798 + }5.799 + break;5.800 + case 0xF:5.801 + { /* STC.L DBR, @-Rn */5.802 + uint32_t Rn = ((ir>>8)&0xF);5.803 + CHECKPRIV();5.804 + sh4r.r[Rn] -= 4;5.805 + CHECKWALIGN32( sh4r.r[Rn] );5.806 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );5.807 + }5.808 + break;5.809 + default:5.810 + UNDEF();5.811 + break;5.812 + }5.813 + break;5.814 + case 0x3:5.815 + switch( (ir&0x80) >> 7 ) {5.816 + case 0x0:5.817 + switch( (ir&0x70) >> 4 ) {5.818 + case 0x0:5.819 + { /* STC.L SR, @-Rn */5.820 + uint32_t Rn = ((ir>>8)&0xF);5.821 + CHECKPRIV();5.822 + sh4r.r[Rn] -= 4;5.823 + CHECKWALIGN32( sh4r.r[Rn] );5.824 + MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );5.825 + }5.826 + break;5.827 + case 0x1:5.828 + { /* STC.L GBR, @-Rn */5.829 + uint32_t Rn = ((ir>>8)&0xF);5.830 + sh4r.r[Rn] -= 4;5.831 + CHECKWALIGN32( sh4r.r[Rn] );5.832 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );5.833 + }5.834 + break;5.835 + case 0x2:5.836 + { /* STC.L VBR, @-Rn */5.837 + uint32_t Rn = ((ir>>8)&0xF);5.838 + CHECKPRIV();5.839 + sh4r.r[Rn] -= 4;5.840 + CHECKWALIGN32( sh4r.r[Rn] );5.841 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );5.842 + }5.843 + break;5.844 + case 0x3:5.845 + { /* STC.L SSR, @-Rn */5.846 + uint32_t Rn = ((ir>>8)&0xF);5.847 + CHECKPRIV();5.848 + sh4r.r[Rn] -= 4;5.849 + CHECKWALIGN32( sh4r.r[Rn] );5.850 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );5.851 + }5.852 + break;5.853 + case 0x4:5.854 + { /* STC.L SPC, @-Rn */5.855 + uint32_t Rn = ((ir>>8)&0xF);5.856 + CHECKPRIV();5.857 + sh4r.r[Rn] -= 4;5.858 + CHECKWALIGN32( sh4r.r[Rn] );5.859 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );5.860 + }5.861 + break;5.862 + default:5.863 + UNDEF();5.864 + break;5.865 + }5.866 + break;5.867 + case 0x1:5.868 + { /* STC.L Rm_BANK, @-Rn */5.869 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);5.870 + CHECKPRIV();5.871 + sh4r.r[Rn] -= 4;5.872 + CHECKWALIGN32( sh4r.r[Rn] );5.873 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );5.874 + }5.875 + break;5.876 + }5.877 + break;5.878 + case 0x4:5.879 + switch( (ir&0xF0) >> 4 ) {5.880 + case 0x0:5.881 + { /* ROTL Rn */5.882 + uint32_t Rn = ((ir>>8)&0xF);5.883 + sh4r.t = sh4r.r[Rn] >> 31;5.884 + sh4r.r[Rn] <<= 1;5.885 + sh4r.r[Rn] |= sh4r.t;5.886 + }5.887 + break;5.888 + case 0x2:5.889 + { /* ROTCL Rn */5.890 + uint32_t Rn = ((ir>>8)&0xF);5.891 + tmp = sh4r.r[Rn] >> 31;5.892 + sh4r.r[Rn] <<= 1;5.893 + sh4r.r[Rn] |= sh4r.t;5.894 + sh4r.t = tmp;5.895 + }5.896 + break;5.897 + default:5.898 + UNDEF();5.899 + break;5.900 + }5.901 + break;5.902 + case 0x5:5.903 + switch( (ir&0xF0) >> 4 ) {5.904 + case 0x0:5.905 + { /* ROTR Rn */5.906 + uint32_t Rn = ((ir>>8)&0xF);5.907 + sh4r.t = sh4r.r[Rn] & 0x00000001;5.908 + sh4r.r[Rn] >>= 1;5.909 + sh4r.r[Rn] |= (sh4r.t << 31);5.910 + }5.911 + break;5.912 + case 0x1:5.913 + { /* CMP/PL Rn */5.914 + uint32_t Rn = ((ir>>8)&0xF);5.915 + sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 );5.916 + }5.917 + break;5.918 + case 0x2:5.919 + { /* ROTCR Rn */5.920 + uint32_t Rn = ((ir>>8)&0xF);5.921 + tmp = sh4r.r[Rn] & 0x00000001;5.922 + sh4r.r[Rn] >>= 1;5.923 + sh4r.r[Rn] |= (sh4r.t << 31 );5.924 + sh4r.t = tmp;5.925 + }5.926 + break;5.927 + default:5.928 + UNDEF();5.929 + break;5.930 + }5.931 + break;5.932 + case 0x6:5.933 + switch( (ir&0xF0) >> 4 ) {5.934 + case 0x0:5.935 + { /* LDS.L @Rm+, MACH */5.936 + uint32_t Rm = ((ir>>8)&0xF);5.937 + CHECKRALIGN32( sh4r.r[Rm] );5.938 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |5.939 + (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);5.940 + sh4r.r[Rm] += 4;5.941 + }5.942 + break;5.943 + case 0x1:5.944 + { /* LDS.L @Rm+, MACL */5.945 + uint32_t Rm = ((ir>>8)&0xF);5.946 + CHECKRALIGN32( sh4r.r[Rm] );5.947 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |5.948 + (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));5.949 + sh4r.r[Rm] += 4;5.950 + }5.951 + break;5.952 + case 0x2:5.953 + { /* LDS.L @Rm+, PR */5.954 + uint32_t Rm = ((ir>>8)&0xF);5.955 + CHECKRALIGN32( sh4r.r[Rm] );5.956 + sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );5.957 + sh4r.r[Rm] += 4;5.958 + }5.959 + break;5.960 + case 0x3:5.961 + { /* LDC.L @Rm+, SGR */5.962 + uint32_t Rm = ((ir>>8)&0xF);5.963 + CHECKPRIV();5.964 + CHECKRALIGN32( sh4r.r[Rm] );5.965 + sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);5.966 + sh4r.r[Rm] +=4;5.967 + }5.968 + break;5.969 + case 0x5:5.970 + { /* LDS.L @Rm+, FPUL */5.971 + uint32_t Rm = ((ir>>8)&0xF);5.972 + CHECKRALIGN32( sh4r.r[Rm] );5.973 + sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);5.974 + sh4r.r[Rm] +=4;5.975 + }5.976 + break;5.977 + case 0x6:5.978 + { /* LDS.L @Rm+, FPSCR */5.979 + uint32_t Rm = ((ir>>8)&0xF);5.980 + CHECKRALIGN32( sh4r.r[Rm] );5.981 + sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);5.982 + sh4r.r[Rm] +=4;5.983 + }5.984 + break;5.985 + case 0xF:5.986 + { /* LDC.L @Rm+, DBR */5.987 + uint32_t Rm = ((ir>>8)&0xF);5.988 + CHECKPRIV();5.989 + CHECKRALIGN32( sh4r.r[Rm] );5.990 + sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);5.991 + sh4r.r[Rm] +=4;5.992 + }5.993 + break;5.994 + default:5.995 + UNDEF();5.996 + break;5.997 + }5.998 + break;5.999 + case 0x7:5.1000 + switch( (ir&0x80) >> 7 ) {5.1001 + case 0x0:5.1002 + switch( (ir&0x70) >> 4 ) {5.1003 + case 0x0:5.1004 + { /* LDC.L @Rm+, SR */5.1005 + uint32_t Rm = ((ir>>8)&0xF);5.1006 + CHECKSLOTILLEGAL();5.1007 + CHECKPRIV();5.1008 + CHECKWALIGN32( sh4r.r[Rm] );5.1009 + sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );5.1010 + sh4r.r[Rm] +=4;5.1011 + }5.1012 + break;5.1013 + case 0x1:5.1014 + { /* LDC.L @Rm+, GBR */5.1015 + uint32_t Rm = ((ir>>8)&0xF);5.1016 + CHECKRALIGN32( sh4r.r[Rm] );5.1017 + sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);5.1018 + sh4r.r[Rm] +=4;5.1019 + }5.1020 + break;5.1021 + case 0x2:5.1022 + { /* LDC.L @Rm+, VBR */5.1023 + uint32_t Rm = ((ir>>8)&0xF);5.1024 + CHECKPRIV();5.1025 + CHECKRALIGN32( sh4r.r[Rm] );5.1026 + sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);5.1027 + sh4r.r[Rm] +=4;5.1028 + }5.1029 + break;5.1030 + case 0x3:5.1031 + { /* LDC.L @Rm+, SSR */5.1032 + uint32_t Rm = ((ir>>8)&0xF);5.1033 + CHECKPRIV();5.1034 + CHECKRALIGN32( sh4r.r[Rm] );5.1035 + sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);5.1036 + sh4r.r[Rm] +=4;5.1037 + }5.1038 + break;5.1039 + case 0x4:5.1040 + { /* LDC.L @Rm+, SPC */5.1041 + uint32_t Rm = ((ir>>8)&0xF);5.1042 + CHECKPRIV();5.1043 + CHECKRALIGN32( sh4r.r[Rm] );5.1044 + sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);5.1045 + sh4r.r[Rm] +=4;5.1046 + }5.1047 + break;5.1048 + default:5.1049 + UNDEF();5.1050 + break;5.1051 + }5.1052 + break;5.1053 + case 0x1:5.1054 + { /* LDC.L @Rm+, Rn_BANK */5.1055 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);5.1056 + CHECKPRIV();5.1057 + CHECKRALIGN32( sh4r.r[Rm] );5.1058 + sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );5.1059 + sh4r.r[Rm] += 4;5.1060 + }5.1061 + break;5.1062 + }5.1063 + break;5.1064 + case 0x8:5.1065 + switch( (ir&0xF0) >> 4 ) {5.1066 + case 0x0:5.1067 + { /* SHLL2 Rn */5.1068 + uint32_t Rn = ((ir>>8)&0xF);5.1069 + sh4r.r[Rn] <<= 2;5.1070 + }5.1071 + break;5.1072 + case 0x1:5.1073 + { /* SHLL8 Rn */5.1074 + uint32_t Rn = ((ir>>8)&0xF);5.1075 + sh4r.r[Rn] <<= 8;5.1076 + }5.1077 + break;5.1078 + case 0x2:5.1079 + { /* SHLL16 Rn */5.1080 + uint32_t Rn = ((ir>>8)&0xF);5.1081 + sh4r.r[Rn] <<= 16;5.1082 + }5.1083 + break;5.1084 + default:5.1085 + UNDEF();5.1086 + break;5.1087 + }5.1088 + break;5.1089 + case 0x9:5.1090 + switch( (ir&0xF0) >> 4 ) {5.1091 + case 0x0:5.1092 + { /* SHLR2 Rn */5.1093 + uint32_t Rn = ((ir>>8)&0xF);5.1094 + sh4r.r[Rn] >>= 2;5.1095 + }5.1096 + break;5.1097 + case 0x1:5.1098 + { /* SHLR8 Rn */5.1099 + uint32_t Rn = ((ir>>8)&0xF);5.1100 + sh4r.r[Rn] >>= 8;5.1101 + }5.1102 + break;5.1103 + case 0x2:5.1104 + { /* SHLR16 Rn */5.1105 + uint32_t Rn = ((ir>>8)&0xF);5.1106 + sh4r.r[Rn] >>= 16;5.1107 + }5.1108 + break;5.1109 + default:5.1110 + UNDEF();5.1111 + break;5.1112 + }5.1113 + break;5.1114 + case 0xA:5.1115 + switch( (ir&0xF0) >> 4 ) {5.1116 + case 0x0:5.1117 + { /* LDS Rm, MACH */5.1118 + uint32_t Rm = ((ir>>8)&0xF);5.1119 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |5.1120 + (((uint64_t)sh4r.r[Rm])<<32);5.1121 + }5.1122 + break;5.1123 + case 0x1:5.1124 + { /* LDS Rm, MACL */5.1125 + uint32_t Rm = ((ir>>8)&0xF);5.1126 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |5.1127 + (uint64_t)((uint32_t)(sh4r.r[Rm]));5.1128 + }5.1129 + break;5.1130 + case 0x2:5.1131 + { /* LDS Rm, PR */5.1132 + uint32_t Rm = ((ir>>8)&0xF);5.1133 + sh4r.pr = sh4r.r[Rm];5.1134 + }5.1135 + break;5.1136 + case 0x3:5.1137 + { /* LDC Rm, SGR */5.1138 + uint32_t Rm = ((ir>>8)&0xF);5.1139 + CHECKPRIV();5.1140 + sh4r.sgr = sh4r.r[Rm];5.1141 + }5.1142 + break;5.1143 + case 0x5:5.1144 + { /* LDS Rm, FPUL */5.1145 + uint32_t Rm = ((ir>>8)&0xF);5.1146 + sh4r.fpul = sh4r.r[Rm];5.1147 + }5.1148 + break;5.1149 + case 0x6:5.1150 + { /* LDS Rm, FPSCR */5.1151 + uint32_t Rm = ((ir>>8)&0xF);5.1152 + sh4r.fpscr = sh4r.r[Rm];5.1153 + }5.1154 + break;5.1155 + case 0xF:5.1156 + { /* LDC Rm, DBR */5.1157 + uint32_t Rm = ((ir>>8)&0xF);5.1158 + CHECKPRIV();5.1159 + sh4r.dbr = sh4r.r[Rm];5.1160 + }5.1161 + break;5.1162 + default:5.1163 + UNDEF();5.1164 + break;5.1165 + }5.1166 + break;5.1167 + case 0xB:5.1168 + switch( (ir&0xF0) >> 4 ) {5.1169 + case 0x0:5.1170 + { /* JSR @Rn */5.1171 + uint32_t Rn = ((ir>>8)&0xF);5.1172 + CHECKDEST( sh4r.r[Rn] );5.1173 + CHECKSLOTILLEGAL();5.1174 + sh4r.in_delay_slot = 1;5.1175 + sh4r.pc = sh4r.new_pc;5.1176 + sh4r.new_pc = sh4r.r[Rn];5.1177 + sh4r.pr = pc + 4;5.1178 + TRACE_CALL( pc, sh4r.new_pc );5.1179 + return TRUE;5.1180 + }5.1181 + break;5.1182 + case 0x1:5.1183 + { /* TAS.B @Rn */5.1184 + uint32_t Rn = ((ir>>8)&0xF);5.1185 + tmp = MEM_READ_BYTE( sh4r.r[Rn] );5.1186 + sh4r.t = ( tmp == 0 ? 1 : 0 );5.1187 + MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );5.1188 + }5.1189 + break;5.1190 + case 0x2:5.1191 + { /* JMP @Rn */5.1192 + uint32_t Rn = ((ir>>8)&0xF);5.1193 + CHECKDEST( sh4r.r[Rn] );5.1194 + CHECKSLOTILLEGAL();5.1195 + sh4r.in_delay_slot = 1;5.1196 + sh4r.pc = sh4r.new_pc;5.1197 + sh4r.new_pc = sh4r.r[Rn];5.1198 + return TRUE;5.1199 + }5.1200 + break;5.1201 + default:5.1202 + UNDEF();5.1203 + break;5.1204 + }5.1205 + break;5.1206 + case 0xC:5.1207 + { /* SHAD Rm, Rn */5.1208 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1209 + tmp = sh4r.r[Rm];5.1210 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);5.1211 + else if( (tmp & 0x1F) == 0 )5.1212 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;5.1213 + else5.1214 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);5.1215 + }5.1216 + break;5.1217 + case 0xD:5.1218 + { /* SHLD Rm, Rn */5.1219 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1220 + tmp = sh4r.r[Rm];5.1221 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);5.1222 + else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;5.1223 + else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);5.1224 + }5.1225 + break;5.1226 + case 0xE:5.1227 + switch( (ir&0x80) >> 7 ) {5.1228 + case 0x0:5.1229 + switch( (ir&0x70) >> 4 ) {5.1230 + case 0x0:5.1231 + { /* LDC Rm, SR */5.1232 + uint32_t Rm = ((ir>>8)&0xF);5.1233 + CHECKSLOTILLEGAL();5.1234 + CHECKPRIV();5.1235 + sh4_load_sr( sh4r.r[Rm] );5.1236 + }5.1237 + break;5.1238 + case 0x1:5.1239 + { /* LDC Rm, GBR */5.1240 + uint32_t Rm = ((ir>>8)&0xF);5.1241 + sh4r.gbr = sh4r.r[Rm];5.1242 + }5.1243 + break;5.1244 + case 0x2:5.1245 + { /* LDC Rm, VBR */5.1246 + uint32_t Rm = ((ir>>8)&0xF);5.1247 + CHECKPRIV();5.1248 + sh4r.vbr = sh4r.r[Rm];5.1249 + }5.1250 + break;5.1251 + case 0x3:5.1252 + { /* LDC Rm, SSR */5.1253 + uint32_t Rm = ((ir>>8)&0xF);5.1254 + CHECKPRIV();5.1255 + sh4r.ssr = sh4r.r[Rm];5.1256 + }5.1257 + break;5.1258 + case 0x4:5.1259 + { /* LDC Rm, SPC */5.1260 + uint32_t Rm = ((ir>>8)&0xF);5.1261 + CHECKPRIV();5.1262 + sh4r.spc = sh4r.r[Rm];5.1263 + }5.1264 + break;5.1265 + default:5.1266 + UNDEF();5.1267 + break;5.1268 + }5.1269 + break;5.1270 + case 0x1:5.1271 + { /* LDC Rm, Rn_BANK */5.1272 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);5.1273 + CHECKPRIV();5.1274 + sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];5.1275 + }5.1276 + break;5.1277 + }5.1278 + break;5.1279 + case 0xF:5.1280 + { /* MAC.W @Rm+, @Rn+ */5.1281 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1282 + CHECKRALIGN16( sh4r.r[Rn] );5.1283 + CHECKRALIGN16( sh4r.r[Rm] );5.1284 + int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));5.1285 + sh4r.r[Rn] += 2;5.1286 + stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));5.1287 + sh4r.r[Rm] += 2;5.1288 + if( sh4r.s ) {5.1289 + int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;5.1290 + if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {5.1291 + sh4r.mac = 0x000000017FFFFFFFLL;5.1292 + } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {5.1293 + sh4r.mac = 0x0000000180000000LL;5.1294 + } else {5.1295 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |5.1296 + ((uint32_t)(sh4r.mac + stmp));5.1297 + }5.1298 + } else {5.1299 + sh4r.mac += SIGNEXT32(stmp);5.1300 + }5.1301 + }5.1302 + break;5.1303 + }5.1304 + break;5.1305 + case 0x5:5.1306 + { /* MOV.L @(disp, Rm), Rn */5.1307 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;5.1308 + tmp = sh4r.r[Rm] + disp;5.1309 + CHECKRALIGN32( tmp );5.1310 + sh4r.r[Rn] = MEM_READ_LONG( tmp );5.1311 + }5.1312 + break;5.1313 + case 0x6:5.1314 + switch( ir&0xF ) {5.1315 + case 0x0:5.1316 + { /* MOV.B @Rm, Rn */5.1317 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1318 + sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] );5.1319 + }5.1320 + break;5.1321 + case 0x1:5.1322 + { /* MOV.W @Rm, Rn */5.1323 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1324 + CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] );5.1325 + }5.1326 + break;5.1327 + case 0x2:5.1328 + { /* MOV.L @Rm, Rn */5.1329 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1330 + CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] );5.1331 + }5.1332 + break;5.1333 + case 0x3:5.1334 + { /* MOV Rm, Rn */5.1335 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1336 + sh4r.r[Rn] = sh4r.r[Rm];5.1337 + }5.1338 + break;5.1339 + case 0x4:5.1340 + { /* MOV.B @Rm+, Rn */5.1341 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1342 + sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++;5.1343 + }5.1344 + break;5.1345 + case 0x5:5.1346 + { /* MOV.W @Rm+, Rn */5.1347 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1348 + CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2;5.1349 + }5.1350 + break;5.1351 + case 0x6:5.1352 + { /* MOV.L @Rm+, Rn */5.1353 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1354 + CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4;5.1355 + }5.1356 + break;5.1357 + case 0x7:5.1358 + { /* NOT Rm, Rn */5.1359 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1360 + sh4r.r[Rn] = ~sh4r.r[Rm];5.1361 + }5.1362 + break;5.1363 + case 0x8:5.1364 + { /* SWAP.B Rm, Rn */5.1365 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1366 + sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8);5.1367 + }5.1368 + break;5.1369 + case 0x9:5.1370 + { /* SWAP.W Rm, Rn */5.1371 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1372 + sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16);5.1373 + }5.1374 + break;5.1375 + case 0xA:5.1376 + { /* NEGC Rm, Rn */5.1377 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1378 + tmp = 0 - sh4r.r[Rm];5.1379 + sh4r.r[Rn] = tmp - sh4r.t;5.1380 + sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );5.1381 + }5.1382 + break;5.1383 + case 0xB:5.1384 + { /* NEG Rm, Rn */5.1385 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1386 + sh4r.r[Rn] = 0 - sh4r.r[Rm];5.1387 + }5.1388 + break;5.1389 + case 0xC:5.1390 + { /* EXTU.B Rm, Rn */5.1391 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1392 + sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF;5.1393 + }5.1394 + break;5.1395 + case 0xD:5.1396 + { /* EXTU.W Rm, Rn */5.1397 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1398 + sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF;5.1399 + }5.1400 + break;5.1401 + case 0xE:5.1402 + { /* EXTS.B Rm, Rn */5.1403 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1404 + sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF );5.1405 + }5.1406 + break;5.1407 + case 0xF:5.1408 + { /* EXTS.W Rm, Rn */5.1409 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1410 + sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF );5.1411 + }5.1412 + break;5.1413 + }5.1414 + break;5.1415 + case 0x7:5.1416 + { /* ADD #imm, Rn */5.1417 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);5.1418 + sh4r.r[Rn] += imm;5.1419 + }5.1420 + break;5.1421 + case 0x8:5.1422 + switch( (ir&0xF00) >> 8 ) {5.1423 + case 0x0:5.1424 + { /* MOV.B R0, @(disp, Rn) */5.1425 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);5.1426 + MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 );5.1427 + }5.1428 + break;5.1429 + case 0x1:5.1430 + { /* MOV.W R0, @(disp, Rn) */5.1431 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;5.1432 + tmp = sh4r.r[Rn] + disp;5.1433 + CHECKWALIGN16( tmp );5.1434 + MEM_WRITE_WORD( tmp, R0 );5.1435 + }5.1436 + break;5.1437 + case 0x4:5.1438 + { /* MOV.B @(disp, Rm), R0 */5.1439 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);5.1440 + R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp );5.1441 + }5.1442 + break;5.1443 + case 0x5:5.1444 + { /* MOV.W @(disp, Rm), R0 */5.1445 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;5.1446 + tmp = sh4r.r[Rm] + disp;5.1447 + CHECKRALIGN16( tmp );5.1448 + R0 = MEM_READ_WORD( tmp );5.1449 + }5.1450 + break;5.1451 + case 0x8:5.1452 + { /* CMP/EQ #imm, R0 */5.1453 + int32_t imm = SIGNEXT8(ir&0xFF);5.1454 + sh4r.t = ( R0 == imm ? 1 : 0 );5.1455 + }5.1456 + break;5.1457 + case 0x9:5.1458 + { /* BT disp */5.1459 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;5.1460 + CHECKSLOTILLEGAL();5.1461 + if( sh4r.t ) {5.1462 + CHECKDEST( sh4r.pc + disp + 4 )5.1463 + sh4r.pc += disp + 4;5.1464 + sh4r.new_pc = sh4r.pc + 2;5.1465 return TRUE;5.1466 - case 2: /* BRAF Rn */5.1467 - CHECKSLOTILLEGAL();5.1468 - CHECKDEST( pc + 4 + RN(ir) );5.1469 + }5.1470 + }5.1471 + break;5.1472 + case 0xB:5.1473 + { /* BF disp */5.1474 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;5.1475 + CHECKSLOTILLEGAL();5.1476 + if( !sh4r.t ) {5.1477 + CHECKDEST( sh4r.pc + disp + 4 )5.1478 + sh4r.pc += disp + 4;5.1479 + sh4r.new_pc = sh4r.pc + 2;5.1480 + return TRUE;5.1481 + }5.1482 + }5.1483 + break;5.1484 + case 0xD:5.1485 + { /* BT/S disp */5.1486 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;5.1487 + CHECKSLOTILLEGAL();5.1488 + if( sh4r.t ) {5.1489 + CHECKDEST( sh4r.pc + disp + 4 )5.1490 sh4r.in_delay_slot = 1;5.1491 sh4r.pc = sh4r.new_pc;5.1492 - sh4r.new_pc = pc + 4 + RN(ir);5.1493 + sh4r.new_pc = pc + disp + 4;5.1494 + sh4r.in_delay_slot = 1;5.1495 return TRUE;5.1496 - case 8: /* PREF [Rn] */5.1497 - tmp = RN(ir);5.1498 - if( (tmp & 0xFC000000) == 0xE0000000 ) {5.1499 - /* Store queue operation */5.1500 - int queue = (tmp&0x20)>>2;5.1501 - int32_t *src = &sh4r.store_queue[queue];5.1502 - uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;5.1503 - uint32_t target = tmp&0x03FFFFE0 | hi;5.1504 - mem_copy_to_sh4( target, src, 32 );5.1505 - }5.1506 - break;5.1507 - case 9: /* OCBI [Rn] */5.1508 - case 10:/* OCBP [Rn] */5.1509 - case 11:/* OCBWB [Rn] */5.1510 - /* anything? */5.1511 - break;5.1512 - case 12:/* MOVCA.L R0, [Rn] */5.1513 - tmp = RN(ir);5.1514 - CHECKWALIGN32(tmp);5.1515 - MEM_WRITE_LONG( tmp, R0 );5.1516 - break;5.1517 - default: UNDEF(ir);5.1518 - }5.1519 - break;5.1520 - case 4: /* MOV.B Rm, [R0 + Rn] */5.1521 - MEM_WRITE_BYTE( R0 + RN(ir), RM(ir) );5.1522 - break;5.1523 - case 5: /* MOV.W Rm, [R0 + Rn] */5.1524 - CHECKWALIGN16( R0 + RN(ir) );5.1525 - MEM_WRITE_WORD( R0 + RN(ir), RM(ir) );5.1526 - break;5.1527 - case 6: /* MOV.L Rm, [R0 + Rn] */5.1528 - CHECKWALIGN32( R0 + RN(ir) );5.1529 - MEM_WRITE_LONG( R0 + RN(ir), RM(ir) );5.1530 - break;5.1531 - case 7: /* MUL.L Rm, Rn */5.1532 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.1533 - (RM(ir) * RN(ir));5.1534 - break;5.1535 - case 8:5.1536 - switch( (ir&0x0FF0)>>4 ) {5.1537 - case 0: /* CLRT */5.1538 - sh4r.t = 0;5.1539 - break;5.1540 - case 1: /* SETT */5.1541 - sh4r.t = 1;5.1542 - break;5.1543 - case 2: /* CLRMAC */5.1544 - sh4r.mac = 0;5.1545 - break;5.1546 - case 3: /* LDTLB */5.1547 - break;5.1548 - case 4: /* CLRS */5.1549 - sh4r.s = 0;5.1550 - break;5.1551 - case 5: /* SETS */5.1552 - sh4r.s = 1;5.1553 - break;5.1554 - default: UNDEF(ir);5.1555 - }5.1556 - break;5.1557 - case 9:5.1558 - if( (ir&0x00F0) == 0x20 ) /* MOVT Rn */5.1559 - RN(ir) = sh4r.t;5.1560 - else if( ir == 0x0019 ) /* DIV0U */5.1561 - sh4r.m = sh4r.q = sh4r.t = 0;5.1562 - else if( ir == 0x0009 )5.1563 - /* NOP */;5.1564 - else UNDEF(ir);5.1565 - break;5.1566 - case 10:5.1567 - switch( (ir&0x00F0) >> 4 ) {5.1568 - case 0: /* STS MACH, Rn */5.1569 - RN(ir) = sh4r.mac >> 32;5.1570 - break;5.1571 - case 1: /* STS MACL, Rn */5.1572 - RN(ir) = (uint32_t)sh4r.mac;5.1573 - break;5.1574 - case 2: /* STS PR, Rn */5.1575 - RN(ir) = sh4r.pr;5.1576 - break;5.1577 - case 3: /* STC SGR, Rn */5.1578 - CHECKPRIV();5.1579 - RN(ir) = sh4r.sgr;5.1580 - break;5.1581 - case 5:/* STS FPUL, Rn */5.1582 - RN(ir) = sh4r.fpul;5.1583 - break;5.1584 - case 6: /* STS FPSCR, Rn */5.1585 - RN(ir) = sh4r.fpscr;5.1586 - break;5.1587 - case 15:/* STC DBR, Rn */5.1588 - CHECKPRIV();5.1589 - RN(ir) = sh4r.dbr;5.1590 - break;5.1591 - default: UNDEF(ir);5.1592 - }5.1593 - break;5.1594 - case 11:5.1595 - switch( (ir&0x0FF0)>>4 ) {5.1596 - case 0: /* RTS */5.1597 - CHECKSLOTILLEGAL();5.1598 - CHECKDEST( sh4r.pr );5.1599 + }5.1600 + }5.1601 + break;5.1602 + case 0xF:5.1603 + { /* BF/S disp */5.1604 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;5.1605 + CHECKSLOTILLEGAL();5.1606 + if( !sh4r.t ) {5.1607 + CHECKDEST( sh4r.pc + disp + 4 )5.1608 sh4r.in_delay_slot = 1;5.1609 sh4r.pc = sh4r.new_pc;5.1610 - sh4r.new_pc = sh4r.pr;5.1611 - TRACE_RETURN( pc, sh4r.new_pc );5.1612 + sh4r.new_pc = pc + disp + 4;5.1613 return TRUE;5.1614 - case 1: /* SLEEP */5.1615 - if( MMIO_READ( CPG, STBCR ) & 0x80 ) {5.1616 - sh4r.sh4_state = SH4_STATE_STANDBY;5.1617 - } else {5.1618 - sh4r.sh4_state = SH4_STATE_SLEEP;5.1619 - }5.1620 - return FALSE; /* Halt CPU */5.1621 - case 2: /* RTE */5.1622 - CHECKPRIV();5.1623 - CHECKDEST( sh4r.spc );5.1624 - CHECKSLOTILLEGAL();5.1625 - sh4r.in_delay_slot = 1;5.1626 - sh4r.pc = sh4r.new_pc;5.1627 - sh4r.new_pc = sh4r.spc;5.1628 - sh4_load_sr( sh4r.ssr );5.1629 - return TRUE;5.1630 - default:UNDEF(ir);5.1631 - }5.1632 - break;5.1633 - case 12:/* MOV.B [R0+R%d], R%d */5.1634 - RN(ir) = MEM_READ_BYTE( R0 + RM(ir) );5.1635 - break;5.1636 - case 13:/* MOV.W [R0+R%d], R%d */5.1637 - CHECKRALIGN16( R0 + RM(ir) );5.1638 - RN(ir) = MEM_READ_WORD( R0 + RM(ir) );5.1639 - break;5.1640 - case 14:/* MOV.L [R0+R%d], R%d */5.1641 - CHECKRALIGN32( R0 + RM(ir) );5.1642 - RN(ir) = MEM_READ_LONG( R0 + RM(ir) );5.1643 - break;5.1644 - case 15:/* MAC.L [Rm++], [Rn++] */5.1645 - CHECKRALIGN32( RM(ir) );5.1646 - CHECKRALIGN32( RN(ir) );5.1647 - tmpl = ( SIGNEXT32(MEM_READ_LONG(RM(ir))) *5.1648 - SIGNEXT32(MEM_READ_LONG(RN(ir))) );5.1649 - if( sh4r.s ) {5.1650 - /* 48-bit Saturation. Yuch */5.1651 - tmpl += SIGNEXT48(sh4r.mac);5.1652 - if( tmpl < 0xFFFF800000000000LL )5.1653 - tmpl = 0xFFFF800000000000LL;5.1654 - else if( tmpl > 0x00007FFFFFFFFFFFLL )5.1655 - tmpl = 0x00007FFFFFFFFFFFLL;5.1656 - sh4r.mac = (sh4r.mac&0xFFFF000000000000LL) |5.1657 - (tmpl&0x0000FFFFFFFFFFFFLL);5.1658 - } else sh4r.mac = tmpl;5.1659 -5.1660 - RM(ir) += 4;5.1661 - RN(ir) += 4;5.1662 -5.1663 - break;5.1664 - default: UNDEF(ir);5.1665 - }5.1666 - break;5.1667 - case 1: /* 0001nnnnmmmmdddd */5.1668 - /* MOV.L Rm, [Rn + disp4*4] */5.1669 - tmp = RN(ir) + (DISP4(ir)<<2);5.1670 - CHECKWALIGN32( tmp );5.1671 - MEM_WRITE_LONG( tmp, RM(ir) );5.1672 - break;5.1673 - case 2: /* 0010nnnnmmmmxxxx */5.1674 - switch( ir&0x000F ) {5.1675 - case 0: /* MOV.B Rm, [Rn] */5.1676 - MEM_WRITE_BYTE( RN(ir), RM(ir) );5.1677 - break;5.1678 - case 1: /* MOV.W Rm, [Rn] */5.1679 - CHECKWALIGN16( RN(ir) );5.1680 - MEM_WRITE_WORD( RN(ir), RM(ir) );5.1681 - break;5.1682 - case 2: /* MOV.L Rm, [Rn] */5.1683 - CHECKWALIGN32( RN(ir) );5.1684 - MEM_WRITE_LONG( RN(ir), RM(ir) );5.1685 - break;5.1686 - case 3: UNDEF(ir);5.1687 - break;5.1688 - case 4: /* MOV.B Rm, [--Rn] */5.1689 - RN(ir) --;5.1690 - MEM_WRITE_BYTE( RN(ir), RM(ir) );5.1691 - break;5.1692 - case 5: /* MOV.W Rm, [--Rn] */5.1693 - RN(ir) -= 2;5.1694 - CHECKWALIGN16( RN(ir) );5.1695 - MEM_WRITE_WORD( RN(ir), RM(ir) );5.1696 - break;5.1697 - case 6: /* MOV.L Rm, [--Rn] */5.1698 - RN(ir) -= 4;5.1699 - CHECKWALIGN32( RN(ir) );5.1700 - MEM_WRITE_LONG( RN(ir), RM(ir) );5.1701 - break;5.1702 - case 7: /* DIV0S Rm, Rn */5.1703 - sh4r.q = RN(ir)>>31;5.1704 - sh4r.m = RM(ir)>>31;5.1705 - sh4r.t = sh4r.q ^ sh4r.m;5.1706 - break;5.1707 - case 8: /* TST Rm, Rn */5.1708 - sh4r.t = (RN(ir)&RM(ir) ? 0 : 1);5.1709 - break;5.1710 - case 9: /* AND Rm, Rn */5.1711 - RN(ir) &= RM(ir);5.1712 - break;5.1713 - case 10:/* XOR Rm, Rn */5.1714 - RN(ir) ^= RM(ir);5.1715 - break;5.1716 - case 11:/* OR Rm, Rn */5.1717 - RN(ir) |= RM(ir);5.1718 - break;5.1719 - case 12:/* CMP/STR Rm, Rn */5.1720 - /* set T = 1 if any byte in RM & RN is the same */5.1721 - tmp = RM(ir) ^ RN(ir);5.1722 - sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||5.1723 - (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;5.1724 - break;5.1725 - case 13:/* XTRCT Rm, Rn */5.1726 - RN(ir) = (RN(ir)>>16) | (RM(ir)<<16);5.1727 - break;5.1728 - case 14:/* MULU.W Rm, Rn */5.1729 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.1730 - (uint32_t)((RM(ir)&0xFFFF) * (RN(ir)&0xFFFF));5.1731 - break;5.1732 - case 15:/* MULS.W Rm, Rn */5.1733 - sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |5.1734 - (uint32_t)(SIGNEXT32(RM(ir)&0xFFFF) * SIGNEXT32(RN(ir)&0xFFFF));5.1735 - break;5.1736 - }5.1737 - break;5.1738 - case 3: /* 0011nnnnmmmmxxxx */5.1739 - switch( ir&0x000F ) {5.1740 - case 0: /* CMP/EQ Rm, Rn */5.1741 - sh4r.t = ( RM(ir) == RN(ir) ? 1 : 0 );5.1742 - break;5.1743 - case 2: /* CMP/HS Rm, Rn */5.1744 - sh4r.t = ( RN(ir) >= RM(ir) ? 1 : 0 );5.1745 - break;5.1746 - case 3: /* CMP/GE Rm, Rn */5.1747 - sh4r.t = ( ((int32_t)RN(ir)) >= ((int32_t)RM(ir)) ? 1 : 0 );5.1748 - break;5.1749 - case 4: { /* DIV1 Rm, Rn */5.1750 - /* This is just from the sh4p manual with some5.1751 - * simplifications (someone want to check it's correct? :)5.1752 - * Why they couldn't just provide a real DIV instruction...5.1753 - * Please oh please let the translator batch these things5.1754 - * up into a single DIV... */5.1755 - uint32_t tmp0, tmp1, tmp2, dir;5.1756 + }5.1757 + }5.1758 + break;5.1759 + default:5.1760 + UNDEF();5.1761 + break;5.1762 + }5.1763 + break;5.1764 + case 0x9:5.1765 + { /* MOV.W @(disp, PC), Rn */5.1766 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;5.1767 + CHECKSLOTILLEGAL();5.1768 + tmp = pc + 4 + disp;5.1769 + sh4r.r[Rn] = MEM_READ_WORD( tmp );5.1770 + }5.1771 + break;5.1772 + case 0xA:5.1773 + { /* BRA disp */5.1774 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;5.1775 + CHECKSLOTILLEGAL();5.1776 + CHECKDEST( sh4r.pc + disp + 4 );5.1777 + sh4r.in_delay_slot = 1;5.1778 + sh4r.pc = sh4r.new_pc;5.1779 + sh4r.new_pc = pc + 4 + disp;5.1780 + return TRUE;5.1781 + }5.1782 + break;5.1783 + case 0xB:5.1784 + { /* BSR disp */5.1785 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;5.1786 + CHECKDEST( sh4r.pc + disp + 4 );5.1787 + CHECKSLOTILLEGAL();5.1788 + sh4r.in_delay_slot = 1;5.1789 + sh4r.pr = pc + 4;5.1790 + sh4r.pc = sh4r.new_pc;5.1791 + sh4r.new_pc = pc + 4 + disp;5.1792 + TRACE_CALL( pc, sh4r.new_pc );5.1793 + return TRUE;5.1794 + }5.1795 + break;5.1796 + case 0xC:5.1797 + switch( (ir&0xF00) >> 8 ) {5.1798 + case 0x0:5.1799 + { /* MOV.B R0, @(disp, GBR) */5.1800 + uint32_t disp = (ir&0xFF);5.1801 + MEM_WRITE_BYTE( sh4r.gbr + disp, R0 );5.1802 + }5.1803 + break;5.1804 + case 0x1:5.1805 + { /* MOV.W R0, @(disp, GBR) */5.1806 + uint32_t disp = (ir&0xFF)<<1;5.1807 + tmp = sh4r.gbr + disp;5.1808 + CHECKWALIGN16( tmp );5.1809 + MEM_WRITE_WORD( tmp, R0 );5.1810 + }5.1811 + break;5.1812 + case 0x2:5.1813 + { /* MOV.L R0, @(disp, GBR) */5.1814 + uint32_t disp = (ir&0xFF)<<2;5.1815 + tmp = sh4r.gbr + disp;5.1816 + CHECKWALIGN32( tmp );5.1817 + MEM_WRITE_LONG( tmp, R0 );5.1818 + }5.1819 + break;5.1820 + case 0x3:5.1821 + { /* TRAPA #imm */5.1822 + uint32_t imm = (ir&0xFF);5.1823 + CHECKSLOTILLEGAL();5.1824 + MMIO_WRITE( MMU, TRA, imm<<2 );5.1825 + sh4r.pc += 2;5.1826 + sh4_raise_exception( EXC_TRAP );5.1827 + }5.1828 + break;5.1829 + case 0x4:5.1830 + { /* MOV.B @(disp, GBR), R0 */5.1831 + uint32_t disp = (ir&0xFF);5.1832 + R0 = MEM_READ_BYTE( sh4r.gbr + disp );5.1833 + }5.1834 + break;5.1835 + case 0x5:5.1836 + { /* MOV.W @(disp, GBR), R0 */5.1837 + uint32_t disp = (ir&0xFF)<<1;5.1838 + tmp = sh4r.gbr + disp;5.1839 + CHECKRALIGN16( tmp );5.1840 + R0 = MEM_READ_WORD( tmp );5.1841 + }5.1842 + break;5.1843 + case 0x6:5.1844 + { /* MOV.L @(disp, GBR), R0 */5.1845 + uint32_t disp = (ir&0xFF)<<2;5.1846 + tmp = sh4r.gbr + disp;5.1847 + CHECKRALIGN32( tmp );5.1848 + R0 = MEM_READ_LONG( tmp );5.1849 + }5.1850 + break;5.1851 + case 0x7:5.1852 + { /* MOVA @(disp, PC), R0 */5.1853 + uint32_t disp = (ir&0xFF)<<2;5.1854 + CHECKSLOTILLEGAL();5.1855 + R0 = (pc&0xFFFFFFFC) + disp + 4;5.1856 + }5.1857 + break;5.1858 + case 0x8:5.1859 + { /* TST #imm, R0 */5.1860 + uint32_t imm = (ir&0xFF);5.1861 + sh4r.t = (R0 & imm ? 0 : 1);5.1862 + }5.1863 + break;5.1864 + case 0x9:5.1865 + { /* AND #imm, R0 */5.1866 + uint32_t imm = (ir&0xFF);5.1867 + R0 &= imm;5.1868 + }5.1869 + break;5.1870 + case 0xA:5.1871 + { /* XOR #imm, R0 */5.1872 + uint32_t imm = (ir&0xFF);5.1873 + R0 ^= imm;5.1874 + }5.1875 + break;5.1876 + case 0xB:5.1877 + { /* OR #imm, R0 */5.1878 + uint32_t imm = (ir&0xFF);5.1879 + R0 |= imm;5.1880 + }5.1881 + break;5.1882 + case 0xC:5.1883 + { /* TST.B #imm, @(R0, GBR) */5.1884 + uint32_t imm = (ir&0xFF);5.1885 + sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 );5.1886 + }5.1887 + break;5.1888 + case 0xD:5.1889 + { /* AND.B #imm, @(R0, GBR) */5.1890 + uint32_t imm = (ir&0xFF);5.1891 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) );5.1892 + }5.1893 + break;5.1894 + case 0xE:5.1895 + { /* XOR.B #imm, @(R0, GBR) */5.1896 + uint32_t imm = (ir&0xFF);5.1897 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) );5.1898 + }5.1899 + break;5.1900 + case 0xF:5.1901 + { /* OR.B #imm, @(R0, GBR) */5.1902 + uint32_t imm = (ir&0xFF);5.1903 + MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) );5.1904 + }5.1905 + break;5.1906 + }5.1907 + break;5.1908 + case 0xD:5.1909 + { /* MOV.L @(disp, PC), Rn */5.1910 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;5.1911 + CHECKSLOTILLEGAL();5.1912 + tmp = (pc&0xFFFFFFFC) + disp + 4;5.1913 + sh4r.r[Rn] = MEM_READ_LONG( tmp );5.1914 + }5.1915 + break;5.1916 + case 0xE:5.1917 + { /* MOV #imm, Rn */5.1918 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);5.1919 + sh4r.r[Rn] = imm;5.1920 + }5.1921 + break;5.1922 + case 0xF:5.1923 + switch( ir&0xF ) {5.1924 + case 0x0:5.1925 + { /* FADD FRm, FRn */5.1926 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1927 + CHECKFPUEN();5.1928 + if( IS_FPU_DOUBLEPREC() ) {5.1929 + DR(FRn) += DR(FRm);5.1930 + } else {5.1931 + FR(FRn) += FR(FRm);5.1932 + }5.1933 + }5.1934 + break;5.1935 + case 0x1:5.1936 + { /* FSUB FRm, FRn */5.1937 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1938 + CHECKFPUEN();5.1939 + if( IS_FPU_DOUBLEPREC() ) {5.1940 + DR(FRn) -= DR(FRm);5.1941 + } else {5.1942 + FR(FRn) -= FR(FRm);5.1943 + }5.1944 + }5.1945 + break;5.1946 + case 0x2:5.1947 + { /* FMUL FRm, FRn */5.1948 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1949 + CHECKFPUEN();5.1950 + if( IS_FPU_DOUBLEPREC() ) {5.1951 + DR(FRn) *= DR(FRm);5.1952 + } else {5.1953 + FR(FRn) *= FR(FRm);5.1954 + }5.1955 + }5.1956 + break;5.1957 + case 0x3:5.1958 + { /* FDIV FRm, FRn */5.1959 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1960 + CHECKFPUEN();5.1961 + if( IS_FPU_DOUBLEPREC() ) {5.1962 + DR(FRn) /= DR(FRm);5.1963 + } else {5.1964 + FR(FRn) /= FR(FRm);5.1965 + }5.1966 + }5.1967 + break;5.1968 + case 0x4:5.1969 + { /* FCMP/EQ FRm, FRn */5.1970 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1971 + CHECKFPUEN();5.1972 + if( IS_FPU_DOUBLEPREC() ) {5.1973 + sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );5.1974 + } else {5.1975 + sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );5.1976 + }5.1977 + }5.1978 + break;5.1979 + case 0x5:5.1980 + { /* FCMP/GT FRm, FRn */5.1981 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1982 + CHECKFPUEN();5.1983 + if( IS_FPU_DOUBLEPREC() ) {5.1984 + sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );5.1985 + } else {5.1986 + sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );5.1987 + }5.1988 + }5.1989 + break;5.1990 + case 0x6:5.1991 + { /* FMOV @(R0, Rm), FRn */5.1992 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.1993 + MEM_FP_READ( sh4r.r[Rm] + R0, FRn );5.1994 + }5.1995 + break;5.1996 + case 0x7:5.1997 + { /* FMOV FRm, @(R0, Rn) */5.1998 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.1999 + MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm );5.2000 + }5.2001 + break;5.2002 + case 0x8:5.2003 + { /* FMOV @Rm, FRn */5.2004 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.2005 + MEM_FP_READ( sh4r.r[Rm], FRn );5.2006 + }5.2007 + break;5.2008 + case 0x9:5.2009 + { /* FMOV @Rm+, FRn */5.2010 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);5.2011 + MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH;5.2012 + }5.2013 + break;5.2014 + case 0xA:5.2015 + { /* FMOV FRm, @Rn */5.2016 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.2017 + MEM_FP_WRITE( sh4r.r[Rn], FRm );5.2018 + }5.2019 + break;5.2020 + case 0xB:5.2021 + { /* FMOV FRm, @-Rn */5.2022 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.2023 + sh4r.r[Rn] -= FP_WIDTH; MEM_FP_WRITE( sh4r.r[Rn], FRm );5.2024 + }5.2025 + break;5.2026 + case 0xC:5.2027 + { /* FMOV FRm, FRn */5.2028 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.2029 + if( IS_FPU_DOUBLESIZE() )5.2030 + DR(FRn) = DR(FRm);5.2031 + else5.2032 + FR(FRn) = FR(FRm);5.2033 + }5.2034 + break;5.2035 + case 0xD:5.2036 + switch( (ir&0xF0) >> 4 ) {5.2037 + case 0x0:5.2038 + { /* FSTS FPUL, FRn */5.2039 + uint32_t FRn = ((ir>>8)&0xF);5.2040 + CHECKFPUEN(); FR(FRn) = FPULf;5.2041 + }5.2042 + break;5.2043 + case 0x1:5.2044 + { /* FLDS FRm, FPUL */5.2045 + uint32_t FRm = ((ir>>8)&0xF);5.2046 + CHECKFPUEN(); FPULf = FR(FRm);5.2047 + }5.2048 + break;5.2049 + case 0x2:5.2050 + { /* FLOAT FPUL, FRn */5.2051 + uint32_t FRn = ((ir>>8)&0xF);5.2052 + CHECKFPUEN();5.2053 + if( IS_FPU_DOUBLEPREC() )5.2054 + DR(FRn) = (float)FPULi;5.2055 + else5.2056 + FR(FRn) = (float)FPULi;5.2057 + }5.2058 + break;5.2059 + case 0x3:5.2060 + { /* FTRC FRm, FPUL */5.2061 + uint32_t FRm = ((ir>>8)&0xF);5.2062 + CHECKFPUEN();5.2063 + if( IS_FPU_DOUBLEPREC() ) {5.2064 + dtmp = DR(FRm);5.2065 + if( dtmp >= MAX_INTF )5.2066 + FPULi = MAX_INT;5.2067 + else if( dtmp <= MIN_INTF )5.2068 + FPULi = MIN_INT;5.2069 + else5.2070 + FPULi = (int32_t)dtmp;5.2071 + } else {5.2072 + ftmp = FR(FRm);5.2073 + if( ftmp >= MAX_INTF )5.2074 + FPULi = MAX_INT;5.2075 + else if( ftmp <= MIN_INTF )5.2076 + FPULi = MIN_INT;5.2077 + else5.2078 + FPULi = (int32_t)ftmp;5.2079 + }5.2080 + }5.2081 + break;5.2082 + case 0x4:5.2083 + { /* FNEG FRn */5.2084 + uint32_t FRn = ((ir>>8)&0xF);5.2085 + CHECKFPUEN();5.2086 + if( IS_FPU_DOUBLEPREC() ) {5.2087 + DR(FRn) = -DR(FRn);5.2088 + } else {5.2089 + FR(FRn) = -FR(FRn);5.2090 + }5.2091 + }5.2092 + break;5.2093 + case 0x5:5.2094 + { /* FABS FRn */5.2095 + uint32_t FRn = ((ir>>8)&0xF);5.2096 + CHECKFPUEN();5.2097 + if( IS_FPU_DOUBLEPREC() ) {5.2098 + DR(FRn) = fabs(DR(FRn));5.2099 + } else {5.2100 + FR(FRn) = fabsf(FR(FRn));5.2101 + }5.2102 + }5.2103 + break;5.2104 + case 0x6:5.2105 + { /* FSQRT FRn */5.2106 + uint32_t FRn = ((ir>>8)&0xF);5.2107 + CHECKFPUEN();5.2108 + if( IS_FPU_DOUBLEPREC() ) {5.2109 + DR(FRn) = sqrt(DR(FRn));5.2110 + } else {5.2111 + FR(FRn) = sqrtf(FR(FRn));5.2112 + }5.2113 + }5.2114 + break;5.2115 + case 0x7:5.2116 + { /* FSRRA FRn */5.2117 + uint32_t FRn = ((ir>>8)&0xF);5.2118 + CHECKFPUEN();5.2119 + if( !IS_FPU_DOUBLEPREC() ) {5.2120 + FR(FRn) = 1.0/sqrtf(FR(FRn));5.2121 + }5.2122 + }5.2123 + break;5.2124 + case 0x8:5.2125 + { /* FLDI0 FRn */5.2126 + uint32_t FRn = ((ir>>8)&0xF);5.2127 + CHECKFPUEN();5.2128 + if( IS_FPU_DOUBLEPREC() ) {5.2129 + DR(FRn) = 0.0;5.2130 + } else {5.2131 + FR(FRn) = 0.0;5.2132 + }5.2133 + }5.2134 + break;5.2135 + case 0x9:5.2136 + { /* FLDI1 FRn */5.2137 + uint32_t FRn = ((ir>>8)&0xF);5.2138 + CHECKFPUEN();5.2139 + if( IS_FPU_DOUBLEPREC() ) {5.2140 + DR(FRn) = 1.0;5.2141 + } else {5.2142 + FR(FRn) = 1.0;5.2143 + }5.2144 + }5.2145 + break;5.2146 + case 0xA:5.2147 + { /* FCNVSD FPUL, FRn */5.2148 + uint32_t FRn = ((ir>>8)&0xF);5.2149 + CHECKFPUEN();5.2150 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {5.2151 + DR(FRn) = (double)FPULf;5.2152 + }5.2153 + }5.2154 + break;5.2155 + case 0xB:5.2156 + { /* FCNVDS FRm, FPUL */5.2157 + uint32_t FRm = ((ir>>8)&0xF);5.2158 + CHECKFPUEN();5.2159 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {5.2160 + FPULf = (float)DR(FRm);5.2161 + }5.2162 + }5.2163 + break;5.2164 + case 0xE:5.2165 + { /* FIPR FVm, FVn */5.2166 + uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);5.2167 + CHECKFPUEN();5.2168 + if( !IS_FPU_DOUBLEPREC() ) {5.2169 + int tmp2 = FVn<<2;5.2170 + tmp = FVm<<2;5.2171 + FR(tmp2+3) = FR(tmp)*FR(tmp2) +5.2172 + FR(tmp+1)*FR(tmp2+1) +5.2173 + FR(tmp+2)*FR(tmp2+2) +5.2174 + FR(tmp+3)*FR(tmp2+3);5.2175 + }5.2176 + }5.2177 + break;5.2178 + case 0xF:5.2179 + switch( (ir&0x100) >> 8 ) {5.2180 + case 0x0:5.2181 + { /* FSCA FPUL, FRn */5.2182 + uint32_t FRn = ((ir>>9)&0x7)<<1;5.2183 + CHECKFPUEN();5.2184 + if( !IS_FPU_DOUBLEPREC() ) {5.2185 + float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;5.2186 + FR(FRn) = sinf(angle);5.2187 + FR((FRn)+1) = cosf(angle);5.2188 + }5.2189 + }5.2190 + break;5.2191 + case 0x1:5.2192 + switch( (ir&0x200) >> 9 ) {5.2193 + case 0x0:5.2194 + { /* FTRV XMTRX, FVn */5.2195 + uint32_t FVn = ((ir>>10)&0x3);5.2196 + CHECKFPUEN();5.2197 + if( !IS_FPU_DOUBLEPREC() ) {5.2198 + tmp = FVn<<2;5.2199 + float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };5.2200 + FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +5.2201 + XF(8)*fv[2] + XF(12)*fv[3];5.2202 + FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +5.2203 + XF(9)*fv[2] + XF(13)*fv[3];5.2204 + FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +5.2205 + XF(10)*fv[2] + XF(14)*fv[3];5.2206 + FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +5.2207 + XF(11)*fv[2] + XF(15)*fv[3];5.2208 + }5.2209 + }5.2210 + break;5.2211 + case 0x1:5.2212 + switch( (ir&0xC00) >> 10 ) {5.2213 + case 0x0:5.2214 + { /* FSCHG */5.2215 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ;5.2216 + }5.2217 + break;5.2218 + case 0x2:5.2219 + { /* FRCHG */5.2220 + CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR;5.2221 + }5.2222 + break;5.2223 + case 0x3:5.2224 + { /* UNDEF */5.2225 + UNDEF(ir);5.2226 + }5.2227 + break;5.2228 + default:5.2229 + UNDEF();5.2230 + break;5.2231 + }5.2232 + break;5.2233 + }5.2234 + break;5.2235 + }5.2236 + break;5.2237 + default:5.2238 + UNDEF();5.2239 + break;5.2240 + }5.2241 + break;5.2242 + case 0xE:5.2243 + { /* FMAC FR0, FRm, FRn */5.2244 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);5.2245 + CHECKFPUEN();5.2246 + if( IS_FPU_DOUBLEPREC() ) {5.2247 + DR(FRn) += DR(FRm)*DR(0);5.2248 + } else {5.2249 + FR(FRn) += FR(FRm)*FR(0);5.2250 + }5.2251 + }5.2252 + break;5.2253 + default:5.2254 + UNDEF();5.2255 + break;5.2256 + }5.2257 + break;5.2258 + }5.2260 - dir = sh4r.q ^ sh4r.m;5.2261 - sh4r.q = (RN(ir) >> 31);5.2262 - tmp2 = RM(ir);5.2263 - RN(ir) = (RN(ir) << 1) | sh4r.t;5.2264 - tmp0 = RN(ir);5.2265 - if( dir ) {5.2266 - RN(ir) += tmp2;5.2267 - tmp1 = (RN(ir)<tmp0 ? 1 : 0 );5.2268 - } else {5.2269 - RN(ir) -= tmp2;5.2270 - tmp1 = (RN(ir)>tmp0 ? 1 : 0 );5.2271 - }5.2272 - sh4r.q ^= sh4r.m ^ tmp1;5.2273 - sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );5.2274 - break; }5.2275 - case 5: /* DMULU.L Rm, Rn */5.2276 - sh4r.mac = ((uint64_t)RM(ir)) * ((uint64_t)RN(ir));5.2277 - break;5.2278 - case 6: /* CMP/HI Rm, Rn */5.2279 - sh4r.t = ( RN(ir) > RM(ir) ? 1 : 0 );5.2280 - break;5.2281 - case 7: /* CMP/GT Rm, Rn */5.2282 - sh4r.t = ( ((int32_t)RN(ir)) > ((int32_t)RM(ir)) ? 1 : 0 );5.2283 - break;5.2284 - case 8: /* SUB Rm, Rn */5.2285 - RN(ir) -= RM(ir);5.2286 - break;5.2287 - case 10:/* SUBC Rm, Rn */5.2288 - tmp = RN(ir);5.2289 - RN(ir) = RN(ir) - RM(ir) - sh4r.t;5.2290 - sh4r.t = (RN(ir) > tmp || (RN(ir) == tmp && sh4r.t == 1));5.2291 - break;5.2292 - case 11:/* SUBV Rm, Rn */5.2293 - UNIMP(ir);5.2294 - break;5.2295 - case 12:/* ADD Rm, Rn */5.2296 - RN(ir) += RM(ir);5.2297 - break;5.2298 - case 13:/* DMULS.L Rm, Rn */5.2299 - sh4r.mac = SIGNEXT32(RM(ir)) * SIGNEXT32(RN(ir));5.2300 - break;5.2301 - case 14:/* ADDC Rm, Rn */5.2302 - tmp = RN(ir);5.2303 - RN(ir) += RM(ir) + sh4r.t;5.2304 - sh4r.t = ( RN(ir) < tmp || (RN(ir) == tmp && sh4r.t != 0) ? 1 : 0 );5.2305 - break;5.2306 - case 15:/* ADDV Rm, Rn */5.2307 - tmp = RN(ir) + RM(ir);5.2308 - sh4r.t = ( (RN(ir)>>31) == (RM(ir)>>31) && ((RN(ir)>>31) != (tmp>>31)) );5.2309 - RN(ir) = tmp;5.2310 - break;5.2311 - default: UNDEF(ir);5.2312 - }5.2313 - break;5.2314 - case 4: /* 0100nnnnxxxxxxxx */5.2315 - switch( ir&0x00FF ) {5.2316 - case 0x00: /* SHLL Rn */5.2317 - sh4r.t = RN(ir) >> 31;5.2318 - RN(ir) <<= 1;5.2319 - break;5.2320 - case 0x01: /* SHLR Rn */5.2321 - sh4r.t = RN(ir) & 0x00000001;5.2322 - RN(ir) >>= 1;5.2323 - break;5.2324 - case 0x02: /* STS.L MACH, [--Rn] */5.2325 - RN(ir) -= 4;5.2326 - CHECKWALIGN32( RN(ir) );5.2327 - MEM_WRITE_LONG( RN(ir), (sh4r.mac>>32) );5.2328 - break;5.2329 - case 0x03: /* STC.L SR, [--Rn] */5.2330 - CHECKPRIV();5.2331 - RN(ir) -= 4;5.2332 - CHECKWALIGN32( RN(ir) );5.2333 - MEM_WRITE_LONG( RN(ir), sh4_read_sr() );5.2334 - break;5.2335 - case 0x04: /* ROTL Rn */5.2336 - sh4r.t = RN(ir) >> 31;5.2337 - RN(ir) <<= 1;5.2338 - RN(ir) |= sh4r.t;5.2339 - break;5.2340 - case 0x05: /* ROTR Rn */5.2341 - sh4r.t = RN(ir) & 0x00000001;5.2342 - RN(ir) >>= 1;5.2343 - RN(ir) |= (sh4r.t << 31);5.2344 - break;5.2345 - case 0x06: /* LDS.L [Rn++], MACH */5.2346 - CHECKRALIGN32( RN(ir) );5.2347 - sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |5.2348 - (((uint64_t)MEM_READ_LONG(RN(ir)))<<32);5.2349 - RN(ir) += 4;5.2350 - break;5.2351 - case 0x07: /* LDC.L [Rn++], SR */5.2352 - CHECKSLOTILLEGAL();5.2353 - CHECKPRIV();5.2354 - CHECKWALIGN32( RN(ir) );5.2355 - sh4_load_sr( MEM_READ_LONG(RN(ir)) );5.2356 - RN(ir) +=4;5.2357 - break;5.2358 - case 0x08: /* SHLL2 Rn */5.2359 - RN(ir) <<= 2;5.2360 - break;5.2361 - case 0x09: /* SHLR2 Rn */5.2362 - RN(ir) >>= 2;5.2363 - break;5.2364 - case 0x0A: /* LDS Rn, MACH */5.2365 - sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |5.2366 - (((uint64_t)RN(ir))<<32);5.2367 - break;5.2368 - case 0x0B: /* JSR [Rn] */5.2369 - CHECKDEST( RN(ir) );5.2370 - CHECKSLOTILLEGAL();5.2371 - sh4r.in_delay_slot = 1;5.2372 - sh4r.pc = sh4r.new_pc;5.2373 - sh4r.new_pc = RN(ir);5.2374 - sh4r.pr = pc + 4;5.2375 - TRACE_CALL( pc, sh4r.new_pc );5.2376 - return TRUE;5.2377 - case 0x0E: /* LDC Rn, SR */5.2378 - CHECKSLOTILLEGAL();5.2379 - CHECKPRIV();5.2380 - sh4_load_sr( RN(ir) );5.2381 - break;5.2382 - case 0x10: /* DT Rn */5.2383 - RN(ir) --;5.2384 - sh4r.t = ( RN(ir) == 0 ? 1 : 0 );5.2385 - break;5.2386 - case 0x11: /* CMP/PZ Rn */5.2387 - sh4r.t = ( ((int32_t)RN(ir)) >= 0 ? 1 : 0 );5.2388 - break;5.2389 - case 0x12: /* STS.L MACL, [--Rn] */5.2390 - RN(ir) -= 4;5.2391 - CHECKWALIGN32( RN(ir) );5.2392 - MEM_WRITE_LONG( RN(ir), (uint32_t)sh4r.mac );5.2393 - break;5.2394 - case 0x13: /* STC.L GBR, [--Rn] */5.2395 - RN(ir) -= 4;5.2396 - CHECKWALIGN32( RN(ir) );5.2397 - MEM_WRITE_LONG( RN(ir), sh4r.gbr );5.2398 - break;5.2399 - case 0x15: /* CMP/PL Rn */5.2400 - sh4r.t = ( ((int32_t)RN(ir)) > 0 ? 1 : 0 );5.2401 - break;5.2402 - case 0x16: /* LDS.L [Rn++], MACL */5.2403 - CHECKRALIGN32( RN(ir) );5.2404 - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |5.2405 - (uint64_t)((uint32_t)MEM_READ_LONG(RN(ir)));5.2406 - RN(ir) += 4;5.2407 - break;5.2408 - case 0x17: /* LDC.L [Rn++], GBR */5.2409 - CHECKRALIGN32( RN(ir) );5.2410 - sh4r.gbr = MEM_READ_LONG(RN(ir));5.2411 - RN(ir) +=4;5.2412 - break;5.2413 - case 0x18: /* SHLL8 Rn */5.2414 - RN(ir) <<= 8;5.2415 - break;5.2416 - case 0x19: /* SHLR8 Rn */5.2417 - RN(ir) >>= 8;5.2418 - break;5.2419 - case 0x1A: /* LDS Rn, MACL */5.2420 - sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |5.2421 - (uint64_t)((uint32_t)(RN(ir)));5.2422 - break;5.2423 - case 0x1B: /* TAS.B [Rn] */5.2424 - tmp = MEM_READ_BYTE( RN(ir) );5.2425 - sh4r.t = ( tmp == 0 ? 1 : 0 );5.2426 - MEM_WRITE_BYTE( RN(ir), tmp | 0x80 );5.2427 - break;5.2428 - case 0x1E: /* LDC Rn, GBR */5.2429 - sh4r.gbr = RN(ir);5.2430 - break;5.2431 - case 0x20: /* SHAL Rn */5.2432 - sh4r.t = RN(ir) >> 31;5.2433 - RN(ir) <<= 1;5.2434 - break;5.2435 - case 0x21: /* SHAR Rn */5.2436 - sh4r.t = RN(ir) & 0x00000001;5.2437 - RN(ir) = ((int32_t)RN(ir)) >> 1;5.2438 - break;5.2439 - case 0x22: /* STS.L PR, [--Rn] */5.2440 - RN(ir) -= 4;5.2441 - CHECKWALIGN32( RN(ir) );5.2442 - MEM_WRITE_LONG( RN(ir), sh4r.pr );5.2443 - break;5.2444 - case 0x23: /* STC.L VBR, [--Rn] */5.2445 - CHECKPRIV();5.2446 - RN(ir) -= 4;5.2447 - CHECKWALIGN32( RN(ir) );5.2448 - MEM_WRITE_LONG( RN(ir), sh4r.vbr );5.2449 - break;5.2450 - case 0x24: /* ROTCL Rn */5.2451 - tmp = RN(ir) >> 31;5.2452 - RN(ir) <<= 1;5.2453 - RN(ir) |= sh4r.t;5.2454 - sh4r.t = tmp;5.2455 - break;5.2456 - case 0x25: /* ROTCR Rn */5.2457 - tmp = RN(ir) & 0x00000001;5.2458 - RN(ir) >>= 1;5.2459 - RN(ir) |= (sh4r.t << 31 );5.2460 - sh4r.t = tmp;5.2461 - break;5.2462 - case 0x26: /* LDS.L [Rn++], PR */5.2463 - CHECKRALIGN32( RN(ir) );5.2464 - sh4r.pr = MEM_READ_LONG( RN(ir) );5.2465 - RN(ir) += 4;5.2466 - break;5.2467 - case 0x27: /* LDC.L [Rn++], VBR */5.2468 - CHECKPRIV();5.2469 - CHECKRALIGN32( RN(ir) );5.2470 - sh4r.vbr = MEM_READ_LONG(RN(ir));5.2471 - RN(ir) +=4;5.2472 - break;5.2473 - case 0x28: /* SHLL16 Rn */5.2474 - RN(ir) <<= 16;5.2475 - break;5.2476 - case 0x29: /* SHLR16 Rn */5.2477 - RN(ir) >>= 16;5.2478 - break;5.2479 - case 0x2A: /* LDS Rn, PR */5.2480 - sh4r.pr = RN(ir);5.2481 - break;5.2482 - case 0x2B: /* JMP [Rn] */5.2483 - CHECKDEST( RN(ir) );5.2484 - CHECKSLOTILLEGAL();5.2485 - sh4r.in_delay_slot = 1;5.2486 - sh4r.pc = sh4r.new_pc;5.2487 - sh4r.new_pc = RN(ir);5.2488 - return TRUE;5.2489 - case 0x2E: /* LDC Rn, VBR */5.2490 - CHECKPRIV();5.2491 - sh4r.vbr = RN(ir);5.2492 - break;5.2493 - case 0x32: /* STC.L SGR, [--Rn] */5.2494 - CHECKPRIV();5.2495 - RN(ir) -= 4;5.2496 - CHECKWALIGN32( RN(ir) );5.2497 - MEM_WRITE_LONG( RN(ir), sh4r.sgr );5.2498 - break;5.2499 - case 0x33: /* STC.L SSR, [--Rn] */5.2500 - CHECKPRIV();5.2501 - RN(ir) -= 4;5.2502 - CHECKWALIGN32( RN(ir) );5.2503 - MEM_WRITE_LONG( RN(ir), sh4r.ssr );5.2504 - break;5.2505 - case 0x37: /* LDC.L [Rn++], SSR */5.2506 - CHECKPRIV();5.2507 - CHECKRALIGN32( RN(ir) );5.2508 - sh4r.ssr = MEM_READ_LONG(RN(ir));5.2509 - RN(ir) +=4;5.2510 - break;5.2511 - case 0x3E: /* LDC Rn, SSR */5.2512 - CHECKPRIV();5.2513 - sh4r.ssr = RN(ir);5.2514 - break;5.2515 - case 0x43: /* STC.L SPC, [--Rn] */5.2516 - CHECKPRIV();5.2517 - RN(ir) -= 4;5.2518 - CHECKWALIGN32( RN(ir) );5.2519 - MEM_WRITE_LONG( RN(ir), sh4r.spc );5.2520 - break;5.2521 - case 0x47: /* LDC.L [Rn++], SPC */5.2522 - CHECKPRIV();5.2523 - CHECKRALIGN32( RN(ir) );5.2524 - sh4r.spc = MEM_READ_LONG(RN(ir));5.2525 - RN(ir) +=4;5.2526 - break;5.2527 - case 0x4E: /* LDC Rn, SPC */5.2528 - CHECKPRIV();5.2529 - sh4r.spc = RN(ir);5.2530 - break;5.2531 - case 0x52: /* STS.L FPUL, [--Rn] */5.2532 - RN(ir) -= 4;5.2533 - CHECKWALIGN32( RN(ir) );5.2534 - MEM_WRITE_LONG( RN(ir), sh4r.fpul );5.2535 - break;5.2536 - case 0x56: /* LDS.L [Rn++], FPUL */5.2537 - CHECKRALIGN32( RN(ir) );5.2538 - sh4r.fpul = MEM_READ_LONG(RN(ir));5.2539 - RN(ir) +=4;5.2540 - break;5.2541 - case 0x5A: /* LDS Rn, FPUL */5.2542 - sh4r.fpul = RN(ir);5.2543 - break;5.2544 - case 0x62: /* STS.L FPSCR, [--Rn] */5.2545 - RN(ir) -= 4;5.2546 - CHECKWALIGN32( RN(ir) );5.2547 - MEM_WRITE_LONG( RN(ir), sh4r.fpscr );5.2548 - break;5.2549 - case 0x66: /* LDS.L [Rn++], FPSCR */5.2550 - CHECKRALIGN32( RN(ir) );5.2551 - sh4r.fpscr = MEM_READ_LONG(RN(ir));5.2552 - RN(ir) +=4;5.2553 - break;5.2554 - case 0x6A: /* LDS Rn, FPSCR */5.2555 - sh4r.fpscr = RN(ir);5.2556 - break;5.2557 - case 0xF2: /* STC.L DBR, [--Rn] */5.2558 - CHECKPRIV();5.2559 - RN(ir) -= 4;5.2560 - CHECKWALIGN32( RN(ir) );5.2561 - MEM_WRITE_LONG( RN(ir), sh4r.dbr );5.2562 - break;5.2563 - case 0xF6: /* LDC.L [Rn++], DBR */5.2564 - CHECKPRIV();5.2565 - CHECKRALIGN32( RN(ir) );5.2566 - sh4r.dbr = MEM_READ_LONG(RN(ir));5.2567 - RN(ir) +=4;5.2568 - break;5.2569 - case 0xFA: /* LDC Rn, DBR */5.2570 - CHECKPRIV();5.2571 - sh4r.dbr = RN(ir);5.2572 - break;5.2573 - case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3:5.2574 - case 0xD3: case 0xE3: case 0xF3: /* STC.L Rn_BANK, [--Rn] */5.2575 - CHECKPRIV();5.2576 - RN(ir) -= 4;5.2577 - CHECKWALIGN32( RN(ir) );5.2578 - MEM_WRITE_LONG( RN(ir), RN_BANK(ir) );5.2579 - break;5.2580 - case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7:5.2581 - case 0xD7: case 0xE7: case 0xF7: /* LDC.L [Rn++], Rn_BANK */5.2582 - CHECKPRIV();5.2583 - CHECKRALIGN32( RN(ir) );5.2584 - RN_BANK(ir) = MEM_READ_LONG( RN(ir) );5.2585 - RN(ir) += 4;5.2586 - break;5.2587 - case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE:5.2588 - case 0xDE: case 0xEE: case 0xFE: /* LDC Rm, Rn_BANK */5.2589 - CHECKPRIV();5.2590 - RN_BANK(ir) = RM(ir);5.2591 - break;5.2592 - default:5.2593 - if( (ir&0x000F) == 0x0F ) {5.2594 - /* MAC.W [Rm++], [Rn++] */5.2595 - CHECKRALIGN16( RN(ir) );5.2596 - CHECKRALIGN16( RM(ir) );5.2597 - tmp = SIGNEXT16(MEM_READ_WORD(RM(ir))) *5.2598 - SIGNEXT16(MEM_READ_WORD(RN(ir)));5.2599 - if( sh4r.s ) {5.2600 - /* FIXME */5.2601 - UNIMP(ir);5.2602 - } else sh4r.mac += SIGNEXT32(tmp);5.2603 - RM(ir) += 2;5.2604 - RN(ir) += 2;5.2605 - } else if( (ir&0x000F) == 0x0C ) {5.2606 - /* SHAD Rm, Rn */5.2607 - tmp = RM(ir);5.2608 - if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);5.2609 - else if( (tmp & 0x1F) == 0 )5.2610 - RN(ir) = ((int32_t)RN(ir)) >> 31;5.2611 - else5.2612 - RN(ir) = ((int32_t)RN(ir)) >> (((~RM(ir)) & 0x1F)+1);5.2613 - } else if( (ir&0x000F) == 0x0D ) {5.2614 - /* SHLD Rm, Rn */5.2615 - tmp = RM(ir);5.2616 - if( (tmp & 0x80000000) == 0 ) RN(ir) <<= (tmp&0x1f);5.2617 - else if( (tmp & 0x1F) == 0 ) RN(ir) = 0;5.2618 - else RN(ir) >>= (((~tmp) & 0x1F)+1);5.2619 - } else UNDEF(ir);5.2620 - }5.2621 - break;5.2622 - case 5: /* 0101nnnnmmmmdddd */5.2623 - /* MOV.L [Rm + disp4*4], Rn */5.2624 - tmp = RM(ir) + (DISP4(ir)<<2);5.2625 - CHECKRALIGN32( tmp );5.2626 - RN(ir) = MEM_READ_LONG( tmp );5.2627 - break;5.2628 - case 6: /* 0110xxxxxxxxxxxx */5.2629 - switch( ir&0x000f ) {5.2630 - case 0: /* MOV.B [Rm], Rn */5.2631 - RN(ir) = MEM_READ_BYTE( RM(ir) );5.2632 - break;5.2633 - case 1: /* MOV.W [Rm], Rn */5.2634 - CHECKRALIGN16( RM(ir) );5.2635 - RN(ir) = MEM_READ_WORD( RM(ir) );5.2636 - break;5.2637 - case 2: /* MOV.L [Rm], Rn */5.2638 - CHECKRALIGN32( RM(ir) );5.2639 - RN(ir) = MEM_READ_LONG( RM(ir) );5.2640 - break;5.2641 - case 3: /* MOV Rm, Rn */5.2642 - RN(ir) = RM(ir);5.2643 - break;5.2644 - case 4: /* MOV.B [Rm++], Rn */5.2645 - RN(ir) = MEM_READ_BYTE( RM(ir) );5.2646 - RM(ir) ++;5.2647 - break;5.2648 - case 5: /* MOV.W [Rm++], Rn */5.2649 - CHECKRALIGN16( RM(ir) );5.2650 - RN(ir) = MEM_READ_WORD( RM(ir) );5.2651 - RM(ir) += 2;5.2652 - break;5.2653 - case 6: /* MOV.L [Rm++], Rn */5.2654 - CHECKRALIGN32( RM(ir) );5.2655 - RN(ir) = MEM_READ_LONG( RM(ir) );5.2656 - RM(ir) += 4;5.2657 - break;5.2658 - case 7: /* NOT Rm, Rn */5.2659 - RN(ir) = ~RM(ir);5.2660 - break;5.2661 - case 8: /* SWAP.B Rm, Rn */5.2662 - RN(ir) = (RM(ir)&0xFFFF0000) | ((RM(ir)&0x0000FF00)>>8) |5.2663 - ((RM(ir)&0x000000FF)<<8);5.2664 - break;5.2665 - case 9: /* SWAP.W Rm, Rn */5.2666 - RN(ir) = (RM(ir)>>16) | (RM(ir)<<16);5.2667 - break;5.2668 - case 10:/* NEGC Rm, Rn */5.2669 - tmp = 0 - RM(ir);5.2670 - RN(ir) = tmp - sh4r.t;5.2671 - sh4r.t = ( 0<tmp || tmp<RN(ir) ? 1 : 0 );5.2672 - break;5.2673 - case 11:/* NEG Rm, Rn */5.2674 - RN(ir) = 0 - RM(ir);5.2675 - break;5.2676 - case 12:/* EXTU.B Rm, Rn */5.2677 - RN(ir) = RM(ir)&0x000000FF;5.2678 - break;5.2679 - case 13:/* EXTU.W Rm, Rn */5.2680 - RN(ir) = RM(ir)&0x0000FFFF;5.2681 - break;5.2682 - case 14:/* EXTS.B Rm, Rn */5.2683 - RN(ir) = SIGNEXT8( RM(ir)&0x000000FF );5.2684 - break;5.2685 - case 15:/* EXTS.W Rm, Rn */5.2686 - RN(ir) = SIGNEXT16( RM(ir)&0x0000FFFF );5.2687 - break;5.2688 - }5.2689 - break;5.2690 - case 7: /* 0111nnnniiiiiiii */5.2691 - /* ADD imm8, Rn */5.2692 - RN(ir) += IMM8(ir);5.2693 - break;5.2694 - case 8: /* 1000xxxxxxxxxxxx */5.2695 - switch( (ir&0x0F00) >> 8 ) {5.2696 - case 0: /* MOV.B R0, [Rm + disp4] */5.2697 - MEM_WRITE_BYTE( RM(ir) + DISP4(ir), R0 );5.2698 - break;5.2699 - case 1: /* MOV.W R0, [Rm + disp4*2] */5.2700 - tmp = RM(ir) + (DISP4(ir)<<1);5.2701 - CHECKWALIGN16( tmp );5.2702 - MEM_WRITE_WORD( tmp, R0 );5.2703 - break;5.2704 - case 4: /* MOV.B [Rm + disp4], R0 */5.2705 - R0 = MEM_READ_BYTE( RM(ir) + DISP4(ir) );5.2706 - break;5.2707 - case 5: /* MOV.W [Rm + disp4*2], R0 */5.2708 - tmp = RM(ir) + (DISP4(ir)<<1);5.2709 - CHECKRALIGN16( tmp );5.2710 - R0 = MEM_READ_WORD( tmp );5.2711 - break;5.2712 - case 8: /* CMP/EQ imm, R0 */5.2713 - sh4r.t = ( R0 == IMM8(ir) ? 1 : 0 );5.2714 - break;5.2715 - case 9: /* BT disp8 */5.2716 - CHECKSLOTILLEGAL();5.2717 - if( sh4r.t ) {5.2718 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )5.2719 - sh4r.pc += (PCDISP8(ir)<<1) + 4;5.2720 - sh4r.new_pc = sh4r.pc + 2;5.2721 - return TRUE;5.2722 - }5.2723 - break;5.2724 - case 11:/* BF disp8 */5.2725 - CHECKSLOTILLEGAL();5.2726 - if( !sh4r.t ) {5.2727 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )5.2728 - sh4r.pc += (PCDISP8(ir)<<1) + 4;5.2729 - sh4r.new_pc = sh4r.pc + 2;5.2730 - return TRUE;5.2731 - }5.2732 - break;5.2733 - case 13:/* BT/S disp8 */5.2734 - CHECKSLOTILLEGAL();5.2735 - if( sh4r.t ) {5.2736 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )5.2737 - sh4r.in_delay_slot = 1;5.2738 - sh4r.pc = sh4r.new_pc;5.2739 - sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;5.2740 - sh4r.in_delay_slot = 1;5.2741 - return TRUE;5.2742 - }5.2743 - break;5.2744 - case 15:/* BF/S disp8 */5.2745 - CHECKSLOTILLEGAL();5.2746 - if( !sh4r.t ) {5.2747 - CHECKDEST( sh4r.pc + (PCDISP8(ir)<<1) + 4 )5.2748 - sh4r.in_delay_slot = 1;5.2749 - sh4r.pc = sh4r.new_pc;5.2750 - sh4r.new_pc = pc + (PCDISP8(ir)<<1) + 4;5.2751 - return TRUE;5.2752 - }5.2753 - break;5.2754 - default: UNDEF(ir);5.2755 - }5.2756 - break;5.2757 - case 9: /* 1001xxxxxxxxxxxx */5.2758 - /* MOV.W [disp8*2 + pc + 4], Rn */5.2759 - CHECKSLOTILLEGAL();5.2760 - tmp = pc + 4 + (DISP8(ir)<<1);5.2761 - RN(ir) = MEM_READ_WORD( tmp );5.2762 - break;5.2763 - case 10:/* 1010dddddddddddd */5.2764 - /* BRA disp12 */5.2765 - CHECKSLOTILLEGAL();5.2766 - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );5.2767 - sh4r.in_delay_slot = 1;5.2768 - sh4r.pc = sh4r.new_pc;5.2769 - sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);5.2770 - return TRUE;5.2771 - case 11:/* 1011dddddddddddd */5.2772 - /* BSR disp12 */5.2773 - CHECKDEST( sh4r.pc + (DISP12(ir)<<1) + 4 );5.2774 - CHECKSLOTILLEGAL();5.2775 - sh4r.in_delay_slot = 1;5.2776 - sh4r.pr = pc + 4;5.2777 - sh4r.pc = sh4r.new_pc;5.2778 - sh4r.new_pc = pc + 4 + (DISP12(ir)<<1);5.2779 - TRACE_CALL( pc, sh4r.new_pc );5.2780 - return TRUE;5.2781 - case 12:/* 1100xxxxdddddddd */5.2782 - switch( (ir&0x0F00)>>8 ) {5.2783 - case 0: /* MOV.B R0, [GBR + disp8] */5.2784 - MEM_WRITE_BYTE( sh4r.gbr + DISP8(ir), R0 );5.2785 - break;5.2786 - case 1: /* MOV.W R0, [GBR + disp8*2] */5.2787 - tmp = sh4r.gbr + (DISP8(ir)<<1);5.2788 - CHECKWALIGN16( tmp );5.2789 - MEM_WRITE_WORD( tmp, R0 );5.2790 - break;5.2791 - case 2: /*MOV.L R0, [GBR + disp8*4] */5.2792 - tmp = sh4r.gbr + (DISP8(ir)<<2);5.2793 - CHECKWALIGN32( tmp );5.2794 - MEM_WRITE_LONG( tmp, R0 );5.2795 - break;5.2796 - case 3: /* TRAPA imm8 */5.2797 - CHECKSLOTILLEGAL();5.2798 - MMIO_WRITE( MMU, TRA, UIMM8(ir)<<2 );5.2799 - sh4r.pc += 2;5.2800 - sh4_raise_exception( EXC_TRAP );5.2801 - break;5.2802 - case 4: /* MOV.B [GBR + disp8], R0 */5.2803 - R0 = MEM_READ_BYTE( sh4r.gbr + DISP8(ir) );5.2804 - break;5.2805 - case 5: /* MOV.W [GBR + disp8*2], R0 */5.2806 - tmp = sh4r.gbr + (DISP8(ir)<<1);5.2807 - CHECKRALIGN16( tmp );5.2808 - R0 = MEM_READ_WORD( tmp );5.2809 - break;5.2810 - case 6: /* MOV.L [GBR + disp8*4], R0 */5.2811 - tmp = sh4r.gbr + (DISP8(ir)<<2);5.2812 - CHECKRALIGN32( tmp );5.2813 - R0 = MEM_READ_LONG( tmp );5.2814 - break;5.2815 - case 7: /* MOVA disp8 + pc&~3 + 4, R0 */5.2816 - CHECKSLOTILLEGAL();5.2817 - R0 = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;5.2818 - break;5.2819 - case 8: /* TST imm8, R0 */5.2820 - sh4r.t = (R0 & UIMM8(ir) ? 0 : 1);5.2821 - break;5.2822 - case 9: /* AND imm8, R0 */5.2823 - R0 &= UIMM8(ir);5.2824 - break;5.2825 - case 10:/* XOR imm8, R0 */5.2826 - R0 ^= UIMM8(ir);5.2827 - break;5.2828 - case 11:/* OR imm8, R0 */5.2829 - R0 |= UIMM8(ir);5.2830 - break;5.2831 - case 12:/* TST.B imm8, [R0+GBR] */5.2832 - sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & UIMM8(ir) ? 0 : 1 );5.2833 - break;5.2834 - case 13:/* AND.B imm8, [R0+GBR] */5.2835 - MEM_WRITE_BYTE( R0 + sh4r.gbr,5.2836 - UIMM8(ir) & MEM_READ_BYTE(R0 + sh4r.gbr) );5.2837 - break;5.2838 - case 14:/* XOR.B imm8, [R0+GBR] */5.2839 - MEM_WRITE_BYTE( R0 + sh4r.gbr,5.2840 - UIMM8(ir) ^ MEM_READ_BYTE(R0 + sh4r.gbr) );5.2841 - break;5.2842 - case 15:/* OR.B imm8, [R0+GBR] */5.2843 - MEM_WRITE_BYTE( R0 + sh4r.gbr,5.2844 - UIMM8(ir) | MEM_READ_BYTE(R0 + sh4r.gbr) );5.2845 - break;5.2846 - }5.2847 - break;5.2848 - case 13:/* 1101nnnndddddddd */5.2849 - /* MOV.L [disp8*4 + pc&~3 + 4], Rn */5.2850 - CHECKSLOTILLEGAL();5.2851 - tmp = (pc&0xFFFFFFFC) + (DISP8(ir)<<2) + 4;5.2852 - RN(ir) = MEM_READ_LONG( tmp );5.2853 - break;5.2854 - case 14:/* 1110nnnniiiiiiii */5.2855 - /* MOV imm8, Rn */5.2856 - RN(ir) = IMM8(ir);5.2857 - break;5.2858 - case 15:/* 1111xxxxxxxxxxxx */5.2859 - CHECKFPUEN();5.2860 - if( IS_FPU_DOUBLEPREC() ) {5.2861 - switch( ir&0x000F ) {5.2862 - case 0: /* FADD FRm, FRn */5.2863 - DRN(ir) += DRM(ir);5.2864 - break;5.2865 - case 1: /* FSUB FRm, FRn */5.2866 - DRN(ir) -= DRM(ir);5.2867 - break;5.2868 - case 2: /* FMUL FRm, FRn */5.2869 - DRN(ir) = DRN(ir) * DRM(ir);5.2870 - break;5.2871 - case 3: /* FDIV FRm, FRn */5.2872 - DRN(ir) = DRN(ir) / DRM(ir);5.2873 - break;5.2874 - case 4: /* FCMP/EQ FRm, FRn */5.2875 - sh4r.t = ( DRN(ir) == DRM(ir) ? 1 : 0 );5.2876 - break;5.2877 - case 5: /* FCMP/GT FRm, FRn */5.2878 - sh4r.t = ( DRN(ir) > DRM(ir) ? 1 : 0 );5.2879 - break;5.2880 - case 6: /* FMOV.S [Rm+R0], FRn */5.2881 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );5.2882 - break;5.2883 - case 7: /* FMOV.S FRm, [Rn+R0] */5.2884 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );5.2885 - break;5.2886 - case 8: /* FMOV.S [Rm], FRn */5.2887 - MEM_FP_READ( RM(ir), FRNn(ir) );5.2888 - break;5.2889 - case 9: /* FMOV.S [Rm++], FRn */5.2890 - MEM_FP_READ( RM(ir), FRNn(ir) );5.2891 - RM(ir) += FP_WIDTH;5.2892 - break;5.2893 - case 10:/* FMOV.S FRm, [Rn] */5.2894 - MEM_FP_WRITE( RN(ir), FRMn(ir) );5.2895 - break;5.2896 - case 11:/* FMOV.S FRm, [--Rn] */5.2897 - RN(ir) -= FP_WIDTH;5.2898 - MEM_FP_WRITE( RN(ir), FRMn(ir) );5.2899 - break;5.2900 - case 12:/* FMOV FRm, FRn */5.2901 - if( IS_FPU_DOUBLESIZE() )5.2902 - DRN(ir) = DRM(ir);5.2903 - else5.2904 - FRN(ir) = FRM(ir);5.2905 - break;5.2906 - case 13:5.2907 - switch( (ir&0x00F0) >> 4 ) {5.2908 - case 0: /* FSTS FPUL, FRn */5.2909 - FRN(ir) = FPULf;5.2910 - break;5.2911 - case 1: /* FLDS FRn,FPUL */5.2912 - FPULf = FRN(ir);5.2913 - break;5.2914 - case 2: /* FLOAT FPUL, FRn */5.2915 - DRN(ir) = (float)FPULi;5.2916 - break;5.2917 - case 3: /* FTRC FRn, FPUL */5.2918 - dtmp = DRN(ir);5.2919 - if( dtmp >= MAX_INTF )5.2920 - FPULi = MAX_INT;5.2921 - else if( dtmp <= MIN_INTF )5.2922 - FPULi = MIN_INT;5.2923 - else5.2924 - FPULi = (int32_t)dtmp;5.2925 - break;5.2926 - case 4: /* FNEG FRn */5.2927 - DRN(ir) = -DRN(ir);5.2928 - break;5.2929 - case 5: /* FABS FRn */5.2930 - DRN(ir) = fabs(DRN(ir));5.2931 - break;5.2932 - case 6: /* FSQRT FRn */5.2933 - DRN(ir) = sqrt(DRN(ir));5.2934 - break;5.2935 - case 7: /* FSRRA FRn */5.2936 - /* NO-OP when PR=1 */5.2937 - break;5.2938 - case 8: /* FLDI0 FRn */5.2939 - DRN(ir) = 0.0;5.2940 - break;5.2941 - case 9: /* FLDI1 FRn */5.2942 - DRN(ir) = 1.0;5.2943 - break;5.2944 - case 10: /* FCNVSD FPUL, DRn */5.2945 - if( ! IS_FPU_DOUBLESIZE() )5.2946 - DRN(ir) = (double)FPULf;5.2947 - break;5.2948 - case 11: /* FCNVDS DRn, FPUL */5.2949 - if( ! IS_FPU_DOUBLESIZE() )5.2950 - FPULf = (float)DRN(ir);5.2951 - break;5.2952 - case 14:/* FIPR FVm, FVn */5.2953 - /* NO-OP when PR=1 */5.2954 - break;5.2955 - case 15:5.2956 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */5.2957 - /* NO-OP when PR=1 */5.2958 - break;5.2959 - }5.2960 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */5.2961 - /* NO-OP when PR=1 */5.2962 - break;5.2963 - }5.2964 - else if( ir == 0xFBFD ) {5.2965 - /* FRCHG */5.2966 - sh4r.fpscr ^= FPSCR_FR;5.2967 - break;5.2968 - }5.2969 - else if( ir == 0xF3FD ) {5.2970 - /* FSCHG */5.2971 - sh4r.fpscr ^= FPSCR_SZ;5.2972 - break;5.2973 - }5.2974 - default: UNDEF(ir);5.2975 - }5.2976 - break;5.2977 - case 14:/* FMAC FR0, FRm, FRn */5.2978 - DRN(ir) += DRM(ir)*DR0;5.2979 - break;5.2980 - default: UNDEF(ir);5.2981 - }5.2982 - } else { /* Single precision */5.2983 - switch( ir&0x000F ) {5.2984 - case 0: /* FADD FRm, FRn */5.2985 - FRN(ir) += FRM(ir);5.2986 - break;5.2987 - case 1: /* FSUB FRm, FRn */5.2988 - FRN(ir) -= FRM(ir);5.2989 - break;5.2990 - case 2: /* FMUL FRm, FRn */5.2991 - FRN(ir) = FRN(ir) * FRM(ir);5.2992 - break;5.2993 - case 3: /* FDIV FRm, FRn */5.2994 - FRN(ir) = FRN(ir) / FRM(ir);5.2995 - break;5.2996 - case 4: /* FCMP/EQ FRm, FRn */5.2997 - sh4r.t = ( FRN(ir) == FRM(ir) ? 1 : 0 );5.2998 - break;5.2999 - case 5: /* FCMP/GT FRm, FRn */5.3000 - sh4r.t = ( FRN(ir) > FRM(ir) ? 1 : 0 );5.3001 - break;5.3002 - case 6: /* FMOV.S [Rm+R0], FRn */5.3003 - MEM_FP_READ( RM(ir) + R0, FRNn(ir) );5.3004 - break;5.3005 - case 7: /* FMOV.S FRm, [Rn+R0] */5.3006 - MEM_FP_WRITE( RN(ir) + R0, FRMn(ir) );5.3007 - break;5.3008 - case 8: /* FMOV.S [Rm], FRn */5.3009 - MEM_FP_READ( RM(ir), FRNn(ir) );5.3010 - break;5.3011 - case 9: /* FMOV.S [Rm++], FRn */5.3012 - MEM_FP_READ( RM(ir), FRNn(ir) );5.3013 - RM(ir) += FP_WIDTH;5.3014 - break;5.3015 - case 10:/* FMOV.S FRm, [Rn] */5.3016 - MEM_FP_WRITE( RN(ir), FRMn(ir) );5.3017 - break;5.3018 - case 11:/* FMOV.S FRm, [--Rn] */5.3019 - RN(ir) -= FP_WIDTH;5.3020 - MEM_FP_WRITE( RN(ir), FRMn(ir) );5.3021 - break;5.3022 - case 12:/* FMOV FRm, FRn */5.3023 - if( IS_FPU_DOUBLESIZE() )5.3024 - DRN(ir) = DRM(ir);5.3025 - else5.3026 - FRN(ir) = FRM(ir);5.3027 - break;5.3028 - case 13:5.3029 - switch( (ir&0x00F0) >> 4 ) {5.3030 - case 0: /* FSTS FPUL, FRn */5.3031 - FRN(ir) = FPULf;5.3032 - break;5.3033 - case 1: /* FLDS FRn,FPUL */5.3034 - FPULf = FRN(ir);5.3035 - break;5.3036 - case 2: /* FLOAT FPUL, FRn */5.3037 - FRN(ir) = (float)FPULi;5.3038 - break;5.3039 - case 3: /* FTRC FRn, FPUL */5.3040 - ftmp = FRN(ir);5.3041 - if( ftmp >= MAX_INTF )5.3042 - FPULi = MAX_INT;5.3043 - else if( ftmp <= MIN_INTF )5.3044 - FPULi = MIN_INT;5.3045 - else5.3046 - FPULi = (int32_t)ftmp;5.3047 - break;5.3048 - case 4: /* FNEG FRn */5.3049 - FRN(ir) = -FRN(ir);5.3050 - break;5.3051 - case 5: /* FABS FRn */5.3052 - FRN(ir) = fabsf(FRN(ir));5.3053 - break;5.3054 - case 6: /* FSQRT FRn */5.3055 - FRN(ir) = sqrtf(FRN(ir));5.3056 - break;5.3057 - case 7: /* FSRRA FRn */5.3058 - FRN(ir) = 1.0/sqrtf(FRN(ir));5.3059 - break;5.3060 - case 8: /* FLDI0 FRn */5.3061 - FRN(ir) = 0.0;5.3062 - break;5.3063 - case 9: /* FLDI1 FRn */5.3064 - FRN(ir) = 1.0;5.3065 - break;5.3066 - case 10: /* FCNVSD FPUL, DRn */5.3067 - break;5.3068 - case 11: /* FCNVDS DRn, FPUL */5.3069 - break;5.3070 - case 14:/* FIPR FVm, FVn */5.3071 - /* FIXME: This is not going to be entirely accurate5.3072 - * as the SH4 instruction is less precise. Also5.3073 - * need to check for 0s and infinities.5.3074 - */5.3075 - {5.3076 - int tmp2 = FVN(ir);5.3077 - tmp = FVM(ir);5.3078 - FR(tmp2+3) = FR(tmp)*FR(tmp2) +5.3079 - FR(tmp+1)*FR(tmp2+1) +5.3080 - FR(tmp+2)*FR(tmp2+2) +5.3081 - FR(tmp+3)*FR(tmp2+3);5.3082 - break;5.3083 - }5.3084 - case 15:5.3085 - if( (ir&0x0300) == 0x0100 ) { /* FTRV XMTRX,FVn */5.3086 - tmp = FVN(ir);5.3087 - float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };5.3088 - FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +5.3089 - XF(8)*fv[2] + XF(12)*fv[3];5.3090 - FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +5.3091 - XF(9)*fv[2] + XF(13)*fv[3];5.3092 - FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +5.3093 - XF(10)*fv[2] + XF(14)*fv[3];5.3094 - FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +5.3095 - XF(11)*fv[2] + XF(15)*fv[3];5.3096 - break;5.3097 - }5.3098 - else if( (ir&0x0100) == 0 ) { /* FSCA FPUL, DRn */5.3099 - float angle = (((float)(short)(FPULi>>16)) +5.3100 - (((float)(FPULi&0xFFFF))/65536.0)) *5.3101 - 2 * M_PI;5.3102 - int reg = FRNn(ir);5.3103 - FR(reg) = sinf(angle);5.3104 - FR(reg+1) = cosf(angle);5.3105 - break;5.3106 - }5.3107 - else if( ir == 0xFBFD ) {5.3108 - /* FRCHG */5.3109 - sh4r.fpscr ^= FPSCR_FR;5.3110 - break;5.3111 - }5.3112 - else if( ir == 0xF3FD ) {5.3113 - /* FSCHG */5.3114 - sh4r.fpscr ^= FPSCR_SZ;5.3115 - break;5.3116 - }5.3117 - default: UNDEF(ir);5.3118 - }5.3119 - break;5.3120 - case 14:/* FMAC FR0, FRm, FRn */5.3121 - FRN(ir) += FRM(ir)*FR0;5.3122 - break;5.3123 - default: UNDEF(ir);5.3124 - }5.3125 - }5.3126 - break;5.3127 - }5.3128 sh4r.pc = sh4r.new_pc;5.3129 sh4r.new_pc += 2;5.3130 sh4r.in_delay_slot = 0;
6.1 --- a/src/sh4/sh4core.h Thu Aug 23 12:31:31 2007 +00006.2 +++ b/src/sh4/sh4core.h Thu Aug 23 12:33:27 2007 +00006.3 @@ -1,5 +1,5 @@6.4 /**6.5 - * $Id: sh4core.h,v 1.18 2007-01-23 08:17:06 nkeynes Exp $6.6 + * $Id: sh4core.h,v 1.19 2007-08-23 12:33:27 nkeynes Exp $6.7 *6.8 * This file defines the internal functions exported/used by the SH4 core,6.9 * except for disassembly functions defined in sh4dasm.h6.10 @@ -59,11 +59,11 @@6.11 struct sh4_registers {6.12 uint32_t r[16];6.13 uint32_t r_bank[8]; /* hidden banked registers */6.14 - uint32_t sr, gbr, ssr, spc, sgr, dbr, vbr;6.15 - uint32_t pr, pc, fpscr;6.16 + uint32_t sr, pr, pc, fpscr, t;6.17 int32_t fpul;6.18 + uint32_t gbr, ssr, spc, sgr, dbr, vbr;6.19 uint64_t mac;6.20 - uint32_t m, q, s, t; /* really boolean - 0 or 1 */6.21 + uint32_t m, q, s; /* really boolean - 0 or 1 */6.22 float fr[2][16];6.24 int32_t store_queue[16]; /* technically 2 banks of 32 bytes */6.25 @@ -171,10 +171,14 @@6.26 #define IS_FPU_ENABLED() ((sh4r.sr&SR_FD)==0)6.28 #define FR(x) sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21][(x)^1]6.29 -#define DR(x) ((double *)(sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21]))[x]6.30 +#define DRF(x) ((double *)(sh4r.fr[(sh4r.fpscr&FPSCR_FR)>>21]))[x]6.31 #define XF(x) sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21][(x)^1]6.32 #define XDR(x) ((double *)(sh4r.fr[((~sh4r.fpscr)&FPSCR_FR)>>21]))[x]6.33 #define DRb(x,b) ((double *)(sh4r.fr[((b ? (~sh4r.fpscr) : sh4r.fpscr)&FPSCR_FR)>>21]))[x]6.34 +#define DR(x) DRb((x>>1), (x&1))6.35 +#define FPULf *((float *)&sh4r.fpul)6.36 +#define FPULi (sh4r.fpul)6.37 +6.38 /* Exceptions (for use with sh4_raise_exception) */6.40 #define EX_ILLEGAL_INSTRUCTION 0x180, 0x1006.41 @@ -198,3 +202,4 @@6.42 }6.43 #endif6.44 #endif6.45 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00007.2 +++ b/src/sh4/sh4core.in Thu Aug 23 12:33:27 2007 +00007.3 @@ -0,0 +1,1340 @@7.4 +/**7.5 + * $Id: sh4core.in,v 1.1 2007-08-23 12:33:27 nkeynes Exp $7.6 + *7.7 + * SH4 emulation core, and parent module for all the SH4 peripheral7.8 + * modules.7.9 + *7.10 + * Copyright (c) 2005 Nathan Keynes.7.11 + *7.12 + * This program is free software; you can redistribute it and/or modify7.13 + * it under the terms of the GNU General Public License as published by7.14 + * the Free Software Foundation; either version 2 of the License, or7.15 + * (at your option) any later version.7.16 + *7.17 + * This program is distributed in the hope that it will be useful,7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the7.20 + * GNU General Public License for more details.7.21 + */7.22 +7.23 +#define MODULE sh4_module7.24 +#include <math.h>7.25 +#include "dream.h"7.26 +#include "sh4/sh4core.h"7.27 +#include "sh4/sh4mmio.h"7.28 +#include "sh4/intc.h"7.29 +#include "mem.h"7.30 +#include "clock.h"7.31 +#include "syscall.h"7.32 +7.33 +#define SH4_CALLTRACE 17.34 +7.35 +#define MAX_INT 0x7FFFFFFF7.36 +#define MIN_INT 0x800000007.37 +#define MAX_INTF 2147483647.07.38 +#define MIN_INTF -2147483648.07.39 +7.40 +/* CPU-generated exception code/vector pairs */7.41 +#define EXC_POWER_RESET 0x000 /* vector special */7.42 +#define EXC_MANUAL_RESET 0x0207.43 +#define EXC_READ_ADDR_ERR 0x0E07.44 +#define EXC_WRITE_ADDR_ERR 0x1007.45 +#define EXC_SLOT_ILLEGAL 0x1A07.46 +#define EXC_ILLEGAL 0x1807.47 +#define EXC_TRAP 0x1607.48 +#define EXC_FPDISABLE 0x8007.49 +#define EXC_SLOT_FPDISABLE 0x8207.50 +7.51 +#define EXV_EXCEPTION 0x100 /* General exception vector */7.52 +#define EXV_TLBMISS 0x400 /* TLB-miss exception vector */7.53 +#define EXV_INTERRUPT 0x600 /* External interrupt vector */7.54 +7.55 +/********************** SH4 Module Definition ****************************/7.56 +7.57 +void sh4_init( void );7.58 +void sh4_reset( void );7.59 +uint32_t sh4_run_slice( uint32_t );7.60 +void sh4_start( void );7.61 +void sh4_stop( void );7.62 +void sh4_save_state( FILE *f );7.63 +int sh4_load_state( FILE *f );7.64 +void sh4_accept_interrupt( void );7.65 +7.66 +struct dreamcast_module sh4_module = { "SH4", sh4_init, sh4_reset,7.67 + NULL, sh4_run_slice, sh4_stop,7.68 + sh4_save_state, sh4_load_state };7.69 +7.70 +struct sh4_registers sh4r;7.71 +7.72 +void sh4_init(void)7.73 +{7.74 + register_io_regions( mmio_list_sh4mmio );7.75 + MMU_init();7.76 + sh4_reset();7.77 +}7.78 +7.79 +void sh4_reset(void)7.80 +{7.81 + /* zero everything out, for the sake of having a consistent state. */7.82 + memset( &sh4r, 0, sizeof(sh4r) );7.83 +7.84 + /* Resume running if we were halted */7.85 + sh4r.sh4_state = SH4_STATE_RUNNING;7.86 +7.87 + sh4r.pc = 0xA0000000;7.88 + sh4r.new_pc= 0xA0000002;7.89 + sh4r.vbr = 0x00000000;7.90 + sh4r.fpscr = 0x00040001;7.91 + sh4r.sr = 0x700000F0;7.92 +7.93 + /* Mem reset will do this, but if we want to reset _just_ the SH4... */7.94 + MMIO_WRITE( MMU, EXPEVT, EXC_POWER_RESET );7.95 +7.96 + /* Peripheral modules */7.97 + CPG_reset();7.98 + INTC_reset();7.99 + MMU_reset();7.100 + TMU_reset();7.101 + SCIF_reset();7.102 +}7.103 +7.104 +static struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];7.105 +static int sh4_breakpoint_count = 0;7.106 +static uint16_t *sh4_icache = NULL;7.107 +static uint32_t sh4_icache_addr = 0;7.108 +7.109 +void sh4_set_breakpoint( uint32_t pc, int type )7.110 +{7.111 + sh4_breakpoints[sh4_breakpoint_count].address = pc;7.112 + sh4_breakpoints[sh4_breakpoint_count].type = type;7.113 + sh4_breakpoint_count++;7.114 +}7.115 +7.116 +gboolean sh4_clear_breakpoint( uint32_t pc, int type )7.117 +{7.118 + int i;7.119 +7.120 + for( i=0; i<sh4_breakpoint_count; i++ ) {7.121 + if( sh4_breakpoints[i].address == pc &&7.122 + sh4_breakpoints[i].type == type ) {7.123 + while( ++i < sh4_breakpoint_count ) {7.124 + sh4_breakpoints[i-1].address = sh4_breakpoints[i].address;7.125 + sh4_breakpoints[i-1].type = sh4_breakpoints[i].type;7.126 + }7.127 + sh4_breakpoint_count--;7.128 + return TRUE;7.129 + }7.130 + }7.131 + return FALSE;7.132 +}7.133 +7.134 +int sh4_get_breakpoint( uint32_t pc )7.135 +{7.136 + int i;7.137 + for( i=0; i<sh4_breakpoint_count; i++ ) {7.138 + if( sh4_breakpoints[i].address == pc )7.139 + return sh4_breakpoints[i].type;7.140 + }7.141 + return 0;7.142 +}7.143 +7.144 +uint32_t sh4_run_slice( uint32_t nanosecs )7.145 +{7.146 + int i;7.147 + sh4r.slice_cycle = 0;7.148 +7.149 + if( sh4r.sh4_state != SH4_STATE_RUNNING ) {7.150 + if( sh4r.event_pending < nanosecs ) {7.151 + sh4r.sh4_state = SH4_STATE_RUNNING;7.152 + sh4r.slice_cycle = sh4r.event_pending;7.153 + }7.154 + }7.155 +7.156 + if( sh4_breakpoint_count == 0 ) {7.157 + for( ; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {7.158 + if( SH4_EVENT_PENDING() ) {7.159 + if( sh4r.event_types & PENDING_EVENT ) {7.160 + event_execute();7.161 + }7.162 + /* Eventq execute may (quite likely) deliver an immediate IRQ */7.163 + if( sh4r.event_types & PENDING_IRQ ) {7.164 + sh4_accept_interrupt();7.165 + }7.166 + }7.167 + if( !sh4_execute_instruction() ) {7.168 + break;7.169 + }7.170 + }7.171 + } else {7.172 + for( ;sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {7.173 + if( SH4_EVENT_PENDING() ) {7.174 + if( sh4r.event_types & PENDING_EVENT ) {7.175 + event_execute();7.176 + }7.177 + /* Eventq execute may (quite likely) deliver an immediate IRQ */7.178 + if( sh4r.event_types & PENDING_IRQ ) {7.179 + sh4_accept_interrupt();7.180 + }7.181 + }7.182 +7.183 + if( !sh4_execute_instruction() )7.184 + break;7.185 +#ifdef ENABLE_DEBUG_MODE7.186 + for( i=0; i<sh4_breakpoint_count; i++ ) {7.187 + if( sh4_breakpoints[i].address == sh4r.pc ) {7.188 + break;7.189 + }7.190 + }7.191 + if( i != sh4_breakpoint_count ) {7.192 + dreamcast_stop();7.193 + if( sh4_breakpoints[i].type == BREAK_ONESHOT )7.194 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );7.195 + break;7.196 + }7.197 +#endif7.198 + }7.199 + }7.200 +7.201 + /* If we aborted early, but the cpu is still technically running,7.202 + * we're doing a hard abort - cut the timeslice back to what we7.203 + * actually executed7.204 + */7.205 + if( sh4r.slice_cycle != nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {7.206 + nanosecs = sh4r.slice_cycle;7.207 + }7.208 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {7.209 + TMU_run_slice( nanosecs );7.210 + SCIF_run_slice( nanosecs );7.211 + }7.212 + return nanosecs;7.213 +}7.214 +7.215 +void sh4_stop(void)7.216 +{7.217 +7.218 +}7.219 +7.220 +void sh4_save_state( FILE *f )7.221 +{7.222 + fwrite( &sh4r, sizeof(sh4r), 1, f );7.223 + MMU_save_state( f );7.224 + INTC_save_state( f );7.225 + TMU_save_state( f );7.226 + SCIF_save_state( f );7.227 +}7.228 +7.229 +int sh4_load_state( FILE * f )7.230 +{7.231 + fread( &sh4r, sizeof(sh4r), 1, f );7.232 + MMU_load_state( f );7.233 + INTC_load_state( f );7.234 + TMU_load_state( f );7.235 + return SCIF_load_state( f );7.236 +}7.237 +7.238 +/********************** SH4 emulation core ****************************/7.239 +7.240 +void sh4_set_pc( int pc )7.241 +{7.242 + sh4r.pc = pc;7.243 + sh4r.new_pc = pc+2;7.244 +}7.245 +7.246 +#define UNDEF(ir) return sh4_raise_slot_exception(EXC_ILLEGAL, EXC_SLOT_ILLEGAL)7.247 +#define UNIMP(ir) do{ ERROR( "Halted on unimplemented instruction at %08x, opcode = %04x", sh4r.pc, ir ); dreamcast_stop(); return FALSE; }while(0)7.248 +7.249 +#if(SH4_CALLTRACE == 1)7.250 +#define MAX_CALLSTACK 327.251 +static struct call_stack {7.252 + sh4addr_t call_addr;7.253 + sh4addr_t target_addr;7.254 + sh4addr_t stack_pointer;7.255 +} call_stack[MAX_CALLSTACK];7.256 +7.257 +static int call_stack_depth = 0;7.258 +int sh4_call_trace_on = 0;7.259 +7.260 +static inline trace_call( sh4addr_t source, sh4addr_t dest )7.261 +{7.262 + if( call_stack_depth < MAX_CALLSTACK ) {7.263 + call_stack[call_stack_depth].call_addr = source;7.264 + call_stack[call_stack_depth].target_addr = dest;7.265 + call_stack[call_stack_depth].stack_pointer = sh4r.r[15];7.266 + }7.267 + call_stack_depth++;7.268 +}7.269 +7.270 +static inline trace_return( sh4addr_t source, sh4addr_t dest )7.271 +{7.272 + if( call_stack_depth > 0 ) {7.273 + call_stack_depth--;7.274 + }7.275 +}7.276 +7.277 +void fprint_stack_trace( FILE *f )7.278 +{7.279 + int i = call_stack_depth -1;7.280 + if( i >= MAX_CALLSTACK )7.281 + i = MAX_CALLSTACK - 1;7.282 + for( ; i >= 0; i-- ) {7.283 + fprintf( f, "%d. Call from %08X => %08X, SP=%08X\n",7.284 + (call_stack_depth - i), call_stack[i].call_addr,7.285 + call_stack[i].target_addr, call_stack[i].stack_pointer );7.286 + }7.287 +}7.288 +7.289 +#define TRACE_CALL( source, dest ) trace_call(source, dest)7.290 +#define TRACE_RETURN( source, dest ) trace_return(source, dest)7.291 +#else7.292 +#define TRACE_CALL( dest, rts )7.293 +#define TRACE_RETURN( source, dest )7.294 +#endif7.295 +7.296 +#define RAISE( x, v ) do{ \7.297 + if( sh4r.vbr == 0 ) { \7.298 + ERROR( "%08X: VBR not initialized while raising exception %03X, halting", sh4r.pc, x ); \7.299 + dreamcast_stop(); return FALSE; \7.300 + } else { \7.301 + sh4r.spc = sh4r.pc; \7.302 + sh4r.ssr = sh4_read_sr(); \7.303 + sh4r.sgr = sh4r.r[15]; \7.304 + MMIO_WRITE(MMU,EXPEVT,x); \7.305 + sh4r.pc = sh4r.vbr + v; \7.306 + sh4r.new_pc = sh4r.pc + 2; \7.307 + sh4_load_sr( sh4r.ssr |SR_MD|SR_BL|SR_RB ); \7.308 + if( sh4r.in_delay_slot ) { \7.309 + sh4r.in_delay_slot = 0; \7.310 + sh4r.spc -= 2; \7.311 + } \7.312 + } \7.313 + return TRUE; } while(0)7.314 +7.315 +#define MEM_READ_BYTE( addr ) sh4_read_byte(addr)7.316 +#define MEM_READ_WORD( addr ) sh4_read_word(addr)7.317 +#define MEM_READ_LONG( addr ) sh4_read_long(addr)7.318 +#define MEM_WRITE_BYTE( addr, val ) sh4_write_byte(addr, val)7.319 +#define MEM_WRITE_WORD( addr, val ) sh4_write_word(addr, val)7.320 +#define MEM_WRITE_LONG( addr, val ) sh4_write_long(addr, val)7.321 +7.322 +#define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)7.323 +7.324 +#define MEM_FP_READ( addr, reg ) sh4_read_float( addr, reg );7.325 +#define MEM_FP_WRITE( addr, reg ) sh4_write_float( addr, reg );7.326 +7.327 +#define CHECKPRIV() if( !IS_SH4_PRIVMODE() ) return sh4_raise_slot_exception( EXC_ILLEGAL, EXC_SLOT_ILLEGAL )7.328 +#define CHECKRALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_READ_ADDR_ERR )7.329 +#define CHECKRALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_READ_ADDR_ERR )7.330 +#define CHECKWALIGN16(addr) if( (addr)&0x01 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )7.331 +#define CHECKWALIGN32(addr) if( (addr)&0x03 ) return sh4_raise_exception( EXC_WRITE_ADDR_ERR )7.332 +7.333 +#define CHECKFPUEN() if( !IS_FPU_ENABLED() ) { if( ir == 0xFFFD ) { UNDEF(ir); } else { return sh4_raise_slot_exception( EXC_FPDISABLE, EXC_SLOT_FPDISABLE ); } }7.334 +#define CHECKDEST(p) if( (p) == 0 ) { ERROR( "%08X: Branch/jump to NULL, CPU halted", sh4r.pc ); dreamcast_stop(); return FALSE; }7.335 +#define CHECKSLOTILLEGAL() if(sh4r.in_delay_slot) return sh4_raise_exception(EXC_SLOT_ILLEGAL)7.336 +7.337 +static void sh4_switch_banks( )7.338 +{7.339 + uint32_t tmp[8];7.340 +7.341 + memcpy( tmp, sh4r.r, sizeof(uint32_t)*8 );7.342 + memcpy( sh4r.r, sh4r.r_bank, sizeof(uint32_t)*8 );7.343 + memcpy( sh4r.r_bank, tmp, sizeof(uint32_t)*8 );7.344 +}7.345 +7.346 +static void sh4_load_sr( uint32_t newval )7.347 +{7.348 + if( (newval ^ sh4r.sr) & SR_RB )7.349 + sh4_switch_banks();7.350 + sh4r.sr = newval;7.351 + sh4r.t = (newval&SR_T) ? 1 : 0;7.352 + sh4r.s = (newval&SR_S) ? 1 : 0;7.353 + sh4r.m = (newval&SR_M) ? 1 : 0;7.354 + sh4r.q = (newval&SR_Q) ? 1 : 0;7.355 + intc_mask_changed();7.356 +}7.357 +7.358 +static void sh4_write_float( uint32_t addr, int reg )7.359 +{7.360 + if( IS_FPU_DOUBLESIZE() ) {7.361 + if( reg & 1 ) {7.362 + sh4_write_long( addr, *((uint32_t *)&XF((reg)&0x0E)) );7.363 + sh4_write_long( addr+4, *((uint32_t *)&XF(reg)) );7.364 + } else {7.365 + sh4_write_long( addr, *((uint32_t *)&FR(reg)) );7.366 + sh4_write_long( addr+4, *((uint32_t *)&FR((reg)|0x01)) );7.367 + }7.368 + } else {7.369 + sh4_write_long( addr, *((uint32_t *)&FR((reg))) );7.370 + }7.371 +}7.372 +7.373 +static void sh4_read_float( uint32_t addr, int reg )7.374 +{7.375 + if( IS_FPU_DOUBLESIZE() ) {7.376 + if( reg & 1 ) {7.377 + *((uint32_t *)&XF((reg) & 0x0E)) = sh4_read_long(addr);7.378 + *((uint32_t *)&XF(reg)) = sh4_read_long(addr+4);7.379 + } else {7.380 + *((uint32_t *)&FR(reg)) = sh4_read_long(addr);7.381 + *((uint32_t *)&FR((reg) | 0x01)) = sh4_read_long(addr+4);7.382 + }7.383 + } else {7.384 + *((uint32_t *)&FR(reg)) = sh4_read_long(addr);7.385 + }7.386 +}7.387 +7.388 +static uint32_t sh4_read_sr( void )7.389 +{7.390 + /* synchronize sh4r.sr with the various bitflags */7.391 + sh4r.sr &= SR_MQSTMASK;7.392 + if( sh4r.t ) sh4r.sr |= SR_T;7.393 + if( sh4r.s ) sh4r.sr |= SR_S;7.394 + if( sh4r.m ) sh4r.sr |= SR_M;7.395 + if( sh4r.q ) sh4r.sr |= SR_Q;7.396 + return sh4r.sr;7.397 +}7.398 +7.399 +/**7.400 + * Raise a general CPU exception for the specified exception code.7.401 + * (NOT for TRAPA or TLB exceptions)7.402 + */7.403 +gboolean sh4_raise_exception( int code )7.404 +{7.405 + RAISE( code, EXV_EXCEPTION );7.406 +}7.407 +7.408 +gboolean sh4_raise_slot_exception( int normal_code, int slot_code ) {7.409 + if( sh4r.in_delay_slot ) {7.410 + return sh4_raise_exception(slot_code);7.411 + } else {7.412 + return sh4_raise_exception(normal_code);7.413 + }7.414 +}7.415 +7.416 +gboolean sh4_raise_tlb_exception( int code )7.417 +{7.418 + RAISE( code, EXV_TLBMISS );7.419 +}7.420 +7.421 +void sh4_accept_interrupt( void )7.422 +{7.423 + uint32_t code = intc_accept_interrupt();7.424 + sh4r.ssr = sh4_read_sr();7.425 + sh4r.spc = sh4r.pc;7.426 + sh4r.sgr = sh4r.r[15];7.427 + sh4_load_sr( sh4r.ssr|SR_BL|SR_MD|SR_RB );7.428 + MMIO_WRITE( MMU, INTEVT, code );7.429 + sh4r.pc = sh4r.vbr + 0x600;7.430 + sh4r.new_pc = sh4r.pc + 2;7.431 + // WARN( "Accepting interrupt %03X, from %08X => %08X", code, sh4r.spc, sh4r.pc );7.432 +}7.433 +7.434 +gboolean sh4_execute_instruction( void )7.435 +{7.436 + uint32_t pc;7.437 + unsigned short ir;7.438 + uint32_t tmp;7.439 + float ftmp;7.440 + double dtmp;7.441 +7.442 +#define R0 sh4r.r[0]7.443 + pc = sh4r.pc;7.444 + if( pc > 0xFFFFFF00 ) {7.445 + /* SYSCALL Magic */7.446 + syscall_invoke( pc );7.447 + sh4r.in_delay_slot = 0;7.448 + pc = sh4r.pc = sh4r.pr;7.449 + sh4r.new_pc = sh4r.pc + 2;7.450 + }7.451 + CHECKRALIGN16(pc);7.452 +7.453 + /* Read instruction */7.454 + uint32_t pageaddr = pc >> 12;7.455 + if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {7.456 + ir = sh4_icache[(pc&0xFFF)>>1];7.457 + } else {7.458 + sh4_icache = (uint16_t *)mem_get_page(pc);7.459 + if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {7.460 + /* If someone's actually been so daft as to try to execute out of an IO7.461 + * region, fallback on the full-blown memory read7.462 + */7.463 + sh4_icache = NULL;7.464 + ir = MEM_READ_WORD(pc);7.465 + } else {7.466 + sh4_icache_addr = pageaddr;7.467 + ir = sh4_icache[(pc&0xFFF)>>1];7.468 + }7.469 + }7.470 +%%7.471 +AND Rm, Rn {: sh4r.r[Rn] &= sh4r.r[Rm]; :}7.472 +AND #imm, R0 {: R0 &= imm; :}7.473 +AND.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm & MEM_READ_BYTE(R0 + sh4r.gbr) ); :}7.474 +NOT Rm, Rn {: sh4r.r[Rn] = ~sh4r.r[Rm]; :}7.475 +OR Rm, Rn {: sh4r.r[Rn] |= sh4r.r[Rm]; :}7.476 +OR #imm, R0 {: R0 |= imm; :}7.477 +OR.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm | MEM_READ_BYTE(R0 + sh4r.gbr) ); :}7.478 +TAS.B @Rn {:7.479 + tmp = MEM_READ_BYTE( sh4r.r[Rn] );7.480 + sh4r.t = ( tmp == 0 ? 1 : 0 );7.481 + MEM_WRITE_BYTE( sh4r.r[Rn], tmp | 0x80 );7.482 +:}7.483 +TST Rm, Rn {: sh4r.t = (sh4r.r[Rn]&sh4r.r[Rm] ? 0 : 1); :}7.484 +TST #imm, R0 {: sh4r.t = (R0 & imm ? 0 : 1); :}7.485 +TST.B #imm, @(R0, GBR) {: sh4r.t = ( MEM_READ_BYTE(R0 + sh4r.gbr) & imm ? 0 : 1 ); :}7.486 +XOR Rm, Rn {: sh4r.r[Rn] ^= sh4r.r[Rm]; :}7.487 +XOR #imm, R0 {: R0 ^= imm; :}7.488 +XOR.B #imm, @(R0, GBR) {: MEM_WRITE_BYTE( R0 + sh4r.gbr, imm ^ MEM_READ_BYTE(R0 + sh4r.gbr) ); :}7.489 +XTRCT Rm, Rn {: sh4r.r[Rn] = (sh4r.r[Rn]>>16) | (sh4r.r[Rm]<<16); :}7.490 +7.491 +ROTL Rn {:7.492 + sh4r.t = sh4r.r[Rn] >> 31;7.493 + sh4r.r[Rn] <<= 1;7.494 + sh4r.r[Rn] |= sh4r.t;7.495 +:}7.496 +ROTR Rn {:7.497 + sh4r.t = sh4r.r[Rn] & 0x00000001;7.498 + sh4r.r[Rn] >>= 1;7.499 + sh4r.r[Rn] |= (sh4r.t << 31);7.500 +:}7.501 +ROTCL Rn {:7.502 + tmp = sh4r.r[Rn] >> 31;7.503 + sh4r.r[Rn] <<= 1;7.504 + sh4r.r[Rn] |= sh4r.t;7.505 + sh4r.t = tmp;7.506 +:}7.507 +ROTCR Rn {:7.508 + tmp = sh4r.r[Rn] & 0x00000001;7.509 + sh4r.r[Rn] >>= 1;7.510 + sh4r.r[Rn] |= (sh4r.t << 31 );7.511 + sh4r.t = tmp;7.512 +:}7.513 +SHAD Rm, Rn {:7.514 + tmp = sh4r.r[Rm];7.515 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);7.516 + else if( (tmp & 0x1F) == 0 )7.517 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 31;7.518 + else7.519 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> (((~sh4r.r[Rm]) & 0x1F)+1);7.520 +:}7.521 +SHLD Rm, Rn {:7.522 + tmp = sh4r.r[Rm];7.523 + if( (tmp & 0x80000000) == 0 ) sh4r.r[Rn] <<= (tmp&0x1f);7.524 + else if( (tmp & 0x1F) == 0 ) sh4r.r[Rn] = 0;7.525 + else sh4r.r[Rn] >>= (((~tmp) & 0x1F)+1);7.526 +:}7.527 +SHAL Rn {:7.528 + sh4r.t = sh4r.r[Rn] >> 31;7.529 + sh4r.r[Rn] <<= 1;7.530 +:}7.531 +SHAR Rn {:7.532 + sh4r.t = sh4r.r[Rn] & 0x00000001;7.533 + sh4r.r[Rn] = ((int32_t)sh4r.r[Rn]) >> 1;7.534 +:}7.535 +SHLL Rn {: sh4r.t = sh4r.r[Rn] >> 31; sh4r.r[Rn] <<= 1; :}7.536 +SHLR Rn {: sh4r.t = sh4r.r[Rn] & 0x00000001; sh4r.r[Rn] >>= 1; :}7.537 +SHLL2 Rn {: sh4r.r[Rn] <<= 2; :}7.538 +SHLR2 Rn {: sh4r.r[Rn] >>= 2; :}7.539 +SHLL8 Rn {: sh4r.r[Rn] <<= 8; :}7.540 +SHLR8 Rn {: sh4r.r[Rn] >>= 8; :}7.541 +SHLL16 Rn {: sh4r.r[Rn] <<= 16; :}7.542 +SHLR16 Rn {: sh4r.r[Rn] >>= 16; :}7.543 +7.544 +EXTU.B Rm, Rn {: sh4r.r[Rn] = sh4r.r[Rm]&0x000000FF; :}7.545 +EXTU.W Rm, Rn {: sh4r.r[Rn] = sh4r.r[Rm]&0x0000FFFF; :}7.546 +EXTS.B Rm, Rn {: sh4r.r[Rn] = SIGNEXT8( sh4r.r[Rm]&0x000000FF ); :}7.547 +EXTS.W Rm, Rn {: sh4r.r[Rn] = SIGNEXT16( sh4r.r[Rm]&0x0000FFFF ); :}7.548 +SWAP.B Rm, Rn {: sh4r.r[Rn] = (sh4r.r[Rm]&0xFFFF0000) | ((sh4r.r[Rm]&0x0000FF00)>>8) | ((sh4r.r[Rm]&0x000000FF)<<8); :}7.549 +SWAP.W Rm, Rn {: sh4r.r[Rn] = (sh4r.r[Rm]>>16) | (sh4r.r[Rm]<<16); :}7.550 +7.551 +CLRT {: sh4r.t = 0; :}7.552 +SETT {: sh4r.t = 1; :}7.553 +CLRMAC {: sh4r.mac = 0; :}7.554 +LDTLB {: /* TODO */ :}7.555 +CLRS {: sh4r.s = 0; :}7.556 +SETS {: sh4r.s = 1; :}7.557 +MOVT Rn {: sh4r.r[Rn] = sh4r.t; :}7.558 +NOP {: /* NOP */ :}7.559 +7.560 +PREF @Rn {:7.561 + tmp = sh4r.r[Rn];7.562 + if( (tmp & 0xFC000000) == 0xE0000000 ) {7.563 + /* Store queue operation */7.564 + int queue = (tmp&0x20)>>2;7.565 + int32_t *src = &sh4r.store_queue[queue];7.566 + uint32_t hi = (MMIO_READ( MMU, (queue == 0 ? QACR0 : QACR1) ) & 0x1C) << 24;7.567 + uint32_t target = tmp&0x03FFFFE0 | hi;7.568 + mem_copy_to_sh4( target, src, 32 );7.569 + }7.570 +:}7.571 +OCBI @Rn {: :}7.572 +OCBP @Rn {: :}7.573 +OCBWB @Rn {: :}7.574 +MOVCA.L R0, @Rn {:7.575 + tmp = sh4r.r[Rn];7.576 + CHECKWALIGN32(tmp);7.577 + MEM_WRITE_LONG( tmp, R0 );7.578 +:}7.579 +MOV.B Rm, @(R0, Rn) {: MEM_WRITE_BYTE( R0 + sh4r.r[Rn], sh4r.r[Rm] ); :}7.580 +MOV.W Rm, @(R0, Rn) {:7.581 + CHECKWALIGN16( R0 + sh4r.r[Rn] );7.582 + MEM_WRITE_WORD( R0 + sh4r.r[Rn], sh4r.r[Rm] );7.583 +:}7.584 +MOV.L Rm, @(R0, Rn) {:7.585 + CHECKWALIGN32( R0 + sh4r.r[Rn] );7.586 + MEM_WRITE_LONG( R0 + sh4r.r[Rn], sh4r.r[Rm] );7.587 +:}7.588 +MOV.B @(R0, Rm), Rn {: sh4r.r[Rn] = MEM_READ_BYTE( R0 + sh4r.r[Rm] ); :}7.589 +MOV.W @(R0, Rm), Rn {: CHECKRALIGN16( R0 + sh4r.r[Rm] );7.590 + sh4r.r[Rn] = MEM_READ_WORD( R0 + sh4r.r[Rm] );7.591 +:}7.592 +MOV.L @(R0, Rm), Rn {: CHECKRALIGN32( R0 + sh4r.r[Rm] );7.593 + sh4r.r[Rn] = MEM_READ_LONG( R0 + sh4r.r[Rm] );7.594 +:}7.595 +MOV.L Rm, @(disp, Rn) {:7.596 + tmp = sh4r.r[Rn] + disp;7.597 + CHECKWALIGN32( tmp );7.598 + MEM_WRITE_LONG( tmp, sh4r.r[Rm] );7.599 +:}7.600 +MOV.B Rm, @Rn {: MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] ); :}7.601 +MOV.W Rm, @Rn {: CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] ); :}7.602 +MOV.L Rm, @Rn {: CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] ); :}7.603 +MOV.B Rm, @-Rn {: sh4r.r[Rn] --; MEM_WRITE_BYTE( sh4r.r[Rn], sh4r.r[Rm] ); :}7.604 +MOV.W Rm, @-Rn {: sh4r.r[Rn] -= 2; CHECKWALIGN16( sh4r.r[Rn] ); MEM_WRITE_WORD( sh4r.r[Rn], sh4r.r[Rm] ); :}7.605 +MOV.L Rm, @-Rn {: sh4r.r[Rn] -= 4; CHECKWALIGN32( sh4r.r[Rn] ); MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r[Rm] ); :}7.606 +MOV.L @(disp, Rm), Rn {:7.607 + tmp = sh4r.r[Rm] + disp;7.608 + CHECKRALIGN32( tmp );7.609 + sh4r.r[Rn] = MEM_READ_LONG( tmp );7.610 +:}7.611 +MOV.B @Rm, Rn {: sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); :}7.612 +MOV.W @Rm, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); :}7.613 +MOV.L @Rm, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); :}7.614 +MOV Rm, Rn {: sh4r.r[Rn] = sh4r.r[Rm]; :}7.615 +MOV.B @Rm+, Rn {: sh4r.r[Rn] = MEM_READ_BYTE( sh4r.r[Rm] ); sh4r.r[Rm] ++; :}7.616 +MOV.W @Rm+, Rn {: CHECKRALIGN16( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_WORD( sh4r.r[Rm] ); sh4r.r[Rm] += 2; :}7.617 +MOV.L @Rm+, Rn {: CHECKRALIGN32( sh4r.r[Rm] ); sh4r.r[Rn] = MEM_READ_LONG( sh4r.r[Rm] ); sh4r.r[Rm] += 4; :}7.618 +MOV.L @(disp, PC), Rn {:7.619 + CHECKSLOTILLEGAL();7.620 + tmp = (pc&0xFFFFFFFC) + disp + 4;7.621 + sh4r.r[Rn] = MEM_READ_LONG( tmp );7.622 +:}7.623 +MOV.B R0, @(disp, GBR) {: MEM_WRITE_BYTE( sh4r.gbr + disp, R0 ); :}7.624 +MOV.W R0, @(disp, GBR) {:7.625 + tmp = sh4r.gbr + disp;7.626 + CHECKWALIGN16( tmp );7.627 + MEM_WRITE_WORD( tmp, R0 );7.628 +:}7.629 +MOV.L R0, @(disp, GBR) {:7.630 + tmp = sh4r.gbr + disp;7.631 + CHECKWALIGN32( tmp );7.632 + MEM_WRITE_LONG( tmp, R0 );7.633 +:}7.634 +MOV.B @(disp, GBR), R0 {: R0 = MEM_READ_BYTE( sh4r.gbr + disp ); :}7.635 +MOV.W @(disp, GBR), R0 {:7.636 + tmp = sh4r.gbr + disp;7.637 + CHECKRALIGN16( tmp );7.638 + R0 = MEM_READ_WORD( tmp );7.639 +:}7.640 +MOV.L @(disp, GBR), R0 {:7.641 + tmp = sh4r.gbr + disp;7.642 + CHECKRALIGN32( tmp );7.643 + R0 = MEM_READ_LONG( tmp );7.644 +:}7.645 +MOV.B R0, @(disp, Rn) {: MEM_WRITE_BYTE( sh4r.r[Rn] + disp, R0 ); :}7.646 +MOV.W R0, @(disp, Rn) {:7.647 + tmp = sh4r.r[Rn] + disp;7.648 + CHECKWALIGN16( tmp );7.649 + MEM_WRITE_WORD( tmp, R0 );7.650 +:}7.651 +MOV.B @(disp, Rm), R0 {: R0 = MEM_READ_BYTE( sh4r.r[Rm] + disp ); :}7.652 +MOV.W @(disp, Rm), R0 {:7.653 + tmp = sh4r.r[Rm] + disp;7.654 + CHECKRALIGN16( tmp );7.655 + R0 = MEM_READ_WORD( tmp );7.656 +:}7.657 +MOV.W @(disp, PC), Rn {:7.658 + CHECKSLOTILLEGAL();7.659 + tmp = pc + 4 + disp;7.660 + sh4r.r[Rn] = MEM_READ_WORD( tmp );7.661 +:}7.662 +MOVA @(disp, PC), R0 {:7.663 + CHECKSLOTILLEGAL();7.664 + R0 = (pc&0xFFFFFFFC) + disp + 4;7.665 +:}7.666 +MOV #imm, Rn {: sh4r.r[Rn] = imm; :}7.667 +7.668 +CMP/EQ #imm, R0 {: sh4r.t = ( R0 == imm ? 1 : 0 ); :}7.669 +CMP/EQ Rm, Rn {: sh4r.t = ( sh4r.r[Rm] == sh4r.r[Rn] ? 1 : 0 ); :}7.670 +CMP/GE Rm, Rn {: sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= ((int32_t)sh4r.r[Rm]) ? 1 : 0 ); :}7.671 +CMP/GT Rm, Rn {: sh4r.t = ( ((int32_t)sh4r.r[Rn]) > ((int32_t)sh4r.r[Rm]) ? 1 : 0 ); :}7.672 +CMP/HI Rm, Rn {: sh4r.t = ( sh4r.r[Rn] > sh4r.r[Rm] ? 1 : 0 ); :}7.673 +CMP/HS Rm, Rn {: sh4r.t = ( sh4r.r[Rn] >= sh4r.r[Rm] ? 1 : 0 ); :}7.674 +CMP/PL Rn {: sh4r.t = ( ((int32_t)sh4r.r[Rn]) > 0 ? 1 : 0 ); :}7.675 +CMP/PZ Rn {: sh4r.t = ( ((int32_t)sh4r.r[Rn]) >= 0 ? 1 : 0 ); :}7.676 +CMP/STR Rm, Rn {:7.677 + /* set T = 1 if any byte in RM & RN is the same */7.678 + tmp = sh4r.r[Rm] ^ sh4r.r[Rn];7.679 + sh4r.t = ((tmp&0x000000FF)==0 || (tmp&0x0000FF00)==0 ||7.680 + (tmp&0x00FF0000)==0 || (tmp&0xFF000000)==0)?1:0;7.681 +:}7.682 +7.683 +ADD Rm, Rn {: sh4r.r[Rn] += sh4r.r[Rm]; :}7.684 +ADD #imm, Rn {: sh4r.r[Rn] += imm; :}7.685 +ADDC Rm, Rn {:7.686 + tmp = sh4r.r[Rn];7.687 + sh4r.r[Rn] += sh4r.r[Rm] + sh4r.t;7.688 + sh4r.t = ( sh4r.r[Rn] < tmp || (sh4r.r[Rn] == tmp && sh4r.t != 0) ? 1 : 0 );7.689 +:}7.690 +ADDV Rm, Rn {:7.691 + tmp = sh4r.r[Rn] + sh4r.r[Rm];7.692 + sh4r.t = ( (sh4r.r[Rn]>>31) == (sh4r.r[Rm]>>31) && ((sh4r.r[Rn]>>31) != (tmp>>31)) );7.693 + sh4r.r[Rn] = tmp;7.694 +:}7.695 +DIV0U {: sh4r.m = sh4r.q = sh4r.t = 0; :}7.696 +DIV0S Rm, Rn {:7.697 + sh4r.q = sh4r.r[Rn]>>31;7.698 + sh4r.m = sh4r.r[Rm]>>31;7.699 + sh4r.t = sh4r.q ^ sh4r.m;7.700 +:}7.701 +DIV1 Rm, Rn {:7.702 + /* This is just from the sh4p manual with some7.703 + * simplifications (someone want to check it's correct? :)7.704 + * Why they couldn't just provide a real DIV instruction...7.705 + */7.706 + uint32_t tmp0, tmp1, tmp2, dir;7.707 +7.708 + dir = sh4r.q ^ sh4r.m;7.709 + sh4r.q = (sh4r.r[Rn] >> 31);7.710 + tmp2 = sh4r.r[Rm];7.711 + sh4r.r[Rn] = (sh4r.r[Rn] << 1) | sh4r.t;7.712 + tmp0 = sh4r.r[Rn];7.713 + if( dir ) {7.714 + sh4r.r[Rn] += tmp2;7.715 + tmp1 = (sh4r.r[Rn]<tmp0 ? 1 : 0 );7.716 + } else {7.717 + sh4r.r[Rn] -= tmp2;7.718 + tmp1 = (sh4r.r[Rn]>tmp0 ? 1 : 0 );7.719 + }7.720 + sh4r.q ^= sh4r.m ^ tmp1;7.721 + sh4r.t = ( sh4r.q == sh4r.m ? 1 : 0 );7.722 +:}7.723 +DMULS.L Rm, Rn {: sh4r.mac = SIGNEXT32(sh4r.r[Rm]) * SIGNEXT32(sh4r.r[Rn]); :}7.724 +DMULU.L Rm, Rn {: sh4r.mac = ((uint64_t)sh4r.r[Rm]) * ((uint64_t)sh4r.r[Rn]); :}7.725 +DT Rn {:7.726 + sh4r.r[Rn] --;7.727 + sh4r.t = ( sh4r.r[Rn] == 0 ? 1 : 0 );7.728 +:}7.729 +MAC.W @Rm+, @Rn+ {:7.730 + CHECKRALIGN16( sh4r.r[Rn] );7.731 + CHECKRALIGN16( sh4r.r[Rm] );7.732 + int32_t stmp = SIGNEXT16(MEM_READ_WORD(sh4r.r[Rn]));7.733 + sh4r.r[Rn] += 2;7.734 + stmp = stmp * SIGNEXT16(MEM_READ_WORD(sh4r.r[Rm]));7.735 + sh4r.r[Rm] += 2;7.736 + if( sh4r.s ) {7.737 + int64_t tmpl = (int64_t)((int32_t)sh4r.mac) + (int64_t)stmp;7.738 + if( tmpl > (int64_t)0x000000007FFFFFFFLL ) {7.739 + sh4r.mac = 0x000000017FFFFFFFLL;7.740 + } else if( tmpl < (int64_t)0xFFFFFFFF80000000LL ) {7.741 + sh4r.mac = 0x0000000180000000LL;7.742 + } else {7.743 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |7.744 + ((uint32_t)(sh4r.mac + stmp));7.745 + }7.746 + } else {7.747 + sh4r.mac += SIGNEXT32(stmp);7.748 + }7.749 +:}7.750 +MAC.L @Rm+, @Rn+ {:7.751 + CHECKRALIGN32( sh4r.r[Rm] );7.752 + CHECKRALIGN32( sh4r.r[Rn] );7.753 + int64_t tmpl = SIGNEXT32(MEM_READ_LONG(sh4r.r[Rn]));7.754 + sh4r.r[Rn] += 4;7.755 + tmpl = tmpl * SIGNEXT32(MEM_READ_LONG(sh4r.r[Rm])) + sh4r.mac;7.756 + sh4r.r[Rm] += 4;7.757 + if( sh4r.s ) {7.758 + /* 48-bit Saturation. Yuch */7.759 + if( tmpl < (int64_t)0xFFFF800000000000LL )7.760 + tmpl = 0xFFFF800000000000LL;7.761 + else if( tmpl > (int64_t)0x00007FFFFFFFFFFFLL )7.762 + tmpl = 0x00007FFFFFFFFFFFLL;7.763 + }7.764 + sh4r.mac = tmpl;7.765 +:}7.766 +MUL.L Rm, Rn {: sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |7.767 + (sh4r.r[Rm] * sh4r.r[Rn]); :}7.768 +MULU.W Rm, Rn {:7.769 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |7.770 + (uint32_t)((sh4r.r[Rm]&0xFFFF) * (sh4r.r[Rn]&0xFFFF));7.771 +:}7.772 +MULS.W Rm, Rn {:7.773 + sh4r.mac = (sh4r.mac&0xFFFFFFFF00000000LL) |7.774 + (uint32_t)(SIGNEXT32(sh4r.r[Rm]&0xFFFF) * SIGNEXT32(sh4r.r[Rn]&0xFFFF));7.775 +:}7.776 +NEGC Rm, Rn {:7.777 + tmp = 0 - sh4r.r[Rm];7.778 + sh4r.r[Rn] = tmp - sh4r.t;7.779 + sh4r.t = ( 0<tmp || tmp<sh4r.r[Rn] ? 1 : 0 );7.780 +:}7.781 +NEG Rm, Rn {: sh4r.r[Rn] = 0 - sh4r.r[Rm]; :}7.782 +SUB Rm, Rn {: sh4r.r[Rn] -= sh4r.r[Rm]; :}7.783 +SUBC Rm, Rn {:7.784 + tmp = sh4r.r[Rn];7.785 + sh4r.r[Rn] = sh4r.r[Rn] - sh4r.r[Rm] - sh4r.t;7.786 + sh4r.t = (sh4r.r[Rn] > tmp || (sh4r.r[Rn] == tmp && sh4r.t == 1));7.787 +:}7.788 +7.789 +BRAF Rn {:7.790 + CHECKSLOTILLEGAL();7.791 + CHECKDEST( pc + 4 + sh4r.r[Rn] );7.792 + sh4r.in_delay_slot = 1;7.793 + sh4r.pc = sh4r.new_pc;7.794 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];7.795 + return TRUE;7.796 +:}7.797 +BSRF Rn {:7.798 + CHECKSLOTILLEGAL();7.799 + CHECKDEST( pc + 4 + sh4r.r[Rn] );7.800 + sh4r.in_delay_slot = 1;7.801 + sh4r.pr = sh4r.pc + 4;7.802 + sh4r.pc = sh4r.new_pc;7.803 + sh4r.new_pc = pc + 4 + sh4r.r[Rn];7.804 + TRACE_CALL( pc, sh4r.new_pc );7.805 + return TRUE;7.806 +:}7.807 +BT disp {:7.808 + CHECKSLOTILLEGAL();7.809 + if( sh4r.t ) {7.810 + CHECKDEST( sh4r.pc + disp + 4 )7.811 + sh4r.pc += disp + 4;7.812 + sh4r.new_pc = sh4r.pc + 2;7.813 + return TRUE;7.814 + }7.815 +:}7.816 +BF disp {:7.817 + CHECKSLOTILLEGAL();7.818 + if( !sh4r.t ) {7.819 + CHECKDEST( sh4r.pc + disp + 4 )7.820 + sh4r.pc += disp + 4;7.821 + sh4r.new_pc = sh4r.pc + 2;7.822 + return TRUE;7.823 + }7.824 +:}7.825 +BT/S disp {:7.826 + CHECKSLOTILLEGAL();7.827 + if( sh4r.t ) {7.828 + CHECKDEST( sh4r.pc + disp + 4 )7.829 + sh4r.in_delay_slot = 1;7.830 + sh4r.pc = sh4r.new_pc;7.831 + sh4r.new_pc = pc + disp + 4;7.832 + sh4r.in_delay_slot = 1;7.833 + return TRUE;7.834 + }7.835 +:}7.836 +BF/S disp {:7.837 + CHECKSLOTILLEGAL();7.838 + if( !sh4r.t ) {7.839 + CHECKDEST( sh4r.pc + disp + 4 )7.840 + sh4r.in_delay_slot = 1;7.841 + sh4r.pc = sh4r.new_pc;7.842 + sh4r.new_pc = pc + disp + 4;7.843 + return TRUE;7.844 + }7.845 +:}7.846 +BRA disp {:7.847 + CHECKSLOTILLEGAL();7.848 + CHECKDEST( sh4r.pc + disp + 4 );7.849 + sh4r.in_delay_slot = 1;7.850 + sh4r.pc = sh4r.new_pc;7.851 + sh4r.new_pc = pc + 4 + disp;7.852 + return TRUE;7.853 +:}7.854 +BSR disp {:7.855 + CHECKDEST( sh4r.pc + disp + 4 );7.856 + CHECKSLOTILLEGAL();7.857 + sh4r.in_delay_slot = 1;7.858 + sh4r.pr = pc + 4;7.859 + sh4r.pc = sh4r.new_pc;7.860 + sh4r.new_pc = pc + 4 + disp;7.861 + TRACE_CALL( pc, sh4r.new_pc );7.862 + return TRUE;7.863 +:}7.864 +TRAPA #imm {:7.865 + CHECKSLOTILLEGAL();7.866 + MMIO_WRITE( MMU, TRA, imm<<2 );7.867 + sh4r.pc += 2;7.868 + sh4_raise_exception( EXC_TRAP );7.869 +:}7.870 +RTS {:7.871 + CHECKSLOTILLEGAL();7.872 + CHECKDEST( sh4r.pr );7.873 + sh4r.in_delay_slot = 1;7.874 + sh4r.pc = sh4r.new_pc;7.875 + sh4r.new_pc = sh4r.pr;7.876 + TRACE_RETURN( pc, sh4r.new_pc );7.877 + return TRUE;7.878 +:}7.879 +SLEEP {:7.880 + if( MMIO_READ( CPG, STBCR ) & 0x80 ) {7.881 + sh4r.sh4_state = SH4_STATE_STANDBY;7.882 + } else {7.883 + sh4r.sh4_state = SH4_STATE_SLEEP;7.884 + }7.885 + return FALSE; /* Halt CPU */7.886 +:}7.887 +RTE {:7.888 + CHECKPRIV();7.889 + CHECKDEST( sh4r.spc );7.890 + CHECKSLOTILLEGAL();7.891 + sh4r.in_delay_slot = 1;7.892 + sh4r.pc = sh4r.new_pc;7.893 + sh4r.new_pc = sh4r.spc;7.894 + sh4_load_sr( sh4r.ssr );7.895 + return TRUE;7.896 +:}7.897 +JMP @Rn {:7.898 + CHECKDEST( sh4r.r[Rn] );7.899 + CHECKSLOTILLEGAL();7.900 + sh4r.in_delay_slot = 1;7.901 + sh4r.pc = sh4r.new_pc;7.902 + sh4r.new_pc = sh4r.r[Rn];7.903 + return TRUE;7.904 +:}7.905 +JSR @Rn {:7.906 + CHECKDEST( sh4r.r[Rn] );7.907 + CHECKSLOTILLEGAL();7.908 + sh4r.in_delay_slot = 1;7.909 + sh4r.pc = sh4r.new_pc;7.910 + sh4r.new_pc = sh4r.r[Rn];7.911 + sh4r.pr = pc + 4;7.912 + TRACE_CALL( pc, sh4r.new_pc );7.913 + return TRUE;7.914 +:}7.915 +STS MACH, Rn {: sh4r.r[Rn] = (sh4r.mac>>32); :}7.916 +STS.L MACH, @-Rn {:7.917 + sh4r.r[Rn] -= 4;7.918 + CHECKWALIGN32( sh4r.r[Rn] );7.919 + MEM_WRITE_LONG( sh4r.r[Rn], (sh4r.mac>>32) );7.920 +:}7.921 +STC.L SR, @-Rn {:7.922 + CHECKPRIV();7.923 + sh4r.r[Rn] -= 4;7.924 + CHECKWALIGN32( sh4r.r[Rn] );7.925 + MEM_WRITE_LONG( sh4r.r[Rn], sh4_read_sr() );7.926 +:}7.927 +LDS.L @Rm+, MACH {:7.928 + CHECKRALIGN32( sh4r.r[Rm] );7.929 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |7.930 + (((uint64_t)MEM_READ_LONG(sh4r.r[Rm]))<<32);7.931 + sh4r.r[Rm] += 4;7.932 +:}7.933 +LDC.L @Rm+, SR {:7.934 + CHECKSLOTILLEGAL();7.935 + CHECKPRIV();7.936 + CHECKWALIGN32( sh4r.r[Rm] );7.937 + sh4_load_sr( MEM_READ_LONG(sh4r.r[Rm]) );7.938 + sh4r.r[Rm] +=4;7.939 +:}7.940 +LDS Rm, MACH {:7.941 + sh4r.mac = (sh4r.mac & 0x00000000FFFFFFFF) |7.942 + (((uint64_t)sh4r.r[Rm])<<32);7.943 +:}7.944 +LDC Rm, SR {:7.945 + CHECKSLOTILLEGAL();7.946 + CHECKPRIV();7.947 + sh4_load_sr( sh4r.r[Rm] );7.948 +:}7.949 +LDC Rm, SGR {:7.950 + CHECKPRIV();7.951 + sh4r.sgr = sh4r.r[Rm];7.952 +:}7.953 +LDC.L @Rm+, SGR {:7.954 + CHECKPRIV();7.955 + CHECKRALIGN32( sh4r.r[Rm] );7.956 + sh4r.sgr = MEM_READ_LONG(sh4r.r[Rm]);7.957 + sh4r.r[Rm] +=4;7.958 +:}7.959 +STS MACL, Rn {: sh4r.r[Rn] = (uint32_t)sh4r.mac; :}7.960 +STS.L MACL, @-Rn {:7.961 + sh4r.r[Rn] -= 4;7.962 + CHECKWALIGN32( sh4r.r[Rn] );7.963 + MEM_WRITE_LONG( sh4r.r[Rn], (uint32_t)sh4r.mac );7.964 +:}7.965 +STC.L GBR, @-Rn {:7.966 + sh4r.r[Rn] -= 4;7.967 + CHECKWALIGN32( sh4r.r[Rn] );7.968 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.gbr );7.969 +:}7.970 +LDS.L @Rm+, MACL {:7.971 + CHECKRALIGN32( sh4r.r[Rm] );7.972 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |7.973 + (uint64_t)((uint32_t)MEM_READ_LONG(sh4r.r[Rm]));7.974 + sh4r.r[Rm] += 4;7.975 +:}7.976 +LDC.L @Rm+, GBR {:7.977 + CHECKRALIGN32( sh4r.r[Rm] );7.978 + sh4r.gbr = MEM_READ_LONG(sh4r.r[Rm]);7.979 + sh4r.r[Rm] +=4;7.980 +:}7.981 +LDS Rm, MACL {:7.982 + sh4r.mac = (sh4r.mac & 0xFFFFFFFF00000000LL) |7.983 + (uint64_t)((uint32_t)(sh4r.r[Rm]));7.984 +:}7.985 +LDC Rm, GBR {: sh4r.gbr = sh4r.r[Rm]; :}7.986 +STS PR, Rn {: sh4r.r[Rn] = sh4r.pr; :}7.987 +STS.L PR, @-Rn {:7.988 + sh4r.r[Rn] -= 4;7.989 + CHECKWALIGN32( sh4r.r[Rn] );7.990 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.pr );7.991 +:}7.992 +STC.L VBR, @-Rn {:7.993 + CHECKPRIV();7.994 + sh4r.r[Rn] -= 4;7.995 + CHECKWALIGN32( sh4r.r[Rn] );7.996 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.vbr );7.997 +:}7.998 +LDS.L @Rm+, PR {:7.999 + CHECKRALIGN32( sh4r.r[Rm] );7.1000 + sh4r.pr = MEM_READ_LONG( sh4r.r[Rm] );7.1001 + sh4r.r[Rm] += 4;7.1002 +:}7.1003 +LDC.L @Rm+, VBR {:7.1004 + CHECKPRIV();7.1005 + CHECKRALIGN32( sh4r.r[Rm] );7.1006 + sh4r.vbr = MEM_READ_LONG(sh4r.r[Rm]);7.1007 + sh4r.r[Rm] +=4;7.1008 +:}7.1009 +LDS Rm, PR {: sh4r.pr = sh4r.r[Rm]; :}7.1010 +LDC Rm, VBR {:7.1011 + CHECKPRIV();7.1012 + sh4r.vbr = sh4r.r[Rm];7.1013 +:}7.1014 +STC SGR, Rn {:7.1015 + CHECKPRIV();7.1016 + sh4r.r[Rn] = sh4r.sgr;7.1017 +:}7.1018 +STC.L SGR, @-Rn {:7.1019 + CHECKPRIV();7.1020 + sh4r.r[Rn] -= 4;7.1021 + CHECKWALIGN32( sh4r.r[Rn] );7.1022 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.sgr );7.1023 +:}7.1024 +STC.L SSR, @-Rn {:7.1025 + CHECKPRIV();7.1026 + sh4r.r[Rn] -= 4;7.1027 + CHECKWALIGN32( sh4r.r[Rn] );7.1028 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.ssr );7.1029 +:}7.1030 +LDC.L @Rm+, SSR {:7.1031 + CHECKPRIV();7.1032 + CHECKRALIGN32( sh4r.r[Rm] );7.1033 + sh4r.ssr = MEM_READ_LONG(sh4r.r[Rm]);7.1034 + sh4r.r[Rm] +=4;7.1035 +:}7.1036 +LDC Rm, SSR {:7.1037 + CHECKPRIV();7.1038 + sh4r.ssr = sh4r.r[Rm];7.1039 +:}7.1040 +STC.L SPC, @-Rn {:7.1041 + CHECKPRIV();7.1042 + sh4r.r[Rn] -= 4;7.1043 + CHECKWALIGN32( sh4r.r[Rn] );7.1044 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.spc );7.1045 +:}7.1046 +LDC.L @Rm+, SPC {:7.1047 + CHECKPRIV();7.1048 + CHECKRALIGN32( sh4r.r[Rm] );7.1049 + sh4r.spc = MEM_READ_LONG(sh4r.r[Rm]);7.1050 + sh4r.r[Rm] +=4;7.1051 +:}7.1052 +LDC Rm, SPC {:7.1053 + CHECKPRIV();7.1054 + sh4r.spc = sh4r.r[Rm];7.1055 +:}7.1056 +STS FPUL, Rn {: sh4r.r[Rn] = sh4r.fpul; :}7.1057 +STS.L FPUL, @-Rn {:7.1058 + sh4r.r[Rn] -= 4;7.1059 + CHECKWALIGN32( sh4r.r[Rn] );7.1060 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpul );7.1061 +:}7.1062 +LDS.L @Rm+, FPUL {:7.1063 + CHECKRALIGN32( sh4r.r[Rm] );7.1064 + sh4r.fpul = MEM_READ_LONG(sh4r.r[Rm]);7.1065 + sh4r.r[Rm] +=4;7.1066 +:}7.1067 +LDS Rm, FPUL {: sh4r.fpul = sh4r.r[Rm]; :}7.1068 +STS FPSCR, Rn {: sh4r.r[Rn] = sh4r.fpscr; :}7.1069 +STS.L FPSCR, @-Rn {:7.1070 + sh4r.r[Rn] -= 4;7.1071 + CHECKWALIGN32( sh4r.r[Rn] );7.1072 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.fpscr );7.1073 +:}7.1074 +LDS.L @Rm+, FPSCR {:7.1075 + CHECKRALIGN32( sh4r.r[Rm] );7.1076 + sh4r.fpscr = MEM_READ_LONG(sh4r.r[Rm]);7.1077 + sh4r.r[Rm] +=4;7.1078 +:}7.1079 +LDS Rm, FPSCR {: sh4r.fpscr = sh4r.r[Rm]; :}7.1080 +STC DBR, Rn {: CHECKPRIV(); sh4r.r[Rn] = sh4r.dbr; :}7.1081 +STC.L DBR, @-Rn {:7.1082 + CHECKPRIV();7.1083 + sh4r.r[Rn] -= 4;7.1084 + CHECKWALIGN32( sh4r.r[Rn] );7.1085 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.dbr );7.1086 +:}7.1087 +LDC.L @Rm+, DBR {:7.1088 + CHECKPRIV();7.1089 + CHECKRALIGN32( sh4r.r[Rm] );7.1090 + sh4r.dbr = MEM_READ_LONG(sh4r.r[Rm]);7.1091 + sh4r.r[Rm] +=4;7.1092 +:}7.1093 +LDC Rm, DBR {:7.1094 + CHECKPRIV();7.1095 + sh4r.dbr = sh4r.r[Rm];7.1096 +:}7.1097 +STC.L Rm_BANK, @-Rn {:7.1098 + CHECKPRIV();7.1099 + sh4r.r[Rn] -= 4;7.1100 + CHECKWALIGN32( sh4r.r[Rn] );7.1101 + MEM_WRITE_LONG( sh4r.r[Rn], sh4r.r_bank[Rm_BANK] );7.1102 +:}7.1103 +LDC.L @Rm+, Rn_BANK {:7.1104 + CHECKPRIV();7.1105 + CHECKRALIGN32( sh4r.r[Rm] );7.1106 + sh4r.r_bank[Rn_BANK] = MEM_READ_LONG( sh4r.r[Rm] );7.1107 + sh4r.r[Rm] += 4;7.1108 +:}7.1109 +LDC Rm, Rn_BANK {:7.1110 + CHECKPRIV();7.1111 + sh4r.r_bank[Rn_BANK] = sh4r.r[Rm];7.1112 +:}7.1113 +STC SR, Rn {:7.1114 + CHECKPRIV();7.1115 + sh4r.r[Rn] = sh4_read_sr();7.1116 +:}7.1117 +STC GBR, Rn {:7.1118 + CHECKPRIV();7.1119 + sh4r.r[Rn] = sh4r.gbr;7.1120 +:}7.1121 +STC VBR, Rn {:7.1122 + CHECKPRIV();7.1123 + sh4r.r[Rn] = sh4r.vbr;7.1124 +:}7.1125 +STC SSR, Rn {:7.1126 + CHECKPRIV();7.1127 + sh4r.r[Rn] = sh4r.ssr;7.1128 +:}7.1129 +STC SPC, Rn {:7.1130 + CHECKPRIV();7.1131 + sh4r.r[Rn] = sh4r.spc;7.1132 +:}7.1133 +STC Rm_BANK, Rn {:7.1134 + CHECKPRIV();7.1135 + sh4r.r[Rn] = sh4r.r_bank[Rm_BANK];7.1136 +:}7.1137 +7.1138 +FADD FRm, FRn {:7.1139 + CHECKFPUEN();7.1140 + if( IS_FPU_DOUBLEPREC() ) {7.1141 + DR(FRn) += DR(FRm);7.1142 + } else {7.1143 + FR(FRn) += FR(FRm);7.1144 + }7.1145 +:}7.1146 +FSUB FRm, FRn {:7.1147 + CHECKFPUEN();7.1148 + if( IS_FPU_DOUBLEPREC() ) {7.1149 + DR(FRn) -= DR(FRm);7.1150 + } else {7.1151 + FR(FRn) -= FR(FRm);7.1152 + }7.1153 +:}7.1154 +7.1155 +FMUL FRm, FRn {:7.1156 + CHECKFPUEN();7.1157 + if( IS_FPU_DOUBLEPREC() ) {7.1158 + DR(FRn) *= DR(FRm);7.1159 + } else {7.1160 + FR(FRn) *= FR(FRm);7.1161 + }7.1162 +:}7.1163 +7.1164 +FDIV FRm, FRn {:7.1165 + CHECKFPUEN();7.1166 + if( IS_FPU_DOUBLEPREC() ) {7.1167 + DR(FRn) /= DR(FRm);7.1168 + } else {7.1169 + FR(FRn) /= FR(FRm);7.1170 + }7.1171 +:}7.1172 +7.1173 +FCMP/EQ FRm, FRn {:7.1174 + CHECKFPUEN();7.1175 + if( IS_FPU_DOUBLEPREC() ) {7.1176 + sh4r.t = ( DR(FRn) == DR(FRm) ? 1 : 0 );7.1177 + } else {7.1178 + sh4r.t = ( FR(FRn) == FR(FRm) ? 1 : 0 );7.1179 + }7.1180 +:}7.1181 +7.1182 +FCMP/GT FRm, FRn {:7.1183 + CHECKFPUEN();7.1184 + if( IS_FPU_DOUBLEPREC() ) {7.1185 + sh4r.t = ( DR(FRn) > DR(FRm) ? 1 : 0 );7.1186 + } else {7.1187 + sh4r.t = ( FR(FRn) > FR(FRm) ? 1 : 0 );7.1188 + }7.1189 +:}7.1190 +7.1191 +FMOV @(R0, Rm), FRn {: MEM_FP_READ( sh4r.r[Rm] + R0, FRn ); :}7.1192 +FMOV FRm, @(R0, Rn) {: MEM_FP_WRITE( sh4r.r[Rn] + R0, FRm ); :}7.1193 +FMOV @Rm, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); :}7.1194 +FMOV @Rm+, FRn {: MEM_FP_READ( sh4r.r[Rm], FRn ); sh4r.r[Rm] += FP_WIDTH; :}7.1195 +FMOV FRm, @Rn {: MEM_FP_WRITE( sh4r.r[Rn], FRm ); :}7.1196 +FMOV FRm, @-Rn {: sh4r.r[Rn] -= FP_WIDTH; MEM_FP_WRITE( sh4r.r[Rn], FRm ); :}7.1197 +FMOV FRm, FRn {:7.1198 + if( IS_FPU_DOUBLESIZE() )7.1199 + DR(FRn) = DR(FRm);7.1200 + else7.1201 + FR(FRn) = FR(FRm);7.1202 +:}7.1203 +FSTS FPUL, FRn {: CHECKFPUEN(); FR(FRn) = FPULf; :}7.1204 +FLDS FRm, FPUL {: CHECKFPUEN(); FPULf = FR(FRm); :}7.1205 +FLOAT FPUL, FRn {:7.1206 + CHECKFPUEN();7.1207 + if( IS_FPU_DOUBLEPREC() )7.1208 + DR(FRn) = (float)FPULi;7.1209 + else7.1210 + FR(FRn) = (float)FPULi;7.1211 +:}7.1212 +FTRC FRm, FPUL {:7.1213 + CHECKFPUEN();7.1214 + if( IS_FPU_DOUBLEPREC() ) {7.1215 + dtmp = DR(FRm);7.1216 + if( dtmp >= MAX_INTF )7.1217 + FPULi = MAX_INT;7.1218 + else if( dtmp <= MIN_INTF )7.1219 + FPULi = MIN_INT;7.1220 + else7.1221 + FPULi = (int32_t)dtmp;7.1222 + } else {7.1223 + ftmp = FR(FRm);7.1224 + if( ftmp >= MAX_INTF )7.1225 + FPULi = MAX_INT;7.1226 + else if( ftmp <= MIN_INTF )7.1227 + FPULi = MIN_INT;7.1228 + else7.1229 + FPULi = (int32_t)ftmp;7.1230 + }7.1231 +:}7.1232 +FNEG FRn {:7.1233 + CHECKFPUEN();7.1234 + if( IS_FPU_DOUBLEPREC() ) {7.1235 + DR(FRn) = -DR(FRn);7.1236 + } else {7.1237 + FR(FRn) = -FR(FRn);7.1238 + }7.1239 +:}7.1240 +FABS FRn {:7.1241 + CHECKFPUEN();7.1242 + if( IS_FPU_DOUBLEPREC() ) {7.1243 + DR(FRn) = fabs(DR(FRn));7.1244 + } else {7.1245 + FR(FRn) = fabsf(FR(FRn));7.1246 + }7.1247 +:}7.1248 +FSQRT FRn {:7.1249 + CHECKFPUEN();7.1250 + if( IS_FPU_DOUBLEPREC() ) {7.1251 + DR(FRn) = sqrt(DR(FRn));7.1252 + } else {7.1253 + FR(FRn) = sqrtf(FR(FRn));7.1254 + }7.1255 +:}7.1256 +FLDI0 FRn {:7.1257 + CHECKFPUEN();7.1258 + if( IS_FPU_DOUBLEPREC() ) {7.1259 + DR(FRn) = 0.0;7.1260 + } else {7.1261 + FR(FRn) = 0.0;7.1262 + }7.1263 +:}7.1264 +FLDI1 FRn {:7.1265 + CHECKFPUEN();7.1266 + if( IS_FPU_DOUBLEPREC() ) {7.1267 + DR(FRn) = 1.0;7.1268 + } else {7.1269 + FR(FRn) = 1.0;7.1270 + }7.1271 +:}7.1272 +FMAC FR0, FRm, FRn {:7.1273 + CHECKFPUEN();7.1274 + if( IS_FPU_DOUBLEPREC() ) {7.1275 + DR(FRn) += DR(FRm)*DR(0);7.1276 + } else {7.1277 + FR(FRn) += FR(FRm)*FR(0);7.1278 + }7.1279 +:}7.1280 +FRCHG {: CHECKFPUEN(); sh4r.fpscr ^= FPSCR_FR; :}7.1281 +FSCHG {: CHECKFPUEN(); sh4r.fpscr ^= FPSCR_SZ; :}7.1282 +FCNVSD FPUL, FRn {:7.1283 + CHECKFPUEN();7.1284 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {7.1285 + DR(FRn) = (double)FPULf;7.1286 + }7.1287 +:}7.1288 +FCNVDS FRm, FPUL {:7.1289 + CHECKFPUEN();7.1290 + if( IS_FPU_DOUBLEPREC() && !IS_FPU_DOUBLESIZE() ) {7.1291 + FPULf = (float)DR(FRm);7.1292 + }7.1293 +:}7.1294 +7.1295 +FSRRA FRn {:7.1296 + CHECKFPUEN();7.1297 + if( !IS_FPU_DOUBLEPREC() ) {7.1298 + FR(FRn) = 1.0/sqrtf(FR(FRn));7.1299 + }7.1300 +:}7.1301 +FIPR FVm, FVn {:7.1302 + CHECKFPUEN();7.1303 + if( !IS_FPU_DOUBLEPREC() ) {7.1304 + int tmp2 = FVn<<2;7.1305 + tmp = FVm<<2;7.1306 + FR(tmp2+3) = FR(tmp)*FR(tmp2) +7.1307 + FR(tmp+1)*FR(tmp2+1) +7.1308 + FR(tmp+2)*FR(tmp2+2) +7.1309 + FR(tmp+3)*FR(tmp2+3);7.1310 + }7.1311 +:}7.1312 +FSCA FPUL, FRn {:7.1313 + CHECKFPUEN();7.1314 + if( !IS_FPU_DOUBLEPREC() ) {7.1315 + float angle = (((float)(FPULi&0xFFFF))/65536.0) * 2 * M_PI;7.1316 + FR(FRn) = sinf(angle);7.1317 + FR((FRn)+1) = cosf(angle);7.1318 + }7.1319 +:}7.1320 +FTRV XMTRX, FVn {:7.1321 + CHECKFPUEN();7.1322 + if( !IS_FPU_DOUBLEPREC() ) {7.1323 + tmp = FVn<<2;7.1324 + float fv[4] = { FR(tmp), FR(tmp+1), FR(tmp+2), FR(tmp+3) };7.1325 + FR(tmp) = XF(0) * fv[0] + XF(4)*fv[1] +7.1326 + XF(8)*fv[2] + XF(12)*fv[3];7.1327 + FR(tmp+1) = XF(1) * fv[0] + XF(5)*fv[1] +7.1328 + XF(9)*fv[2] + XF(13)*fv[3];7.1329 + FR(tmp+2) = XF(2) * fv[0] + XF(6)*fv[1] +7.1330 + XF(10)*fv[2] + XF(14)*fv[3];7.1331 + FR(tmp+3) = XF(3) * fv[0] + XF(7)*fv[1] +7.1332 + XF(11)*fv[2] + XF(15)*fv[3];7.1333 + }7.1334 +:}7.1335 +UNDEF {:7.1336 + UNDEF(ir);7.1337 +:}7.1338 +%%7.1339 + sh4r.pc = sh4r.new_pc;7.1340 + sh4r.new_pc += 2;7.1341 + sh4r.in_delay_slot = 0;7.1342 + return TRUE;7.1343 +}
8.1 --- a/src/sh4/sh4dasm.c Thu Aug 23 12:31:31 2007 +00008.2 +++ b/src/sh4/sh4dasm.c Thu Aug 23 12:33:27 2007 +00008.3 @@ -1,5 +1,5 @@8.4 /**8.5 - * $Id: sh4dasm.c,v 1.10 2007-01-17 21:27:20 nkeynes Exp $8.6 + * $Id: sh4dasm.c,v 1.11 2007-08-23 12:33:27 nkeynes Exp $8.7 *8.8 * SH4 CPU definition and disassembly functions8.9 *8.10 @@ -51,7 +51,8 @@8.11 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )8.12 {8.13 uint16_t ir = sh4_read_word(pc);8.14 -8.15 +8.16 +#define UNDEF(ir) snprintf( buf, len, "???? " );8.17 #define RN(ir) ((ir&0x0F00)>>8)8.18 #define RN_BANK(ir) ((ir&0x0070)>>4)8.19 #define RM(ir) ((ir&0x00F0)>>4)8.20 @@ -66,316 +67,1485 @@8.22 sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );8.24 - switch( (ir&0xF000)>>12 ) {8.25 - case 0: /* 0000nnnnmmmmxxxx */8.26 - switch( ir&0x000F ) {8.27 - case 2:8.28 - switch( (ir&0x00F0)>>4 ) {8.29 - case 0: snprintf( buf, len, "STC SR, R%d", RN(ir) ); break;8.30 - case 1: snprintf( buf, len, "STC GBR, R%d", RN(ir) ); break;8.31 - case 2: snprintf( buf, len, "STC VBR, R%d", RN(ir) ); break;8.32 - case 3: snprintf( buf, len, "STC SSR, R%d", RN(ir) ); break;8.33 - case 4: snprintf( buf, len, "STC SPC, R%d", RN(ir) ); break;8.34 - case 8: case 9: case 10: case 11: case 12: case 13: case 14:8.35 - case 15:snprintf( buf, len, "STC R%d_bank, R%d", RN_BANK(ir), RN(ir) ); break;8.36 - default: UNIMP(ir);8.37 - }8.38 - break;8.39 - case 3:8.40 - switch( (ir&0x00F0)>>4 ) {8.41 - case 0: snprintf( buf, len, "BSRF R%d", RN(ir) ); break;8.42 - case 2: snprintf( buf, len, "BRAF R%d", RN(ir) ); break;8.43 - case 8: snprintf( buf, len, "PREF [R%d]", RN(ir) ); break;8.44 - case 9: snprintf( buf, len, "OCBI [R%d]", RN(ir) ); break;8.45 - case 10:snprintf( buf, len, "OCBP [R%d]", RN(ir) ); break;8.46 - case 11:snprintf( buf, len, "OCBWB [R%d]", RN(ir) ); break;8.47 - case 12:snprintf( buf, len, "MOVCA.L R0, [R%d]", RN(ir) ); break;8.48 - default: UNIMP(ir);8.49 - }8.50 - break;8.51 - case 4: snprintf( buf, len, "MOV.B R%d, [R0+R%d]", RM(ir), RN(ir) ); break;8.52 - case 5: snprintf( buf, len, "MOV.W R%d, [R0+R%d]", RM(ir), RN(ir) ); break;8.53 - case 6: snprintf( buf, len, "MOV.L R%d, [R0+R%d]", RM(ir), RN(ir) ); break;8.54 - case 7: snprintf( buf, len, "MUL.L R%d, R%d", RM(ir), RN(ir) ); break;8.55 - case 8:8.56 - switch( (ir&0x0FF0)>>4 ) {8.57 - case 0: snprintf( buf, len, "CLRT " ); break;8.58 - case 1: snprintf( buf, len, "SETT " ); break;8.59 - case 2: snprintf( buf, len, "CLRMAC " ); break;8.60 - case 3: snprintf( buf, len, "LDTLB " ); break;8.61 - case 4: snprintf( buf, len, "CLRS " ); break;8.62 - case 5: snprintf( buf, len, "SETS " ); break;8.63 - default: UNIMP(ir);8.64 - }8.65 - break;8.66 - case 9:8.67 - if( (ir&0x00F0) == 0x20 )8.68 - snprintf( buf, len, "MOVT R%d", RN(ir) );8.69 - else if( ir == 0x0019 )8.70 - snprintf( buf, len, "DIV0U " );8.71 - else if( ir == 0x0009 )8.72 - snprintf( buf, len, "NOP " );8.73 - else UNIMP(ir);8.74 - break;8.75 - case 10:8.76 - switch( (ir&0x00F0) >> 4 ) {8.77 - case 0: snprintf( buf, len, "STS MACH, R%d", RN(ir) ); break;8.78 - case 1: snprintf( buf, len, "STS MACL, R%d", RN(ir) ); break;8.79 - case 2: snprintf( buf, len, "STS PR, R%d", RN(ir) ); break;8.80 - case 3: snprintf( buf, len, "STC SGR, R%d", RN(ir) ); break;8.81 - case 5: snprintf( buf, len, "STS FPUL, R%d", RN(ir) ); break;8.82 - case 6: snprintf( buf, len, "STS FPSCR, R%d", RN(ir) ); break;8.83 - case 15:snprintf( buf, len, "STC DBR, R%d", RN(ir) ); break;8.84 - default: UNIMP(ir);8.85 - }8.86 - break;8.87 - case 11:8.88 - switch( (ir&0x0FF0)>>4 ) {8.89 - case 0: snprintf( buf, len, "RTS " ); break;8.90 - case 1: snprintf( buf, len, "SLEEP " ); break;8.91 - case 2: snprintf( buf, len, "RTE " ); break;8.92 - default:UNIMP(ir);8.93 - }8.94 - break;8.95 - case 12:snprintf( buf, len, "MOV.B [R0+R%d], R%d", RM(ir), RN(ir) ); break;8.96 - case 13:snprintf( buf, len, "MOV.W [R0+R%d], R%d", RM(ir), RN(ir) ); break;8.97 - case 14:snprintf( buf, len, "MOV.L [R0+R%d], R%d", RM(ir), RN(ir) ); break;8.98 - case 15:snprintf( buf, len, "MAC.L [R%d++], [R%d++]", RM(ir), RN(ir) ); break;8.99 - default: UNIMP(ir);8.100 - }8.101 - break;8.102 - case 1: /* 0001nnnnmmmmdddd */8.103 - snprintf( buf, len, "MOV.L R%d, [R%d%+d]", RM(ir), RN(ir), DISP4(ir)<<2 ); break;8.104 - case 2: /* 0010nnnnmmmmxxxx */8.105 - switch( ir&0x000F ) {8.106 - case 0: snprintf( buf, len, "MOV.B R%d, [R%d]", RM(ir), RN(ir) ); break;8.107 - case 1: snprintf( buf, len, "MOV.W R%d, [R%d]", RM(ir), RN(ir) ); break;8.108 - case 2: snprintf( buf, len, "MOV.L R%d, [R%d]", RM(ir), RN(ir) ); break;8.109 - case 3: UNIMP(ir); break;8.110 - case 4: snprintf( buf, len, "MOV.B R%d, [--R%d]", RM(ir), RN(ir) ); break;8.111 - case 5: snprintf( buf, len, "MOV.W R%d, [--R%d]", RM(ir), RN(ir) ); break;8.112 - case 6: snprintf( buf, len, "MOV.L R%d, [--R%d]", RM(ir), RN(ir) ); break;8.113 - case 7: snprintf( buf, len, "DIV0S R%d, R%d", RM(ir), RN(ir) ); break;8.114 - case 8: snprintf( buf, len, "TST R%d, R%d", RM(ir), RN(ir) ); break;8.115 - case 9: snprintf( buf, len, "AND R%d, R%d", RM(ir), RN(ir) ); break;8.116 - case 10:snprintf( buf, len, "XOR R%d, R%d", RM(ir), RN(ir) ); break;8.117 - case 11:snprintf( buf, len, "OR R%d, R%d", RM(ir), RN(ir) ); break;8.118 - case 12:snprintf( buf, len, "CMP/STR R%d, R%d", RM(ir), RN(ir) ); break;8.119 - case 13:snprintf( buf, len, "XTRCT R%d, R%d", RM(ir), RN(ir) ); break;8.120 - case 14:snprintf( buf, len, "MULU.W R%d, R%d", RM(ir), RN(ir) ); break;8.121 - case 15:snprintf( buf, len, "MULS.W R%d, R%d", RM(ir), RN(ir) ); break;8.122 - }8.123 - break;8.124 - case 3: /* 0011nnnnmmmmxxxx */8.125 - switch( ir&0x000F ) {8.126 - case 0: snprintf( buf, len, "CMP/EQ R%d, R%d", RM(ir), RN(ir) ); break;8.127 - case 2: snprintf( buf, len, "CMP/HS R%d, R%d", RM(ir), RN(ir) ); break;8.128 - case 3: snprintf( buf, len, "CMP/GE R%d, R%d", RM(ir), RN(ir) ); break;8.129 - case 4: snprintf( buf, len, "DIV1 R%d, R%d", RM(ir), RN(ir) ); break;8.130 - case 5: snprintf( buf, len, "DMULU.L R%d, R%d", RM(ir), RN(ir) ); break;8.131 - case 6: snprintf( buf, len, "CMP/HI R%d, R%d", RM(ir), RN(ir) ); break;8.132 - case 7: snprintf( buf, len, "CMP/GT R%d, R%d", RM(ir), RN(ir) ); break;8.133 - case 8: snprintf( buf, len, "SUB R%d, R%d", RM(ir), RN(ir) ); break;8.134 - case 10:snprintf( buf, len, "SUBC R%d, R%d", RM(ir), RN(ir) ); break;8.135 - case 11:snprintf( buf, len, "SUBV R%d, R%d", RM(ir), RN(ir) ); break;8.136 - case 12:snprintf( buf, len, "ADD R%d, R%d", RM(ir), RN(ir) ); break;8.137 - case 13:snprintf( buf, len, "DMULS.L R%d, R%d", RM(ir), RN(ir) ); break;8.138 - case 14:snprintf( buf, len, "ADDC R%d, R%d", RM(ir), RN(ir) ); break;8.139 - case 15:snprintf( buf, len, "ADDV R%d, R%d", RM(ir), RN(ir) ); break;8.140 - default: UNIMP(ir);8.141 - }8.142 - break;8.143 - case 4: /* 0100nnnnxxxxxxxx */8.144 - switch( ir&0x00FF ) {8.145 - case 0x00: snprintf( buf, len, "SHLL R%d", RN(ir) ); break;8.146 - case 0x01: snprintf( buf, len, "SHLR R%d", RN(ir) ); break;8.147 - case 0x02: snprintf( buf, len, "STS.L MACH, [--R%d]", RN(ir) ); break;8.148 - case 0x03: snprintf( buf, len, "STC.L SR, [--R%d]", RN(ir) ); break;8.149 - case 0x04: snprintf( buf, len, "ROTL R%d", RN(ir) ); break;8.150 - case 0x05: snprintf( buf, len, "ROTR R%d", RN(ir) ); break;8.151 - case 0x06: snprintf( buf, len, "LDS.L [R%d++], MACH", RN(ir) ); break;8.152 - case 0x07: snprintf( buf, len, "LDC.L [R%d++], SR", RN(ir) ); break;8.153 - case 0x08: snprintf( buf, len, "SHLL2 R%d", RN(ir) ); break;8.154 - case 0x09: snprintf( buf, len, "SHLR2 R%d", RN(ir) ); break;8.155 - case 0x0A: snprintf( buf, len, "LDS R%d, MACH", RN(ir) ); break;8.156 - case 0x0B: snprintf( buf, len, "JSR [R%d]", RN(ir) ); break;8.157 - case 0x0E: snprintf( buf, len, "LDC R%d, SR", RN(ir) ); break;8.158 - case 0x10: snprintf( buf, len, "DT R%d", RN(ir) ); break;8.159 - case 0x11: snprintf( buf, len, "CMP/PZ R%d", RN(ir) ); break;8.160 - case 0x12: snprintf( buf, len, "STS.L MACL, [--R%d]", RN(ir) ); break;8.161 - case 0x13: snprintf( buf, len, "STC.L GBR, [--R%d]", RN(ir) ); break;8.162 - case 0x15: snprintf( buf, len, "CMP/PL R%d", RN(ir) ); break;8.163 - case 0x16: snprintf( buf, len, "LDS.L [R%d++], MACL", RN(ir) ); break;8.164 - case 0x17: snprintf( buf, len, "LDC.L [R%d++], GBR", RN(ir) ); break;8.165 - case 0x18: snprintf( buf, len, "SHLL8 R%d", RN(ir) ); break;8.166 - case 0x19: snprintf( buf, len, "SHLR8 R%d", RN(ir) ); break;8.167 - case 0x1A: snprintf( buf, len, "LDS R%d, MACL", RN(ir) ); break;8.168 - case 0x1B: snprintf( buf, len, "TAS.B [R%d]", RN(ir) ); break;8.169 - case 0x1E: snprintf( buf, len, "LDC R%d, GBR", RN(ir) ); break;8.170 - case 0x20: snprintf( buf, len, "SHAL R%d", RN(ir) ); break;8.171 - case 0x21: snprintf( buf, len, "SHAR R%d", RN(ir) ); break;8.172 - case 0x22: snprintf( buf, len, "STS.L PR, [--R%d]", RN(ir) ); break;8.173 - case 0x23: snprintf( buf, len, "STC.L VBR, [--R%d]", RN(ir) ); break;8.174 - case 0x24: snprintf( buf, len, "ROTCL R%d", RN(ir) ); break;8.175 - case 0x25: snprintf( buf, len, "ROTCR R%d", RN(ir) ); break;8.176 - case 0x26: snprintf( buf, len, "LDS.L [R%d++], PR", RN(ir) ); break;8.177 - case 0x27: snprintf( buf, len, "LDC.L [R%d++], VBR", RN(ir) ); break;8.178 - case 0x28: snprintf( buf, len, "SHLL16 R%d", RN(ir) ); break;8.179 - case 0x29: snprintf( buf, len, "SHLR16 R%d", RN(ir) ); break;8.180 - case 0x2A: snprintf( buf, len, "LDS R%d, PR", RN(ir) ); break;8.181 - case 0x2B: snprintf( buf, len, "JMP [R%d]", RN(ir) ); break;8.182 - case 0x2E: snprintf( buf, len, "LDC R%d, VBR", RN(ir) ); break;8.183 - case 0x32: snprintf( buf, len, "STC.L SGR, [--R%d]", RN(ir) ); break;8.184 - case 0x33: snprintf( buf, len, "STC.L SSR, [--R%d]", RN(ir) ); break;8.185 - case 0x37: snprintf( buf, len, "LDC.L [R%d++], SSR", RN(ir) ); break;8.186 - case 0x3E: snprintf( buf, len, "LDC R%d, SSR", RN(ir) ); break;8.187 - case 0x43: snprintf( buf, len, "STC.L SPC, [--R%d]", RN(ir) ); break;8.188 - case 0x47: snprintf( buf, len, "LDC.L [R%d++], SPC", RN(ir) ); break;8.189 - case 0x4E: snprintf( buf, len, "LDC R%d, SPC", RN(ir) ); break;8.190 - case 0x52: snprintf( buf, len, "STS.L FPUL, [--R%d]", RN(ir) ); break;8.191 - case 0x56: snprintf( buf, len, "LDS.L [R%d++], FPUL", RN(ir) ); break;8.192 - case 0x5A: snprintf( buf, len, "LDS R%d, FPUL", RN(ir) ); break;8.193 - case 0x62: snprintf( buf, len, "STS.L FPSCR, [--R%d]", RN(ir) ); break;8.194 - case 0x66: snprintf( buf, len, "LDS.L [R%d++], FPSCR", RN(ir) ); break;8.195 - case 0x6A: snprintf( buf, len, "LDS R%d, FPSCR", RN(ir) ); break;8.196 - case 0xF2: snprintf( buf, len, "STC.L DBR, [--R%d]", RN(ir) ); break;8.197 - case 0xF6: snprintf( buf, len, "LDC.L [R%d++], DBR", RN(ir) ); break;8.198 - case 0xFA: snprintf( buf, len, "LDC R%d, DBR", RN(ir) ); break;8.199 - case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3: case 0xD3: case 0xE3:8.200 - case 0xF3: snprintf( buf, len, "STC.L R%d_BANK, [--R%d]", RN_BANK(ir), RN(ir) ); break;8.201 - case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7: case 0xD7: case 0xE7:8.202 - case 0xF7: snprintf( buf, len, "LDC.L [R%d++], R%d_BANK", RN(ir), RN_BANK(ir) ); break;8.203 - case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE: case 0xDE: case 0xEE:8.204 - case 0xFE: snprintf( buf, len, "LDC R%d, R%d_BANK", RN(ir), RN_BANK(ir) ); break;8.205 - default:8.206 - if( (ir&0x000F) == 0x0F ) {8.207 - snprintf( buf, len, "MAC.W [R%d++], [R%d++]", RM(ir), RN(ir) );8.208 - } else if( (ir&0x000F) == 0x0C ) {8.209 - snprintf( buf, len, "SHAD R%d, R%d", RM(ir), RN(ir) );8.210 - } else if( (ir&0x000F) == 0x0D ) {8.211 - snprintf( buf, len, "SHLD R%d, R%d", RM(ir), RN(ir) );8.212 - } else UNIMP(ir);8.213 - }8.214 - break;8.215 - case 5: /* 0101nnnnmmmmdddd */8.216 - snprintf( buf, len, "MOV.L [R%d%+d], R%d", RM(ir), DISP4(ir)<<2, RN(ir) ); break;8.217 - case 6: /* 0110xxxxxxxxxxxx */8.218 - switch( ir&0x000f ) {8.219 - case 0: snprintf( buf, len, "MOV.B [R%d], R%d", RM(ir), RN(ir) ); break;8.220 - case 1: snprintf( buf, len, "MOV.W [R%d], R%d", RM(ir), RN(ir) ); break;8.221 - case 2: snprintf( buf, len, "MOV.L [R%d], R%d", RM(ir), RN(ir) ); break;8.222 - case 3: snprintf( buf, len, "MOV R%d, R%d", RM(ir), RN(ir) ); break;8.223 - case 4: snprintf( buf, len, "MOV.B [R%d++], R%d", RM(ir), RN(ir) ); break;8.224 - case 5: snprintf( buf, len, "MOV.W [R%d++], R%d", RM(ir), RN(ir) ); break;8.225 - case 6: snprintf( buf, len, "MOV.L [R%d++], R%d", RM(ir), RN(ir) ); break;8.226 - case 7: snprintf( buf, len, "NOT R%d, R%d", RM(ir), RN(ir) ); break;8.227 - case 8: snprintf( buf, len, "SWAP.B R%d, R%d", RM(ir), RN(ir) ); break;8.228 - case 9: snprintf( buf, len, "SWAP.W R%d, R%d", RM(ir), RN(ir) ); break;8.229 - case 10:snprintf( buf, len, "NEGC R%d, R%d", RM(ir), RN(ir) ); break;8.230 - case 11:snprintf( buf, len, "NEG R%d, R%d", RM(ir), RN(ir) ); break;8.231 - case 12:snprintf( buf, len, "EXTU.B R%d, R%d", RM(ir), RN(ir) ); break;8.232 - case 13:snprintf( buf, len, "EXTU.W R%d, R%d", RM(ir), RN(ir) ); break;8.233 - case 14:snprintf( buf, len, "EXTS.B R%d, R%d", RM(ir), RN(ir) ); break;8.234 - case 15:snprintf( buf, len, "EXTS.W R%d, R%d", RM(ir), RN(ir) ); break;8.235 - }8.236 - break;8.237 - case 7: /* 0111nnnniiiiiiii */8.238 - snprintf( buf, len, "ADD #%d, R%d", SIGNEXT8(ir&0x00FF), RN(ir) ); break;8.239 - case 8: /* 1000xxxxxxxxxxxx */8.240 - switch( (ir&0x0F00) >> 8 ) {8.241 - case 0: snprintf( buf, len, "MOV.B R0, [R%d%+d]", RM(ir), DISP4(ir) ); break;8.242 - case 1: snprintf( buf, len, "MOV.W R0, [R%d%+d]", RM(ir), DISP4(ir)<<1 ); break;8.243 - case 4: snprintf( buf, len, "MOV.B [R%d%+d], R0", RM(ir), DISP4(ir) ); break;8.244 - case 5: snprintf( buf, len, "MOV.W [R%d%+d], R0", RM(ir), DISP4(ir)<<1 ); break;8.245 - case 8: snprintf( buf, len, "CMP/EQ #%d, R0", IMM8(ir) ); break;8.246 - case 9: snprintf( buf, len, "BT $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;8.247 - case 11:snprintf( buf, len, "BF $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;8.248 - case 13:snprintf( buf, len, "BT/S $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;8.249 - case 15:snprintf( buf, len, "BF/S $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;8.250 - default: UNIMP(ir);8.251 - }8.252 - break;8.253 - case 9: /* 1001xxxxxxxxxxxx */8.254 - snprintf( buf, len, "MOV.W [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<1)+pc+4, RN(ir),8.255 - sh4_read_word( (DISP8(ir)<<1)+pc+4 ) ); break;8.256 - case 10:/* 1010xxxxxxxxxxxx */8.257 - snprintf( buf, len, "BRA $%xh", (DISP12(ir)<<1)+pc+4 ); break;8.258 - case 11:/* 1011xxxxxxxxxxxx */8.259 - snprintf( buf, len, "BSR $%xh", (DISP12(ir)<<1)+pc+4 ); break;8.260 - case 12:/* 1100xxxxdddddddd */8.261 - switch( (ir&0x0F00)>>8 ) {8.262 - case 0: snprintf( buf, len, "MOV.B R0, [GBR%+d]", DISP8(ir) ); break;8.263 - case 1: snprintf( buf, len, "MOV.W R0, [GBR%+d]", DISP8(ir)<<1 ); break;8.264 - case 2: snprintf( buf, len, "MOV.L R0, [GBR%+d]", DISP8(ir)<<2 ); break;8.265 - case 3: snprintf( buf, len, "TRAPA #%d", UIMM8(ir) ); break;8.266 - case 4: snprintf( buf, len, "MOV.B [GBR%+d], R0", DISP8(ir) ); break;8.267 - case 5: snprintf( buf, len, "MOV.W [GBR%+d], R0", DISP8(ir)<<1 ); break;8.268 - case 6: snprintf( buf, len, "MOV.L [GBR%+d], R0", DISP8(ir)<<2 ); break;8.269 - case 7: snprintf( buf, len, "MOVA $%xh, R0", (DISP8(ir)<<2)+(pc&~3)+4 ); break;8.270 - case 8: snprintf( buf, len, "TST #%02Xh, R0", UIMM8(ir) ); break;8.271 - case 9: snprintf( buf, len, "AND #%02Xh, R0", UIMM8(ir) ); break;8.272 - case 10:snprintf( buf, len, "XOR #%02Xh, R0", UIMM8(ir) ); break;8.273 - case 11:snprintf( buf, len, "OR #%02Xh, R0", UIMM8(ir) ); break;8.274 - case 12:snprintf( buf, len, "TST.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;8.275 - case 13:snprintf( buf, len, "AND.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;8.276 - case 14:snprintf( buf, len, "XOR.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;8.277 - case 15:snprintf( buf, len, "OR.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;8.278 - }8.279 - break;8.280 - case 13:/* 1101xxxxxxxxxxxx */8.281 - snprintf( buf, len, "MOV.L [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<2)+(pc&~3)+4, RN(ir),8.282 - sh4_read_long( (DISP8(ir)<<2)+(pc&~3)+4 ) ); break;8.283 - case 14:/* 1110xxxxxxxxxxxx */8.284 - snprintf( buf, len, "MOV #%d, R%d", DISP8(ir), RN(ir)); break;8.285 - case 15:/* 1111xxxxxxxxxxxx */8.286 - switch( ir&0x000F ) {8.287 - case 0: snprintf( buf, len, "FADD FR%d, FR%d", RM(ir), RN(ir) ); break;8.288 - case 1: snprintf( buf, len, "FSUB FR%d, FR%d", RM(ir), RN(ir) ); break;8.289 - case 2: snprintf( buf, len, "FMUL FR%d, FR%d", RM(ir), RN(ir) ); break;8.290 - case 3: snprintf( buf, len, "FDIV FR%d, FR%d", RM(ir), RN(ir) ); break;8.291 - case 4: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", RM(ir), RN(ir) ); break;8.292 - case 5: snprintf( buf, len, "FCMP/GT FR%d, FR%d", RM(ir), RN(ir) ); break;8.293 - case 6: snprintf( buf, len, "FMOV.S [R%d+R0], FR%d", RM(ir), RN(ir) ); break;8.294 - case 7: snprintf( buf, len, "FMOV.S FR%d, [R%d+R0]", RM(ir), RN(ir) ); break;8.295 - case 8: snprintf( buf, len, "FMOV.S [R%d], FR%d", RM(ir), RN(ir) ); break;8.296 - case 9: snprintf( buf, len, "FMOV.S [R%d++], FR%d", RM(ir), RN(ir) ); break;8.297 - case 10:snprintf( buf, len, "FMOV.S FR%d, [R%d]", RM(ir), RN(ir) ); break;8.298 - case 11:snprintf( buf, len, "FMOV.S FR%d, [--R%d]", RM(ir), RN(ir) ); break;8.299 - case 12:snprintf( buf, len, "FMOV FR%d, FR%d", RM(ir), RN(ir) ); break;8.300 - case 13:8.301 - switch( (ir&0x00F0) >> 4 ) {8.302 - case 0: snprintf( buf, len, "FSTS FPUL, FR%d", RN(ir) ); break;8.303 - case 1: snprintf( buf, len, "FLDS FR%d, FPUL", RN(ir) ); break;8.304 - case 2: snprintf( buf, len, "FLOAT FPUL, FR%d", RN(ir) ); break;8.305 - case 3: snprintf( buf, len, "FTRC FR%d, FPUL", RN(ir) ); break;8.306 - case 4: snprintf( buf, len, "FNEG FR%d", RN(ir) ); break;8.307 - case 5: snprintf( buf, len, "FABS FR%d", RN(ir) ); break;8.308 - case 6: snprintf( buf, len, "FSQRT FR%d", RN(ir) ); break;8.309 - case 7: snprintf( buf, len, "FSRRA FR%d", RN(ir) ); break;8.310 - case 8: snprintf( buf, len, "FLDI0 FR%d", RN(ir) ); break;8.311 - case 9: snprintf( buf, len, "FLDI1 FR%d", RN(ir) ); break;8.312 - case 10:snprintf( buf, len, "FCNVSD FPUL, DR%d", RN(ir)>>1 ); break;8.313 - case 11:snprintf( buf, len, "FCNVDS DR%d, FPUL", RN(ir)>>1 ); break;8.314 - case 14:snprintf( buf, len, "FIPR FV%d, FV%d", FVM(ir), FVN(ir) ); break;8.315 - case 15:8.316 - if( (ir & 0x0300) == 0x0100 )8.317 - snprintf( buf, len, "FTRV XMTRX,FV%d", FVN(ir) );8.318 - else if( (ir & 0x0100) == 0 )8.319 - snprintf( buf, len, "FSCA FPUL, DR%d", RN(ir) );8.320 - else if( ir == 0xFBFD )8.321 - snprintf( buf, len, "FRCHG " );8.322 - else if( ir == 0xF3FD )8.323 - snprintf( buf, len, "FSCHG " );8.324 - else UNIMP(ir);8.325 - break;8.326 - default: UNIMP(ir);8.327 - }8.328 - break;8.329 - case 14:snprintf( buf, len, "FMAC FR0, FR%d, FR%d", RM(ir), RN(ir) ); break;8.330 - default: UNIMP(ir);8.331 - }8.332 - break;8.333 - }8.334 + switch( (ir&0xF000) >> 12 ) {8.335 + case 0x0:8.336 + switch( ir&0xF ) {8.337 + case 0x2:8.338 + switch( (ir&0x80) >> 7 ) {8.339 + case 0x0:8.340 + switch( (ir&0x70) >> 4 ) {8.341 + case 0x0:8.342 + { /* STC SR, Rn */8.343 + uint32_t Rn = ((ir>>8)&0xF);8.344 + snprintf( buf, len, "STC SR, R%d", Rn );8.345 + }8.346 + break;8.347 + case 0x1:8.348 + { /* STC GBR, Rn */8.349 + uint32_t Rn = ((ir>>8)&0xF);8.350 + snprintf( buf, len, "STC GBR, R%d", Rn );8.351 + }8.352 + break;8.353 + case 0x2:8.354 + { /* STC VBR, Rn */8.355 + uint32_t Rn = ((ir>>8)&0xF);8.356 + snprintf( buf, len, "STC VBR, R%d", Rn );8.357 + }8.358 + break;8.359 + case 0x3:8.360 + { /* STC SSR, Rn */8.361 + uint32_t Rn = ((ir>>8)&0xF);8.362 + snprintf( buf, len, "STC SSR, R%d", Rn );8.363 + }8.364 + break;8.365 + case 0x4:8.366 + { /* STC SPC, Rn */8.367 + uint32_t Rn = ((ir>>8)&0xF);8.368 + snprintf( buf, len, "STC SPC, R%d", Rn );8.369 + }8.370 + break;8.371 + default:8.372 + UNDEF();8.373 + break;8.374 + }8.375 + break;8.376 + case 0x1:8.377 + { /* STC Rm_BANK, Rn */8.378 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);8.379 + snprintf( buf, len, "STC R%d_BANK, R%d", Rm_BANK, Rn );8.380 + }8.381 + break;8.382 + }8.383 + break;8.384 + case 0x3:8.385 + switch( (ir&0xF0) >> 4 ) {8.386 + case 0x0:8.387 + { /* BSRF Rn */8.388 + uint32_t Rn = ((ir>>8)&0xF);8.389 + snprintf( buf, len, "BSRF R%d", Rn );8.390 + }8.391 + break;8.392 + case 0x2:8.393 + { /* BRAF Rn */8.394 + uint32_t Rn = ((ir>>8)&0xF);8.395 + snprintf( buf, len, "BRAF R%d", Rn );8.396 + }8.397 + break;8.398 + case 0x8:8.399 + { /* PREF @Rn */8.400 + uint32_t Rn = ((ir>>8)&0xF);8.401 + snprintf( buf, len, "PREF R%d", Rn );8.402 + }8.403 + break;8.404 + case 0x9:8.405 + { /* OCBI @Rn */8.406 + uint32_t Rn = ((ir>>8)&0xF);8.407 + snprintf( buf, len, "OCBI @R%d", Rn );8.408 + }8.409 + break;8.410 + case 0xA:8.411 + { /* OCBP @Rn */8.412 + uint32_t Rn = ((ir>>8)&0xF);8.413 + snprintf( buf, len, "OCBP @R%d", Rn );8.414 + }8.415 + break;8.416 + case 0xB:8.417 + { /* OCBWB @Rn */8.418 + uint32_t Rn = ((ir>>8)&0xF);8.419 + snprintf( buf, len, "OCBWB @R%d", Rn );8.420 + }8.421 + break;8.422 + case 0xC:8.423 + { /* MOVCA.L R0, @Rn */8.424 + uint32_t Rn = ((ir>>8)&0xF);8.425 + snprintf( buf, len, "MOVCA.L R0, @R%d", Rn );8.426 + }8.427 + break;8.428 + default:8.429 + UNDEF();8.430 + break;8.431 + }8.432 + break;8.433 + case 0x4:8.434 + { /* MOV.B Rm, @(R0, Rn) */8.435 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.436 + snprintf( buf, len, "MOV.B R%d, @(R0, R%d)", Rm, Rn );8.437 + }8.438 + break;8.439 + case 0x5:8.440 + { /* MOV.W Rm, @(R0, Rn) */8.441 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.442 + snprintf( buf, len, "MOV.W R%d, @(R0, R%d)", Rm, Rn );8.443 + }8.444 + break;8.445 + case 0x6:8.446 + { /* MOV.L Rm, @(R0, Rn) */8.447 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.448 + snprintf( buf, len, "MOV.L R%d, @(R0, R%d)", Rm, Rn );8.449 + }8.450 + break;8.451 + case 0x7:8.452 + { /* MUL.L Rm, Rn */8.453 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.454 + snprintf( buf, len, "MUL.L R%d, R%d", Rm, Rn );8.455 + }8.456 + break;8.457 + case 0x8:8.458 + switch( (ir&0xFF0) >> 4 ) {8.459 + case 0x0:8.460 + { /* CLRT */8.461 + snprintf( buf, len, "CLRT " );8.462 + }8.463 + break;8.464 + case 0x1:8.465 + { /* SETT */8.466 + snprintf( buf, len, "SETT " );8.467 + }8.468 + break;8.469 + case 0x2:8.470 + { /* CLRMAC */8.471 + snprintf( buf, len, "CLRMAC " );8.472 + }8.473 + break;8.474 + case 0x3:8.475 + { /* LDTLB */8.476 + snprintf( buf, len, "LDTLB " );8.477 + }8.478 + break;8.479 + case 0x4:8.480 + { /* CLRS */8.481 + snprintf( buf, len, "CLRS " );8.482 + }8.483 + break;8.484 + case 0x5:8.485 + { /* SETS */8.486 + snprintf( buf, len, "SETS " );8.487 + }8.488 + break;8.489 + default:8.490 + UNDEF();8.491 + break;8.492 + }8.493 + break;8.494 + case 0x9:8.495 + switch( (ir&0xF0) >> 4 ) {8.496 + case 0x0:8.497 + { /* NOP */8.498 + snprintf( buf, len, "NOP " );8.499 + }8.500 + break;8.501 + case 0x1:8.502 + { /* DIV0U */8.503 + snprintf( buf, len, "DIV0U " );8.504 + }8.505 + break;8.506 + case 0x2:8.507 + { /* MOVT Rn */8.508 + uint32_t Rn = ((ir>>8)&0xF);8.509 + snprintf( buf, len, "MOVT R%d", Rn );8.510 + }8.511 + break;8.512 + default:8.513 + UNDEF();8.514 + break;8.515 + }8.516 + break;8.517 + case 0xA:8.518 + switch( (ir&0xF0) >> 4 ) {8.519 + case 0x0:8.520 + { /* STS MACH, Rn */8.521 + uint32_t Rn = ((ir>>8)&0xF);8.522 + snprintf( buf, len, "STS MACH, R%d", Rn );8.523 + }8.524 + break;8.525 + case 0x1:8.526 + { /* STS MACL, Rn */8.527 + uint32_t Rn = ((ir>>8)&0xF);8.528 + snprintf( buf, len, "STS MACL, R%d", Rn );8.529 + }8.530 + break;8.531 + case 0x2:8.532 + { /* STS PR, Rn */8.533 + uint32_t Rn = ((ir>>8)&0xF);8.534 + snprintf( buf, len, "STS PR, R%d", Rn );8.535 + }8.536 + break;8.537 + case 0x3:8.538 + { /* STC SGR, Rn */8.539 + uint32_t Rn = ((ir>>8)&0xF);8.540 + snprintf( buf, len, "STC SGR, R%d", Rn );8.541 + }8.542 + break;8.543 + case 0x5:8.544 + { /* STS FPUL, Rn */8.545 + uint32_t Rn = ((ir>>8)&0xF);8.546 + snprintf( buf, len, "STS FPUL, R%d", Rn );8.547 + }8.548 + break;8.549 + case 0x6:8.550 + { /* STS FPSCR, Rn */8.551 + uint32_t Rn = ((ir>>8)&0xF);8.552 + snprintf( buf, len, "STS FPSCR, R%d", Rn );8.553 + }8.554 + break;8.555 + case 0xF:8.556 + { /* STC DBR, Rn */8.557 + uint32_t Rn = ((ir>>8)&0xF);8.558 + snprintf( buf, len, "STC DBR, R%d", Rn );8.559 + }8.560 + break;8.561 + default:8.562 + UNDEF();8.563 + break;8.564 + }8.565 + break;8.566 + case 0xB:8.567 + switch( (ir&0xFF0) >> 4 ) {8.568 + case 0x0:8.569 + { /* RTS */8.570 + snprintf( buf, len, "RTS " );8.571 + }8.572 + break;8.573 + case 0x1:8.574 + { /* SLEEP */8.575 + snprintf( buf, len, "SLEEP " );8.576 + }8.577 + break;8.578 + case 0x2:8.579 + { /* RTE */8.580 + snprintf( buf, len, "RTE " );8.581 + }8.582 + break;8.583 + default:8.584 + UNDEF();8.585 + break;8.586 + }8.587 + break;8.588 + case 0xC:8.589 + { /* MOV.B @(R0, Rm), Rn */8.590 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.591 + snprintf( buf, len, "MOV.B @(R0, R%d), R%d", Rm, Rn );8.592 + }8.593 + break;8.594 + case 0xD:8.595 + { /* MOV.W @(R0, Rm), Rn */8.596 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.597 + snprintf( buf, len, "MOV.W @(R0, R%d), R%d", Rm, Rn );8.598 + }8.599 + break;8.600 + case 0xE:8.601 + { /* MOV.L @(R0, Rm), Rn */8.602 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.603 + snprintf( buf, len, "MOV.L @(R0, R%d), R%d", Rm, Rn );8.604 + }8.605 + break;8.606 + case 0xF:8.607 + { /* MAC.L @Rm+, @Rn+ */8.608 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.609 + snprintf( buf, len, "MAC.L @R%d+, @R%d+", Rm, Rn );8.610 + }8.611 + break;8.612 + default:8.613 + UNDEF();8.614 + break;8.615 + }8.616 + break;8.617 + case 0x1:8.618 + { /* MOV.L Rm, @(disp, Rn) */8.619 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;8.620 + snprintf( buf, len, "MOV.L R%d, @(%d, R%d)", Rm, disp, Rn );8.621 + }8.622 + break;8.623 + case 0x2:8.624 + switch( ir&0xF ) {8.625 + case 0x0:8.626 + { /* MOV.B Rm, @Rn */8.627 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.628 + snprintf( buf, len, "MOV.B R%d, @R%d", Rm, Rn );8.629 + }8.630 + break;8.631 + case 0x1:8.632 + { /* MOV.W Rm, @Rn */8.633 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.634 + snprintf( buf, len, "MOV.W R%d, @R%d", Rm, Rn );8.635 + }8.636 + break;8.637 + case 0x2:8.638 + { /* MOV.L Rm, @Rn */8.639 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.640 + snprintf( buf, len, "MOV.L R%d, @R%d", Rm, Rn );8.641 + }8.642 + break;8.643 + case 0x4:8.644 + { /* MOV.B Rm, @-Rn */8.645 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.646 + snprintf( buf, len, "MOV.B R%d, @-R%d", Rm, Rn );8.647 + }8.648 + break;8.649 + case 0x5:8.650 + { /* MOV.W Rm, @-Rn */8.651 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.652 + snprintf( buf, len, "MOV.W R%d, @-R%d", Rm, Rn );8.653 + }8.654 + break;8.655 + case 0x6:8.656 + { /* MOV.L Rm, @-Rn */8.657 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.658 + snprintf( buf, len, "MOV.L R%d, @-R%d", Rm, Rn );8.659 + }8.660 + break;8.661 + case 0x7:8.662 + { /* DIV0S Rm, Rn */8.663 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.664 + snprintf( buf, len, "DIV0S R%d, R%d", Rm, Rn );8.665 + }8.666 + break;8.667 + case 0x8:8.668 + { /* TST Rm, Rn */8.669 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.670 + snprintf( buf, len, "TST R%d, R%d", Rm, Rn );8.671 + }8.672 + break;8.673 + case 0x9:8.674 + { /* AND Rm, Rn */8.675 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.676 + snprintf( buf, len, "AND R%d, R%d", Rm, Rn );8.677 + }8.678 + break;8.679 + case 0xA:8.680 + { /* XOR Rm, Rn */8.681 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.682 + snprintf( buf, len, "XOR R%d, R%d", Rm, Rn );8.683 + }8.684 + break;8.685 + case 0xB:8.686 + { /* OR Rm, Rn */8.687 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.688 + snprintf( buf, len, "OR R%d, R%d", Rm, Rn );8.689 + }8.690 + break;8.691 + case 0xC:8.692 + { /* CMP/STR Rm, Rn */8.693 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.694 + snprintf( buf, len, "CMP/STR R%d, R%d", Rm, Rn );8.695 + }8.696 + break;8.697 + case 0xD:8.698 + { /* XTRCT Rm, Rn */8.699 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.700 + snprintf( buf, len, "XTRCT R%d, R%d", Rm, Rn );8.701 + }8.702 + break;8.703 + case 0xE:8.704 + { /* MULU.W Rm, Rn */8.705 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.706 + snprintf( buf, len, "MULU.W R%d, R%d", Rm, Rn );8.707 + }8.708 + break;8.709 + case 0xF:8.710 + { /* MULS.W Rm, Rn */8.711 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.712 + snprintf( buf, len, "MULS.W R%d, R%d", Rm, Rn );8.713 + }8.714 + break;8.715 + default:8.716 + UNDEF();8.717 + break;8.718 + }8.719 + break;8.720 + case 0x3:8.721 + switch( ir&0xF ) {8.722 + case 0x0:8.723 + { /* CMP/EQ Rm, Rn */8.724 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.725 + snprintf( buf, len, "CMP/EQ R%d, R%d", Rm, Rn );8.726 + }8.727 + break;8.728 + case 0x2:8.729 + { /* CMP/HS Rm, Rn */8.730 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.731 + snprintf( buf, len, "CMP/HS R%d, R%d", Rm, Rn );8.732 + }8.733 + break;8.734 + case 0x3:8.735 + { /* CMP/GE Rm, Rn */8.736 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.737 + snprintf( buf, len, "CMP/GE R%d, R%d", Rm, Rn );8.738 + }8.739 + break;8.740 + case 0x4:8.741 + { /* DIV1 Rm, Rn */8.742 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.743 + snprintf( buf, len, "DIV1 R%d, R%d", Rm, Rn );8.744 + }8.745 + break;8.746 + case 0x5:8.747 + { /* DMULU.L Rm, Rn */8.748 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.749 + snprintf( buf, len, "DMULU.L R%d, R%d", Rm, Rn );8.750 + }8.751 + break;8.752 + case 0x6:8.753 + { /* CMP/HI Rm, Rn */8.754 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.755 + snprintf( buf, len, "CMP/HI R%d, R%d", Rm, Rn );8.756 + }8.757 + break;8.758 + case 0x7:8.759 + { /* CMP/GT Rm, Rn */8.760 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.761 + snprintf( buf, len, "CMP/GT R%d, R%d", Rm, Rn );8.762 + }8.763 + break;8.764 + case 0x8:8.765 + { /* SUB Rm, Rn */8.766 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.767 + snprintf( buf, len, "SUB R%d, R%d", Rm, Rn );8.768 + }8.769 + break;8.770 + case 0xA:8.771 + { /* SUBC Rm, Rn */8.772 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.773 + snprintf( buf, len, "SUBC R%d, R%d", Rm, Rn );8.774 + }8.775 + break;8.776 + case 0xB:8.777 + { /* SUBV Rm, Rn */8.778 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.779 + snprintf( buf, len, "SUBV R%d, R%d", Rm, Rn );8.780 + }8.781 + break;8.782 + case 0xC:8.783 + { /* ADD Rm, Rn */8.784 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.785 + snprintf( buf, len, "ADD R%d, R%d", Rm, Rn );8.786 + }8.787 + break;8.788 + case 0xD:8.789 + { /* DMULS.L Rm, Rn */8.790 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.791 + snprintf( buf, len, "DMULS.L R%d, R%d", Rm, Rn );8.792 + }8.793 + break;8.794 + case 0xE:8.795 + { /* ADDC Rm, Rn */8.796 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.797 + snprintf( buf, len, "ADDC R%d, R%d", Rm, Rn );8.798 + }8.799 + break;8.800 + case 0xF:8.801 + { /* ADDV Rm, Rn */8.802 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.803 + snprintf( buf, len, "ADDV R%d, R%d", Rm, Rn );8.804 + }8.805 + break;8.806 + default:8.807 + UNDEF();8.808 + break;8.809 + }8.810 + break;8.811 + case 0x4:8.812 + switch( ir&0xF ) {8.813 + case 0x0:8.814 + switch( (ir&0xF0) >> 4 ) {8.815 + case 0x0:8.816 + { /* SHLL Rn */8.817 + uint32_t Rn = ((ir>>8)&0xF);8.818 + snprintf( buf, len, "SHLL R%d", Rn );8.819 + }8.820 + break;8.821 + case 0x1:8.822 + { /* DT Rn */8.823 + uint32_t Rn = ((ir>>8)&0xF);8.824 + snprintf( buf, len, "DT R%d", Rn );8.825 + }8.826 + break;8.827 + case 0x2:8.828 + { /* SHAL Rn */8.829 + uint32_t Rn = ((ir>>8)&0xF);8.830 + snprintf( buf, len, "SHAL R%d", Rn );8.831 + }8.832 + break;8.833 + default:8.834 + UNDEF();8.835 + break;8.836 + }8.837 + break;8.838 + case 0x1:8.839 + switch( (ir&0xF0) >> 4 ) {8.840 + case 0x0:8.841 + { /* SHLR Rn */8.842 + uint32_t Rn = ((ir>>8)&0xF);8.843 + snprintf( buf, len, "SHLR R%d", Rn );8.844 + }8.845 + break;8.846 + case 0x1:8.847 + { /* CMP/PZ Rn */8.848 + uint32_t Rn = ((ir>>8)&0xF);8.849 + snprintf( buf, len, "CMP/PZ R%d", Rn );8.850 + }8.851 + break;8.852 + case 0x2:8.853 + { /* SHAR Rn */8.854 + uint32_t Rn = ((ir>>8)&0xF);8.855 + snprintf( buf, len, "SHAR R%d", Rn );8.856 + }8.857 + break;8.858 + default:8.859 + UNDEF();8.860 + break;8.861 + }8.862 + break;8.863 + case 0x2:8.864 + switch( (ir&0xF0) >> 4 ) {8.865 + case 0x0:8.866 + { /* STS.L MACH, @-Rn */8.867 + uint32_t Rn = ((ir>>8)&0xF);8.868 + snprintf( buf, len, "STS.L MACH, @-R%d", Rn );8.869 + }8.870 + break;8.871 + case 0x1:8.872 + { /* STS.L MACL, @-Rn */8.873 + uint32_t Rn = ((ir>>8)&0xF);8.874 + snprintf( buf, len, "STS.L MACL, @-R%d", Rn );8.875 + }8.876 + break;8.877 + case 0x2:8.878 + { /* STS.L PR, @-Rn */8.879 + uint32_t Rn = ((ir>>8)&0xF);8.880 + snprintf( buf, len, "STS.L PR, @-R%d", Rn );8.881 + }8.882 + break;8.883 + case 0x3:8.884 + { /* STC.L SGR, @-Rn */8.885 + uint32_t Rn = ((ir>>8)&0xF);8.886 + snprintf( buf, len, "STC.L SGR, @-R%d", Rn );8.887 + }8.888 + break;8.889 + case 0x5:8.890 + { /* STS.L FPUL, @-Rn */8.891 + uint32_t Rn = ((ir>>8)&0xF);8.892 + snprintf( buf, len, "STS.L FPUL, @-R%d", Rn );8.893 + }8.894 + break;8.895 + case 0x6:8.896 + { /* STS.L FPSCR, @-Rn */8.897 + uint32_t Rn = ((ir>>8)&0xF);8.898 + snprintf( buf, len, "STS.L FPSCR, @-R%d", Rn );8.899 + }8.900 + break;8.901 + case 0xF:8.902 + { /* STC.L DBR, @-Rn */8.903 + uint32_t Rn = ((ir>>8)&0xF);8.904 + snprintf( buf, len, "STC.L DBR, @-R%d", Rn );8.905 + }8.906 + break;8.907 + default:8.908 + UNDEF();8.909 + break;8.910 + }8.911 + break;8.912 + case 0x3:8.913 + switch( (ir&0x80) >> 7 ) {8.914 + case 0x0:8.915 + switch( (ir&0x70) >> 4 ) {8.916 + case 0x0:8.917 + { /* STC.L SR, @-Rn */8.918 + uint32_t Rn = ((ir>>8)&0xF);8.919 + snprintf( buf, len, "STC.L SR, @-R%d", Rn );8.920 + }8.921 + break;8.922 + case 0x1:8.923 + { /* STC.L GBR, @-Rn */8.924 + uint32_t Rn = ((ir>>8)&0xF);8.925 + snprintf( buf, len, "STC.L GBR, @-R%d", Rn );8.926 + }8.927 + break;8.928 + case 0x2:8.929 + { /* STC.L VBR, @-Rn */8.930 + uint32_t Rn = ((ir>>8)&0xF);8.931 + snprintf( buf, len, "STC.L VBR, @-R%d", Rn );8.932 + }8.933 + break;8.934 + case 0x3:8.935 + { /* STC.L SSR, @-Rn */8.936 + uint32_t Rn = ((ir>>8)&0xF);8.937 + snprintf( buf, len, "STC.L SSR, @-R%d", Rn );8.938 + }8.939 + break;8.940 + case 0x4:8.941 + { /* STC.L SPC, @-Rn */8.942 + uint32_t Rn = ((ir>>8)&0xF);8.943 + snprintf( buf, len, "STC.L SPC, @-R%d", Rn );8.944 + }8.945 + break;8.946 + default:8.947 + UNDEF();8.948 + break;8.949 + }8.950 + break;8.951 + case 0x1:8.952 + { /* STC.L Rm_BANK, @-Rn */8.953 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);8.954 + snprintf( buf, len, "STC.L @-R%d_BANK, @-R%d", Rm_BANK, Rn );8.955 + }8.956 + break;8.957 + }8.958 + break;8.959 + case 0x4:8.960 + switch( (ir&0xF0) >> 4 ) {8.961 + case 0x0:8.962 + { /* ROTL Rn */8.963 + uint32_t Rn = ((ir>>8)&0xF);8.964 + snprintf( buf, len, "ROTL R%d", Rn );8.965 + }8.966 + break;8.967 + case 0x2:8.968 + { /* ROTCL Rn */8.969 + uint32_t Rn = ((ir>>8)&0xF);8.970 + snprintf( buf, len, "ROTCL R%d", Rn );8.971 + }8.972 + break;8.973 + default:8.974 + UNDEF();8.975 + break;8.976 + }8.977 + break;8.978 + case 0x5:8.979 + switch( (ir&0xF0) >> 4 ) {8.980 + case 0x0:8.981 + { /* ROTR Rn */8.982 + uint32_t Rn = ((ir>>8)&0xF);8.983 + snprintf( buf, len, "ROTR R%d", Rn );8.984 + }8.985 + break;8.986 + case 0x1:8.987 + { /* CMP/PL Rn */8.988 + uint32_t Rn = ((ir>>8)&0xF);8.989 + snprintf( buf, len, "CMP/PL R%d", Rn );8.990 + }8.991 + break;8.992 + case 0x2:8.993 + { /* ROTCR Rn */8.994 + uint32_t Rn = ((ir>>8)&0xF);8.995 + snprintf( buf, len, "ROTCR R%d", Rn );8.996 + }8.997 + break;8.998 + default:8.999 + UNDEF();8.1000 + break;8.1001 + }8.1002 + break;8.1003 + case 0x6:8.1004 + switch( (ir&0xF0) >> 4 ) {8.1005 + case 0x0:8.1006 + { /* LDS.L @Rm+, MACH */8.1007 + uint32_t Rm = ((ir>>8)&0xF);8.1008 + snprintf( buf, len, "LDS.L @R%d+, MACH", Rm );8.1009 + }8.1010 + break;8.1011 + case 0x1:8.1012 + { /* LDS.L @Rm+, MACL */8.1013 + uint32_t Rm = ((ir>>8)&0xF);8.1014 + snprintf( buf, len, "LDS.L @R%d+, MACL", Rm );8.1015 + }8.1016 + break;8.1017 + case 0x2:8.1018 + { /* LDS.L @Rm+, PR */8.1019 + uint32_t Rm = ((ir>>8)&0xF);8.1020 + snprintf( buf, len, "LDS.L @R%d+, PR", Rm );8.1021 + }8.1022 + break;8.1023 + case 0x3:8.1024 + { /* LDC.L @Rm+, SGR */8.1025 + uint32_t Rm = ((ir>>8)&0xF);8.1026 + snprintf( buf, len, "LDC.L @R%d+, SGR", Rm );8.1027 + }8.1028 + break;8.1029 + case 0x5:8.1030 + { /* LDS.L @Rm+, FPUL */8.1031 + uint32_t Rm = ((ir>>8)&0xF);8.1032 + snprintf( buf, len, "LDS.L @R%d+, FPUL", Rm );8.1033 + }8.1034 + break;8.1035 + case 0x6:8.1036 + { /* LDS.L @Rm+, FPSCR */8.1037 + uint32_t Rm = ((ir>>8)&0xF);8.1038 + snprintf( buf, len, "LDS.L @R%d+, FPSCR", Rm );8.1039 + }8.1040 + break;8.1041 + case 0xF:8.1042 + { /* LDC.L @Rm+, DBR */8.1043 + uint32_t Rm = ((ir>>8)&0xF);8.1044 + snprintf( buf, len, "LDC.L @R%d+, DBR", Rm );8.1045 + }8.1046 + break;8.1047 + default:8.1048 + UNDEF();8.1049 + break;8.1050 + }8.1051 + break;8.1052 + case 0x7:8.1053 + switch( (ir&0x80) >> 7 ) {8.1054 + case 0x0:8.1055 + switch( (ir&0x70) >> 4 ) {8.1056 + case 0x0:8.1057 + { /* LDC.L @Rm+, SR */8.1058 + uint32_t Rm = ((ir>>8)&0xF);8.1059 + snprintf( buf, len, "LDC.L @R%d+, SR", Rm );8.1060 + }8.1061 + break;8.1062 + case 0x1:8.1063 + { /* LDC.L @Rm+, GBR */8.1064 + uint32_t Rm = ((ir>>8)&0xF);8.1065 + snprintf( buf, len, "LDC.L @R%d+, GBR", Rm );8.1066 + }8.1067 + break;8.1068 + case 0x2:8.1069 + { /* LDC.L @Rm+, VBR */8.1070 + uint32_t Rm = ((ir>>8)&0xF);8.1071 + snprintf( buf, len, "LDC.L @R%d+, VBR", Rm );8.1072 + }8.1073 + break;8.1074 + case 0x3:8.1075 + { /* LDC.L @Rm+, SSR */8.1076 + uint32_t Rm = ((ir>>8)&0xF);8.1077 + snprintf( buf, len, "LDC.L @R%d+, SSR", Rm );8.1078 + }8.1079 + break;8.1080 + case 0x4:8.1081 + { /* LDC.L @Rm+, SPC */8.1082 + uint32_t Rm = ((ir>>8)&0xF);8.1083 + snprintf( buf, len, "LDC.L @R%d+, SPC", Rm );8.1084 + }8.1085 + break;8.1086 + default:8.1087 + UNDEF();8.1088 + break;8.1089 + }8.1090 + break;8.1091 + case 0x1:8.1092 + { /* LDC.L @Rm+, Rn_BANK */8.1093 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);8.1094 + snprintf( buf, len, "LDC.L @R%d+, @R%d+_BANK", Rm, Rn_BANK );8.1095 + }8.1096 + break;8.1097 + }8.1098 + break;8.1099 + case 0x8:8.1100 + switch( (ir&0xF0) >> 4 ) {8.1101 + case 0x0:8.1102 + { /* SHLL2 Rn */8.1103 + uint32_t Rn = ((ir>>8)&0xF);8.1104 + snprintf( buf, len, "SHLL2 R%d", Rn );8.1105 + }8.1106 + break;8.1107 + case 0x1:8.1108 + { /* SHLL8 Rn */8.1109 + uint32_t Rn = ((ir>>8)&0xF);8.1110 + snprintf( buf, len, "SHLL8 R%d", Rn );8.1111 + }8.1112 + break;8.1113 + case 0x2:8.1114 + { /* SHLL16 Rn */8.1115 + uint32_t Rn = ((ir>>8)&0xF);8.1116 + snprintf( buf, len, "SHLL16 R%d", Rn );8.1117 + }8.1118 + break;8.1119 + default:8.1120 + UNDEF();8.1121 + break;8.1122 + }8.1123 + break;8.1124 + case 0x9:8.1125 + switch( (ir&0xF0) >> 4 ) {8.1126 + case 0x0:8.1127 + { /* SHLR2 Rn */8.1128 + uint32_t Rn = ((ir>>8)&0xF);8.1129 + snprintf( buf, len, "SHLR2 R%d", Rn );8.1130 + }8.1131 + break;8.1132 + case 0x1:8.1133 + { /* SHLR8 Rn */8.1134 + uint32_t Rn = ((ir>>8)&0xF);8.1135 + snprintf( buf, len, "SHLR8 R%d", Rn );8.1136 + }8.1137 + break;8.1138 + case 0x2:8.1139 + { /* SHLR16 Rn */8.1140 + uint32_t Rn = ((ir>>8)&0xF);8.1141 + snprintf( buf, len, "SHLR16 R%d", Rn );8.1142 + }8.1143 + break;8.1144 + default:8.1145 + UNDEF();8.1146 + break;8.1147 + }8.1148 + break;8.1149 + case 0xA:8.1150 + switch( (ir&0xF0) >> 4 ) {8.1151 + case 0x0:8.1152 + { /* LDS Rm, MACH */8.1153 + uint32_t Rm = ((ir>>8)&0xF);8.1154 + snprintf( buf, len, "LDS R%d, MACH", Rm );8.1155 + }8.1156 + break;8.1157 + case 0x1:8.1158 + { /* LDS Rm, MACL */8.1159 + uint32_t Rm = ((ir>>8)&0xF);8.1160 + snprintf( buf, len, "LDS R%d, MACL", Rm );8.1161 + }8.1162 + break;8.1163 + case 0x2:8.1164 + { /* LDS Rm, PR */8.1165 + uint32_t Rm = ((ir>>8)&0xF);8.1166 + snprintf( buf, len, "LDS R%d, PR", Rm );8.1167 + }8.1168 + break;8.1169 + case 0x3:8.1170 + { /* LDC Rm, SGR */8.1171 + uint32_t Rm = ((ir>>8)&0xF);8.1172 + snprintf( buf, len, "LDC R%d, SGR", Rm );8.1173 + }8.1174 + break;8.1175 + case 0x5:8.1176 + { /* LDS Rm, FPUL */8.1177 + uint32_t Rm = ((ir>>8)&0xF);8.1178 + snprintf( buf, len, "LDS R%d, FPUL", Rm );8.1179 + }8.1180 + break;8.1181 + case 0x6:8.1182 + { /* LDS Rm, FPSCR */8.1183 + uint32_t Rm = ((ir>>8)&0xF);8.1184 + snprintf( buf, len, "LDS R%d, FPSCR", Rm );8.1185 + }8.1186 + break;8.1187 + case 0xF:8.1188 + { /* LDC Rm, DBR */8.1189 + uint32_t Rm = ((ir>>8)&0xF);8.1190 + snprintf( buf, len, "LDC R%d, DBR", Rm );8.1191 + }8.1192 + break;8.1193 + default:8.1194 + UNDEF();8.1195 + break;8.1196 + }8.1197 + break;8.1198 + case 0xB:8.1199 + switch( (ir&0xF0) >> 4 ) {8.1200 + case 0x0:8.1201 + { /* JSR @Rn */8.1202 + uint32_t Rn = ((ir>>8)&0xF);8.1203 + snprintf( buf, len, "JSR @R%d", Rn );8.1204 + }8.1205 + break;8.1206 + case 0x1:8.1207 + { /* TAS.B @Rn */8.1208 + uint32_t Rn = ((ir>>8)&0xF);8.1209 + snprintf( buf, len, "TAS.B R%d", Rn );8.1210 + }8.1211 + break;8.1212 + case 0x2:8.1213 + { /* JMP @Rn */8.1214 + uint32_t Rn = ((ir>>8)&0xF);8.1215 + snprintf( buf, len, "JMP @R%d", Rn );8.1216 + }8.1217 + break;8.1218 + default:8.1219 + UNDEF();8.1220 + break;8.1221 + }8.1222 + break;8.1223 + case 0xC:8.1224 + { /* SHAD Rm, Rn */8.1225 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1226 + snprintf( buf, len, "SHAD R%d, R%d", Rm, Rn );8.1227 + }8.1228 + break;8.1229 + case 0xD:8.1230 + { /* SHLD Rm, Rn */8.1231 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1232 + snprintf( buf, len, "SHLD R%d, R%d", Rm, Rn );8.1233 + }8.1234 + break;8.1235 + case 0xE:8.1236 + switch( (ir&0x80) >> 7 ) {8.1237 + case 0x0:8.1238 + switch( (ir&0x70) >> 4 ) {8.1239 + case 0x0:8.1240 + { /* LDC Rm, SR */8.1241 + uint32_t Rm = ((ir>>8)&0xF);8.1242 + snprintf( buf, len, "LDC R%d, SR", Rm );8.1243 + }8.1244 + break;8.1245 + case 0x1:8.1246 + { /* LDC Rm, GBR */8.1247 + uint32_t Rm = ((ir>>8)&0xF);8.1248 + snprintf( buf, len, "LDC R%d, GBR", Rm );8.1249 + }8.1250 + break;8.1251 + case 0x2:8.1252 + { /* LDC Rm, VBR */8.1253 + uint32_t Rm = ((ir>>8)&0xF);8.1254 + snprintf( buf, len, "LDC R%d, VBR", Rm );8.1255 + }8.1256 + break;8.1257 + case 0x3:8.1258 + { /* LDC Rm, SSR */8.1259 + uint32_t Rm = ((ir>>8)&0xF);8.1260 + snprintf( buf, len, "LDC R%d, SSR", Rm );8.1261 + }8.1262 + break;8.1263 + case 0x4:8.1264 + { /* LDC Rm, SPC */8.1265 + uint32_t Rm = ((ir>>8)&0xF);8.1266 + snprintf( buf, len, "LDC R%d, SPC", Rm );8.1267 + }8.1268 + break;8.1269 + default:8.1270 + UNDEF();8.1271 + break;8.1272 + }8.1273 + break;8.1274 + case 0x1:8.1275 + { /* LDC Rm, Rn_BANK */8.1276 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);8.1277 + snprintf( buf, len, "LDC R%d, R%d_BANK", Rm, Rn_BANK );8.1278 + }8.1279 + break;8.1280 + }8.1281 + break;8.1282 + case 0xF:8.1283 + { /* MAC.W @Rm+, @Rn+ */8.1284 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1285 + snprintf( buf, len, "MAC.W @R%d+, @R%d+", Rm, Rn );8.1286 + }8.1287 + break;8.1288 + }8.1289 + break;8.1290 + case 0x5:8.1291 + { /* MOV.L @(disp, Rm), Rn */8.1292 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;8.1293 + snprintf( buf, len, "MOV.L @(%d, R%d), @R%d", disp, Rm, Rn );8.1294 + }8.1295 + break;8.1296 + case 0x6:8.1297 + switch( ir&0xF ) {8.1298 + case 0x0:8.1299 + { /* MOV.B @Rm, Rn */8.1300 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1301 + snprintf( buf, len, "MOV.B @R%d, R%d", Rm, Rn );8.1302 + }8.1303 + break;8.1304 + case 0x1:8.1305 + { /* MOV.W @Rm, Rn */8.1306 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1307 + snprintf( buf, len, "MOV.W @R%d, R%d", Rm, Rn );8.1308 + }8.1309 + break;8.1310 + case 0x2:8.1311 + { /* MOV.L @Rm, Rn */8.1312 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1313 + snprintf( buf, len, "MOV.L @R%d, R%d", Rm, Rn );8.1314 + }8.1315 + break;8.1316 + case 0x3:8.1317 + { /* MOV Rm, Rn */8.1318 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1319 + snprintf( buf, len, "MOV R%d, R%d", Rm, Rn );8.1320 + }8.1321 + break;8.1322 + case 0x4:8.1323 + { /* MOV.B @Rm+, Rn */8.1324 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1325 + snprintf( buf, len, "MOV.B @R%d+, R%d", Rm, Rn );8.1326 + }8.1327 + break;8.1328 + case 0x5:8.1329 + { /* MOV.W @Rm+, Rn */8.1330 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1331 + snprintf( buf, len, "MOV.W @R%d+, R%d", Rm, Rn );8.1332 + }8.1333 + break;8.1334 + case 0x6:8.1335 + { /* MOV.L @Rm+, Rn */8.1336 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1337 + snprintf( buf, len, "MOV.L @R%d+, R%d", Rm, Rn );8.1338 + }8.1339 + break;8.1340 + case 0x7:8.1341 + { /* NOT Rm, Rn */8.1342 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1343 + snprintf( buf, len, "NOT R%d, R%d", Rm, Rn );8.1344 + }8.1345 + break;8.1346 + case 0x8:8.1347 + { /* SWAP.B Rm, Rn */8.1348 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1349 + snprintf( buf, len, "SWAP.B R%d, R%d", Rm, Rn );8.1350 + }8.1351 + break;8.1352 + case 0x9:8.1353 + { /* SWAP.W Rm, Rn */8.1354 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1355 + snprintf( buf, len, "SWAP.W R%d, R%d", Rm, Rn );8.1356 + }8.1357 + break;8.1358 + case 0xA:8.1359 + { /* NEGC Rm, Rn */8.1360 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1361 + snprintf( buf, len, "NEGC R%d, R%d", Rm, Rn );8.1362 + }8.1363 + break;8.1364 + case 0xB:8.1365 + { /* NEG Rm, Rn */8.1366 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1367 + snprintf( buf, len, "NEG R%d, R%d", Rm, Rn );8.1368 + }8.1369 + break;8.1370 + case 0xC:8.1371 + { /* EXTU.B Rm, Rn */8.1372 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1373 + snprintf( buf, len, "EXTU.B R%d, R%d", Rm, Rn );8.1374 + }8.1375 + break;8.1376 + case 0xD:8.1377 + { /* EXTU.W Rm, Rn */8.1378 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1379 + snprintf( buf, len, "EXTU.W R%d, R%d", Rm, Rn );8.1380 + }8.1381 + break;8.1382 + case 0xE:8.1383 + { /* EXTS.B Rm, Rn */8.1384 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1385 + snprintf( buf, len, "EXTS.B R%d, R%d", Rm, Rn );8.1386 + }8.1387 + break;8.1388 + case 0xF:8.1389 + { /* EXTS.W Rm, Rn */8.1390 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1391 + snprintf( buf, len, "EXTS.W R%d, R%d", Rm, Rn );8.1392 + }8.1393 + break;8.1394 + }8.1395 + break;8.1396 + case 0x7:8.1397 + { /* ADD #imm, Rn */8.1398 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);8.1399 + snprintf( buf, len, "ADD #%d, R%d", imm, Rn );8.1400 + }8.1401 + break;8.1402 + case 0x8:8.1403 + switch( (ir&0xF00) >> 8 ) {8.1404 + case 0x0:8.1405 + { /* MOV.B R0, @(disp, Rn) */8.1406 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);8.1407 + snprintf( buf, len, "MOV.B R0, @(%d, R%d)", disp, Rn );8.1408 + }8.1409 + break;8.1410 + case 0x1:8.1411 + { /* MOV.W R0, @(disp, Rn) */8.1412 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;8.1413 + snprintf( buf, len, "MOV.W R0, @(%d, Rn)", disp, Rn );8.1414 + }8.1415 + break;8.1416 + case 0x4:8.1417 + { /* MOV.B @(disp, Rm), R0 */8.1418 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);8.1419 + snprintf( buf, len, "MOV.B @(%d, R%d), R0", disp, Rm );8.1420 + }8.1421 + break;8.1422 + case 0x5:8.1423 + { /* MOV.W @(disp, Rm), R0 */8.1424 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;8.1425 + snprintf( buf, len, "MOV.W @(%d, R%d), R0", disp, Rm );8.1426 + }8.1427 + break;8.1428 + case 0x8:8.1429 + { /* CMP/EQ #imm, R0 */8.1430 + int32_t imm = SIGNEXT8(ir&0xFF);8.1431 + snprintf( buf, len, "CMP/EQ #%d, R0", imm );8.1432 + }8.1433 + break;8.1434 + case 0x9:8.1435 + { /* BT disp */8.1436 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;8.1437 + snprintf( buf, len, "BT $%xh", disp+pc+4 );8.1438 + }8.1439 + break;8.1440 + case 0xB:8.1441 + { /* BF disp */8.1442 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;8.1443 + snprintf( buf, len, "BF $%xh", disp+pc+4 );8.1444 + }8.1445 + break;8.1446 + case 0xD:8.1447 + { /* BT/S disp */8.1448 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;8.1449 + snprintf( buf, len, "BT/S $%xh", disp+pc+4 );8.1450 + }8.1451 + break;8.1452 + case 0xF:8.1453 + { /* BF/S disp */8.1454 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;8.1455 + snprintf( buf, len, "BF/S $%xh", disp+pc+4 );8.1456 + }8.1457 + break;8.1458 + default:8.1459 + UNDEF();8.1460 + break;8.1461 + }8.1462 + break;8.1463 + case 0x9:8.1464 + { /* MOV.W @(disp, PC), Rn */8.1465 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;8.1466 + snprintf( buf, len, "MOV.W @($%xh), R%d ; <- #%08x", disp + pc + 4, Rn, sh4_read_word(disp+pc+4) );8.1467 + }8.1468 + break;8.1469 + case 0xA:8.1470 + { /* BRA disp */8.1471 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;8.1472 + snprintf( buf, len, "BRA $%xh", disp+pc+4 );8.1473 + }8.1474 + break;8.1475 + case 0xB:8.1476 + { /* BSR disp */8.1477 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;8.1478 + snprintf( buf, len, "BSR $%xh", disp+pc+4 );8.1479 + }8.1480 + break;8.1481 + case 0xC:8.1482 + switch( (ir&0xF00) >> 8 ) {8.1483 + case 0x0:8.1484 + { /* MOV.B R0, @(disp, GBR) */8.1485 + uint32_t disp = (ir&0xFF);8.1486 + snprintf( buf, len, "MOV.B R0, @(%d, GBR)", disp );8.1487 + }8.1488 + break;8.1489 + case 0x1:8.1490 + { /* MOV.W R0, @(disp, GBR) */8.1491 + uint32_t disp = (ir&0xFF)<<1;8.1492 + snprintf( buf, len, "MOV.W R0, @(%d, GBR)", disp);8.1493 + }8.1494 + break;8.1495 + case 0x2:8.1496 + { /* MOV.L R0, @(disp, GBR) */8.1497 + uint32_t disp = (ir&0xFF)<<2;8.1498 + snprintf( buf, len, "MOV.L R0, @(%d, GBR)", disp );8.1499 + }8.1500 + break;8.1501 + case 0x3:8.1502 + { /* TRAPA #imm */8.1503 + uint32_t imm = (ir&0xFF);8.1504 + snprintf( buf, len, "TRAPA #%d", imm );8.1505 + }8.1506 + break;8.1507 + case 0x4:8.1508 + { /* MOV.B @(disp, GBR), R0 */8.1509 + uint32_t disp = (ir&0xFF);8.1510 + snprintf( buf, len, "MOV.B @(%d, GBR), R0", disp );8.1511 + }8.1512 + break;8.1513 + case 0x5:8.1514 + { /* MOV.W @(disp, GBR), R0 */8.1515 + uint32_t disp = (ir&0xFF)<<1;8.1516 + snprintf( buf, len, "MOV.W @(%d, GBR), R0", disp );8.1517 + }8.1518 + break;8.1519 + case 0x6:8.1520 + { /* MOV.L @(disp, GBR), R0 */8.1521 + uint32_t disp = (ir&0xFF)<<2;8.1522 + snprintf( buf, len, "MOV.L @(%d, GBR), R0",disp );8.1523 + }8.1524 + break;8.1525 + case 0x7:8.1526 + { /* MOVA @(disp, PC), R0 */8.1527 + uint32_t disp = (ir&0xFF)<<2;8.1528 + snprintf( buf, len, "MOVA @($%xh), R0", disp + (pc&0xFFFFFFFC) + 4 );8.1529 + }8.1530 + break;8.1531 + case 0x8:8.1532 + { /* TST #imm, R0 */8.1533 + uint32_t imm = (ir&0xFF);8.1534 + snprintf( buf, len, "TST #%d, R0", imm );8.1535 + }8.1536 + break;8.1537 + case 0x9:8.1538 + { /* AND #imm, R0 */8.1539 + uint32_t imm = (ir&0xFF);8.1540 + snprintf( buf, len, "ADD #%d, R0", imm );8.1541 + }8.1542 + break;8.1543 + case 0xA:8.1544 + { /* XOR #imm, R0 */8.1545 + uint32_t imm = (ir&0xFF);8.1546 + snprintf( buf, len, "XOR #%d, R0", imm );8.1547 + }8.1548 + break;8.1549 + case 0xB:8.1550 + { /* OR #imm, R0 */8.1551 + uint32_t imm = (ir&0xFF);8.1552 + snprintf( buf, len, "OR #%d, R0", imm );8.1553 + }8.1554 + break;8.1555 + case 0xC:8.1556 + { /* TST.B #imm, @(R0, GBR) */8.1557 + uint32_t imm = (ir&0xFF);8.1558 + snprintf( buf, len, "TST.B #%d, @(R0, GBR)", imm );8.1559 + }8.1560 + break;8.1561 + case 0xD:8.1562 + { /* AND.B #imm, @(R0, GBR) */8.1563 + uint32_t imm = (ir&0xFF);8.1564 + snprintf( buf, len, "AND.B #%d, @(R0, GBR)", imm );8.1565 + }8.1566 + break;8.1567 + case 0xE:8.1568 + { /* XOR.B #imm, @(R0, GBR) */8.1569 + uint32_t imm = (ir&0xFF);8.1570 + snprintf( buf, len, "XOR.B #%d, @(R0, GBR)", imm );8.1571 + }8.1572 + break;8.1573 + case 0xF:8.1574 + { /* OR.B #imm, @(R0, GBR) */8.1575 + uint32_t imm = (ir&0xFF);8.1576 + snprintf( buf, len, "OR.B #%d, @(R0, GBR)", imm );8.1577 + }8.1578 + break;8.1579 + }8.1580 + break;8.1581 + case 0xD:8.1582 + { /* MOV.L @(disp, PC), Rn */8.1583 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;8.1584 + snprintf( buf, len, "MOV.L @($%xh), R%d ; <- #%08x", disp + (pc & 0xFFFFFFFC) + 4, Rn, sh4_read_long(disp+(pc&0xFFFFFFFC)+4) );8.1585 + }8.1586 + break;8.1587 + case 0xE:8.1588 + { /* MOV #imm, Rn */8.1589 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);8.1590 + snprintf( buf, len, "MOV #%d, R%d", imm, Rn );8.1591 + }8.1592 + break;8.1593 + case 0xF:8.1594 + switch( ir&0xF ) {8.1595 + case 0x0:8.1596 + { /* FADD FRm, FRn */8.1597 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1598 + snprintf( buf, len, "FADD FR%d, FR%d", FRm, FRn );8.1599 + }8.1600 + break;8.1601 + case 0x1:8.1602 + { /* FSUB FRm, FRn */8.1603 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1604 + snprintf( buf, len, "FSUB FRm, FR%d", FRm, FRn );8.1605 + }8.1606 + break;8.1607 + case 0x2:8.1608 + { /* FMUL FRm, FRn */8.1609 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1610 + snprintf( buf, len, "FMUL FRm, FR%d", FRm, FRn );8.1611 + }8.1612 + break;8.1613 + case 0x3:8.1614 + { /* FDIV FRm, FRn */8.1615 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1616 + snprintf( buf, len, "FDIV FR%d, FR%d", FRm, FRn );8.1617 + }8.1618 + break;8.1619 + case 0x4:8.1620 + { /* FCMP/EQ FRm, FRn */8.1621 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1622 + snprintf( buf, len, "FCMP/EQ FR%d, FR%d", FRm, FRn );8.1623 + }8.1624 + break;8.1625 + case 0x5:8.1626 + { /* FCMP/GT FRm, FRn */8.1627 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1628 + snprintf( buf, len, "FCMP/QT FR%d, FR%d", FRm, FRn );8.1629 + }8.1630 + break;8.1631 + case 0x6:8.1632 + { /* FMOV @(R0, Rm), FRn */8.1633 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1634 + snprintf( buf, len, "FMOV @(R0, R%d), FR%d", Rm, FRn );8.1635 + }8.1636 + break;8.1637 + case 0x7:8.1638 + { /* FMOV FRm, @(R0, Rn) */8.1639 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1640 + snprintf( buf, len, "FMOV FR%d, @(R0, R%d)", FRm, Rn );8.1641 + }8.1642 + break;8.1643 + case 0x8:8.1644 + { /* FMOV @Rm, FRn */8.1645 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1646 + snprintf( buf, len, "FMOV @R%d, FR%d", Rm, FRn );8.1647 + }8.1648 + break;8.1649 + case 0x9:8.1650 + { /* FMOV @Rm+, FRn */8.1651 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);8.1652 + snprintf( buf, len, "FMOV @R%d+, FR%d", Rm, FRn );8.1653 + }8.1654 + break;8.1655 + case 0xA:8.1656 + { /* FMOV FRm, @Rn */8.1657 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1658 + snprintf( buf, len, "FMOV FR%d, @R%d", FRm, Rn );8.1659 + }8.1660 + break;8.1661 + case 0xB:8.1662 + { /* FMOV FRm, @-Rn */8.1663 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1664 + snprintf( buf, len, "FMOV FR%d, @-R%d", FRm, Rn );8.1665 + }8.1666 + break;8.1667 + case 0xC:8.1668 + { /* FMOV FRm, FRn */8.1669 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1670 + snprintf( buf, len, "FMOV FR%d, FR%d", FRm, FRn );8.1671 + }8.1672 + break;8.1673 + case 0xD:8.1674 + switch( (ir&0xF0) >> 4 ) {8.1675 + case 0x0:8.1676 + { /* FSTS FPUL, FRn */8.1677 + uint32_t FRn = ((ir>>8)&0xF);8.1678 + snprintf( buf, len, "FSTS FPUL, FR%d", FRn );8.1679 + }8.1680 + break;8.1681 + case 0x1:8.1682 + { /* FLDS FRm, FPUL */8.1683 + uint32_t FRm = ((ir>>8)&0xF);8.1684 + snprintf( buf, len, "FLDS FR%d, FPUL", FRm );8.1685 + }8.1686 + break;8.1687 + case 0x2:8.1688 + { /* FLOAT FPUL, FRn */8.1689 + uint32_t FRn = ((ir>>8)&0xF);8.1690 + snprintf( buf, len, "FLOAT FPUL, FR%d", FRn );8.1691 + }8.1692 + break;8.1693 + case 0x3:8.1694 + { /* FTRC FRm, FPUL */8.1695 + uint32_t FRm = ((ir>>8)&0xF);8.1696 + snprintf( buf, len, "FTRC FR%d, FPUL", FRm );8.1697 + }8.1698 + break;8.1699 + case 0x4:8.1700 + { /* FNEG FRn */8.1701 + uint32_t FRn = ((ir>>8)&0xF);8.1702 + snprintf( buf, len, "FNEG FR%d", FRn );8.1703 + }8.1704 + break;8.1705 + case 0x5:8.1706 + { /* FABS FRn */8.1707 + uint32_t FRn = ((ir>>8)&0xF);8.1708 + snprintf( buf, len, "FABS FR%d", FRn );8.1709 + }8.1710 + break;8.1711 + case 0x6:8.1712 + { /* FSQRT FRn */8.1713 + uint32_t FRn = ((ir>>8)&0xF);8.1714 + snprintf( buf, len, "FSQRT FR%d", FRn );8.1715 + }8.1716 + break;8.1717 + case 0x7:8.1718 + { /* FSRRA FRn */8.1719 + uint32_t FRn = ((ir>>8)&0xF);8.1720 + snprintf( buf, len, "FSRRA FR%d", FRn );8.1721 + }8.1722 + break;8.1723 + case 0x8:8.1724 + { /* FLDI0 FRn */8.1725 + uint32_t FRn = ((ir>>8)&0xF);8.1726 + snprintf( buf, len, "FLDI0 FR%d", FRn );8.1727 + }8.1728 + break;8.1729 + case 0x9:8.1730 + { /* FLDI1 FRn */8.1731 + uint32_t FRn = ((ir>>8)&0xF);8.1732 + snprintf( buf, len, "FLDI1 FR%d", FRn );8.1733 + }8.1734 + break;8.1735 + case 0xA:8.1736 + { /* FCNVSD FPUL, FRn */8.1737 + uint32_t FRn = ((ir>>8)&0xF);8.1738 + snprintf( buf, len, "FCNVSD FPUL, FR%d", FRn );8.1739 + }8.1740 + break;8.1741 + case 0xB:8.1742 + { /* FCNVDS FRm, FPUL */8.1743 + uint32_t FRm = ((ir>>8)&0xF);8.1744 + snprintf( buf, len, "FCNVDS FR%d, FPUL", FRm );8.1745 + }8.1746 + break;8.1747 + case 0xE:8.1748 + { /* FIPR FVm, FVn */8.1749 + uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);8.1750 + snprintf( buf, len, "FIPR FV%d, FV%d", FVm, FVn );8.1751 + }8.1752 + break;8.1753 + case 0xF:8.1754 + switch( (ir&0x100) >> 8 ) {8.1755 + case 0x0:8.1756 + { /* FSCA FPUL, FRn */8.1757 + uint32_t FRn = ((ir>>9)&0x7)<<1;8.1758 + snprintf( buf, len, "FSCA FPUL, FR%d", FRn );8.1759 + }8.1760 + break;8.1761 + case 0x1:8.1762 + switch( (ir&0x200) >> 9 ) {8.1763 + case 0x0:8.1764 + { /* FTRV XMTRX, FVn */8.1765 + uint32_t FVn = ((ir>>10)&0x3);8.1766 + snprintf( buf, len, "FTRV XMTRX, FV%d", FVn );8.1767 + }8.1768 + break;8.1769 + case 0x1:8.1770 + switch( (ir&0xC00) >> 10 ) {8.1771 + case 0x0:8.1772 + { /* FSCHG */8.1773 + snprintf( buf, len, "FSCHG " );8.1774 + }8.1775 + break;8.1776 + case 0x2:8.1777 + { /* FRCHG */8.1778 + snprintf( buf, len, "FRCHG " );8.1779 + }8.1780 + break;8.1781 + case 0x3:8.1782 + { /* UNDEF */8.1783 + snprintf( buf, len, "UNDEF " );8.1784 + }8.1785 + break;8.1786 + default:8.1787 + UNDEF();8.1788 + break;8.1789 + }8.1790 + break;8.1791 + }8.1792 + break;8.1793 + }8.1794 + break;8.1795 + default:8.1796 + UNDEF();8.1797 + break;8.1798 + }8.1799 + break;8.1800 + case 0xE:8.1801 + { /* FMAC FR0, FRm, FRn */8.1802 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);8.1803 + snprintf( buf, len, "FMAC FR0, FR%d, FR%d", FRm, FRn );8.1804 + }8.1805 + break;8.1806 + default:8.1807 + UNDEF();8.1808 + break;8.1809 + }8.1810 + break;8.1811 + }8.1812 +8.1813 return pc+2;8.1814 }
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00009.2 +++ b/src/sh4/sh4dasm.in Thu Aug 23 12:33:27 2007 +00009.3 @@ -0,0 +1,303 @@9.4 +/**9.5 + * $Id: sh4dasm.in,v 1.1 2007-08-23 12:33:27 nkeynes Exp $9.6 + *9.7 + * SH4 CPU definition and disassembly functions9.8 + *9.9 + * Copyright (c) 2005 Nathan Keynes.9.10 + *9.11 + * This program is free software; you can redistribute it and/or modify9.12 + * it under the terms of the GNU General Public License as published by9.13 + * the Free Software Foundation; either version 2 of the License, or9.14 + * (at your option) any later version.9.15 + *9.16 + * This program is distributed in the hope that it will be useful,9.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of9.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9.19 + * GNU General Public License for more details.9.20 + */9.21 +9.22 +#include "sh4core.h"9.23 +#include "sh4dasm.h"9.24 +#include "mem.h"9.25 +9.26 +#define UNIMP(ir) snprintf( buf, len, "??? " )9.27 +9.28 +9.29 +const struct reg_desc_struct sh4_reg_map[] =9.30 + { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},9.31 + {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},9.32 + {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},9.33 + {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},9.34 + {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},9.35 + {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},9.36 + {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},9.37 + {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},9.38 + {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},9.39 + {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},9.40 + {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},9.41 + {"VBR",REG_INT, &sh4r.vbr},9.42 + {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},9.43 + {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},9.44 + {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr},9.45 + {NULL, 0, NULL} };9.46 +9.47 +9.48 +const struct cpu_desc_struct sh4_cpu_desc =9.49 + { "SH4", sh4_disasm_instruction, sh4_execute_instruction, mem_has_page,9.50 + sh4_set_breakpoint, sh4_clear_breakpoint, sh4_get_breakpoint, 2,9.51 + (char *)&sh4r, sizeof(sh4r), sh4_reg_map,9.52 + &sh4r.pc };9.53 +9.54 +uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )9.55 +{9.56 + uint16_t ir = sh4_read_word(pc);9.57 +9.58 +#define UNDEF(ir) snprintf( buf, len, "???? " );9.59 +#define RN(ir) ((ir&0x0F00)>>8)9.60 +#define RN_BANK(ir) ((ir&0x0070)>>4)9.61 +#define RM(ir) ((ir&0x00F0)>>4)9.62 +#define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */9.63 +#define DISP8(ir) (ir&0x00FF)9.64 +#define PCDISP8(ir) SIGNEXT8(ir&0x00FF)9.65 +#define UIMM8(ir) (ir&0x00FF)9.66 +#define IMM8(ir) SIGNEXT8(ir&0x00FF)9.67 +#define DISP12(ir) SIGNEXT12(ir&0x0FFF)9.68 +#define FVN(ir) ((ir&0x0C00)>>10)9.69 +#define FVM(ir) ((ir&0x0300)>>8)9.70 +9.71 + sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );9.72 +9.73 +%%9.74 +ADD Rm, Rn {: snprintf( buf, len, "ADD R%d, R%d", Rm, Rn ); :}9.75 +ADD #imm, Rn {: snprintf( buf, len, "ADD #%d, R%d", imm, Rn ); :}9.76 +ADDC Rm, Rn {: snprintf( buf, len, "ADDC R%d, R%d", Rm, Rn ); :}9.77 +ADDV Rm, Rn {: snprintf( buf, len, "ADDV R%d, R%d", Rm, Rn ); :}9.78 +AND Rm, Rn {: snprintf( buf, len, "AND R%d, R%d", Rm, Rn ); :}9.79 +AND #imm, R0 {: snprintf( buf, len, "ADD #%d, R0", imm ); :}9.80 +AND.B #imm, @(R0, GBR) {: snprintf( buf, len, "AND.B #%d, @(R0, GBR)", imm ); :}9.81 +BF disp {: snprintf( buf, len, "BF $%xh", disp+pc+4 ); :}9.82 +BF/S disp {: snprintf( buf, len, "BF/S $%xh", disp+pc+4 ); :}9.83 +BRA disp {: snprintf( buf, len, "BRA $%xh", disp+pc+4 ); :}9.84 +BRAF Rn {: snprintf( buf, len, "BRAF R%d", Rn ); :}9.85 +BSR disp {: snprintf( buf, len, "BSR $%xh", disp+pc+4 ); :}9.86 +BSRF Rn {: snprintf( buf, len, "BSRF R%d", Rn ); :}9.87 +BT disp {: snprintf( buf, len, "BT $%xh", disp+pc+4 ); :}9.88 +BT/S disp {: snprintf( buf, len, "BT/S $%xh", disp+pc+4 ); :}9.89 +CLRMAC {: snprintf( buf, len, "CLRMAC " ); :}9.90 +CLRS {: snprintf( buf, len, "CLRS " ); :}9.91 +CLRT {: snprintf( buf, len, "CLRT " ); :}9.92 +CMP/EQ Rm, Rn {: snprintf( buf, len, "CMP/EQ R%d, R%d", Rm, Rn ); :}9.93 +CMP/EQ #imm, R0 {: snprintf( buf, len, "CMP/EQ #%d, R0", imm ); :}9.94 +CMP/GE Rm, Rn {: snprintf( buf, len, "CMP/GE R%d, R%d", Rm, Rn ); :}9.95 +CMP/GT Rm, Rn {: snprintf( buf, len, "CMP/GT R%d, R%d", Rm, Rn ); :}9.96 +CMP/HI Rm, Rn {: snprintf( buf, len, "CMP/HI R%d, R%d", Rm, Rn ); :}9.97 +CMP/HS Rm, Rn {: snprintf( buf, len, "CMP/HS R%d, R%d", Rm, Rn ); :}9.98 +CMP/PL Rn {: snprintf( buf, len, "CMP/PL R%d", Rn ); :}9.99 +CMP/PZ Rn {: snprintf( buf, len, "CMP/PZ R%d", Rn ); :}9.100 +CMP/STR Rm, Rn {: snprintf( buf, len, "CMP/STR R%d, R%d", Rm, Rn ); :}9.101 +DIV0S Rm, Rn {: snprintf( buf, len, "DIV0S R%d, R%d", Rm, Rn ); :}9.102 +DIV0U {: snprintf( buf, len, "DIV0U " ); :}9.103 +DIV1 Rm, Rn {: snprintf( buf, len, "DIV1 R%d, R%d", Rm, Rn ); :}9.104 +DMULS.L Rm, Rn {: snprintf( buf, len, "DMULS.L R%d, R%d", Rm, Rn ); :}9.105 +DMULU.L RM, Rn {: snprintf( buf, len, "DMULU.L R%d, R%d", Rm, Rn ); :}9.106 +DT Rn {: snprintf( buf, len, "DT R%d", Rn ); :}9.107 +EXTS.B Rm, Rn {: snprintf( buf, len, "EXTS.B R%d, R%d", Rm, Rn ); :}9.108 +EXTS.W Rm, Rn {: snprintf( buf, len, "EXTS.W R%d, R%d", Rm, Rn ); :}9.109 +EXTU.B Rm, Rn {: snprintf( buf, len, "EXTU.B R%d, R%d", Rm, Rn ); :}9.110 +EXTU.W Rm, Rn {: snprintf( buf, len, "EXTU.W R%d, R%d", Rm, Rn ); :}9.111 +FABS FRn {: snprintf( buf, len, "FABS FR%d", FRn ); :}9.112 +FADD FRm, FRn {: snprintf( buf, len, "FADD FR%d, FR%d", FRm, FRn ); :}9.113 +FCMP/EQ FRm, FRn {: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", FRm, FRn ); :}9.114 +FCMP/GT FRm, FRn {: snprintf( buf, len, "FCMP/QT FR%d, FR%d", FRm, FRn ); :}9.115 +FCNVDS FRm, FPUL {: snprintf( buf, len, "FCNVDS FR%d, FPUL", FRm ); :}9.116 +FCNVSD FPUL, FRn {: snprintf( buf, len, "FCNVSD FPUL, FR%d", FRn ); :}9.117 +FDIV FRm, FRn {: snprintf( buf, len, "FDIV FR%d, FR%d", FRm, FRn ); :}9.118 +FIPR FVm, FVn {: snprintf( buf, len, "FIPR FV%d, FV%d", FVm, FVn ); :}9.119 +FLDS FRm, FPUL {: snprintf( buf, len, "FLDS FR%d, FPUL", FRm ); :}9.120 +FLDI0 FRn {: snprintf( buf, len, "FLDI0 FR%d", FRn ); :}9.121 +FLDI1 FRn {: snprintf( buf, len, "FLDI1 FR%d", FRn ); :}9.122 +FLOAT FPUL, FRn {: snprintf( buf, len, "FLOAT FPUL, FR%d", FRn ); :}9.123 +FMAC FR0, FRm, FRn {: snprintf( buf, len, "FMAC FR0, FR%d, FR%d", FRm, FRn ); :}9.124 +FMOV FRm, FRn {: snprintf( buf, len, "FMOV FR%d, FR%d", FRm, FRn ); :}9.125 +FMOV FRm, @Rn {: snprintf( buf, len, "FMOV FR%d, @R%d", FRm, Rn ); :}9.126 +FMOV FRm, @-Rn {: snprintf( buf, len, "FMOV FR%d, @-R%d", FRm, Rn ); :}9.127 +FMOV FRm, @(R0, Rn) {: snprintf( buf, len, "FMOV FR%d, @(R0, R%d)", FRm, Rn ); :}9.128 +FMOV @Rm, FRn {: snprintf( buf, len, "FMOV @R%d, FR%d", Rm, FRn ); :}9.129 +FMOV @Rm+, FRn {: snprintf( buf, len, "FMOV @R%d+, FR%d", Rm, FRn ); :}9.130 +FMOV @(R0, Rm), FRn {: snprintf( buf, len, "FMOV @(R0, R%d), FR%d", Rm, FRn ); :}9.131 +FMUL FRm, FRn {: snprintf( buf, len, "FMUL FRm, FR%d", FRm, FRn ); :}9.132 +FNEG FRn {: snprintf( buf, len, "FNEG FR%d", FRn ); :}9.133 +FRCHG {: snprintf( buf, len, "FRCHG " ); :}9.134 +FSCA FPUL, FRn {: snprintf( buf, len, "FSCA FPUL, FR%d", FRn ); :}9.135 +FSCHG {: snprintf( buf, len, "FSCHG " ); :}9.136 +FSQRT FRn {: snprintf( buf, len, "FSQRT FR%d", FRn ); :}9.137 +FSRRA FRn {: snprintf( buf, len, "FSRRA FR%d", FRn ); :}9.138 +FSTS FPUL, FRn {: snprintf( buf, len, "FSTS FPUL, FR%d", FRn ); :}9.139 +FSUB FRm, FRn {: snprintf( buf, len, "FSUB FRm, FR%d", FRm, FRn ); :}9.140 +FTRC FRm, FPUL {: snprintf( buf, len, "FTRC FR%d, FPUL", FRm ); :}9.141 +FTRV XMTRX, FVn {: snprintf( buf, len, "FTRV XMTRX, FV%d", FVn ); :}9.142 +JMP @Rn {: snprintf( buf, len, "JMP @R%d", Rn ); :}9.143 +JSR @Rn {: snprintf( buf, len, "JSR @R%d", Rn ); :}9.144 +LDC Rm, GBR {: snprintf( buf, len, "LDC R%d, GBR", Rm ); :}9.145 +LDC Rm, SR {: snprintf( buf, len, "LDC R%d, SR", Rm ); :}9.146 +LDC Rm, VBR {: snprintf( buf, len, "LDC R%d, VBR", Rm ); :}9.147 +LDC Rm, SSR {: snprintf( buf, len, "LDC R%d, SSR", Rm ); :}9.148 +LDC Rm, SGR {: snprintf( buf, len, "LDC R%d, SGR", Rm ); :}9.149 +LDC Rm, SPC {: snprintf( buf, len, "LDC R%d, SPC", Rm ); :}9.150 +LDC Rm, DBR {: snprintf( buf, len, "LDC R%d, DBR", Rm ); :}9.151 +LDC Rm, Rn_BANK {: snprintf( buf, len, "LDC R%d, R%d_BANK", Rm, Rn_BANK ); :}9.152 +LDS Rm, FPSCR {: snprintf( buf, len, "LDS R%d, FPSCR", Rm ); :}9.153 +LDS Rm, FPUL {: snprintf( buf, len, "LDS R%d, FPUL", Rm ); :}9.154 +LDS Rm, MACH {: snprintf( buf, len, "LDS R%d, MACH", Rm ); :}9.155 +LDS Rm, MACL {: snprintf( buf, len, "LDS R%d, MACL", Rm ); :}9.156 +LDS Rm, PR {: snprintf( buf, len, "LDS R%d, PR", Rm ); :}9.157 +LDC.L @Rm+, GBR {: snprintf( buf, len, "LDC.L @R%d+, GBR", Rm ); :}9.158 +LDC.L @Rm+, SR {: snprintf( buf, len, "LDC.L @R%d+, SR", Rm ); :}9.159 +LDC.L @Rm+, VBR {: snprintf( buf, len, "LDC.L @R%d+, VBR", Rm ); :}9.160 +LDC.L @Rm+, SSR {: snprintf( buf, len, "LDC.L @R%d+, SSR", Rm ); :}9.161 +LDC.L @Rm+, SGR {: snprintf( buf, len, "LDC.L @R%d+, SGR", Rm ); :}9.162 +LDC.L @Rm+, SPC {: snprintf( buf, len, "LDC.L @R%d+, SPC", Rm ); :}9.163 +LDC.L @Rm+, DBR {: snprintf( buf, len, "LDC.L @R%d+, DBR", Rm ); :}9.164 +LDC.L @Rm+, Rn_BANK{: snprintf( buf, len, "LDC.L @R%d+, @R%d+_BANK", Rm, Rn_BANK ); :}9.165 +LDS.L @Rm+, FPSCR{: snprintf( buf, len, "LDS.L @R%d+, FPSCR", Rm ); :}9.166 +LDS.L @Rm+, FPUL {: snprintf( buf, len, "LDS.L @R%d+, FPUL", Rm ); :}9.167 +LDS.L @Rm+, MACH {: snprintf( buf, len, "LDS.L @R%d+, MACH", Rm ); :}9.168 +LDS.L @Rm+, MACL {: snprintf( buf, len, "LDS.L @R%d+, MACL", Rm ); :}9.169 +LDS.L @Rm+, PR {: snprintf( buf, len, "LDS.L @R%d+, PR", Rm ); :}9.170 +LDTLB {: snprintf( buf, len, "LDTLB " ); :}9.171 +MAC.L @Rm+, @Rn+ {: snprintf( buf, len, "MAC.L @R%d+, @R%d+", Rm, Rn ); :}9.172 +MAC.W @Rm+, @Rn+ {: snprintf( buf, len, "MAC.W @R%d+, @R%d+", Rm, Rn ); :}9.173 +MOV Rm, Rn {: snprintf( buf, len, "MOV R%d, R%d", Rm, Rn ); :}9.174 +MOV #imm, Rn {: snprintf( buf, len, "MOV #%d, R%d", imm, Rn ); :}9.175 +MOV.B Rm, @Rn {: snprintf( buf, len, "MOV.B R%d, @R%d", Rm, Rn ); :}9.176 +MOV.B Rm, @-Rn {: snprintf( buf, len, "MOV.B R%d, @-R%d", Rm, Rn ); :}9.177 +MOV.B Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.B R%d, @(R0, R%d)", Rm, Rn ); :}9.178 +MOV.B R0, @(disp, GBR) {: snprintf( buf, len, "MOV.B R0, @(%d, GBR)", disp ); :}9.179 +MOV.B R0, @(disp, Rn) {: snprintf( buf, len, "MOV.B R0, @(%d, R%d)", disp, Rn ); :}9.180 +MOV.B @Rm, Rn {: snprintf( buf, len, "MOV.B @R%d, R%d", Rm, Rn ); :}9.181 +MOV.B @Rm+, Rn {: snprintf( buf, len, "MOV.B @R%d+, R%d", Rm, Rn ); :}9.182 +MOV.B @(R0, Rm), Rn {: snprintf( buf, len, "MOV.B @(R0, R%d), R%d", Rm, Rn ); :}9.183 +MOV.B @(disp, GBR), R0{: snprintf( buf, len, "MOV.B @(%d, GBR), R0", disp ); :}9.184 +MOV.B @(disp, Rm), R0 {: snprintf( buf, len, "MOV.B @(%d, R%d), R0", disp, Rm ); :}9.185 +MOV.L Rm, @Rn {: snprintf( buf, len, "MOV.L R%d, @R%d", Rm, Rn ); :}9.186 +MOV.L Rm, @-Rn {: snprintf( buf, len, "MOV.L R%d, @-R%d", Rm, Rn ); :}9.187 +MOV.L Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.L R%d, @(R0, R%d)", Rm, Rn ); :}9.188 +MOV.L R0, @(disp, GBR) {: snprintf( buf, len, "MOV.L R0, @(%d, GBR)", disp ); :}9.189 +MOV.L Rm, @(disp, Rn) {: snprintf( buf, len, "MOV.L R%d, @(%d, R%d)", Rm, disp, Rn ); :}9.190 +MOV.L @Rm, Rn {: snprintf( buf, len, "MOV.L @R%d, R%d", Rm, Rn ); :}9.191 +MOV.L @Rm+, Rn {: snprintf( buf, len, "MOV.L @R%d+, R%d", Rm, Rn ); :}9.192 +MOV.L @(R0, Rm), Rn {: snprintf( buf, len, "MOV.L @(R0, R%d), R%d", Rm, Rn ); :}9.193 +MOV.L @(disp, GBR), R0 {: snprintf( buf, len, "MOV.L @(%d, GBR), R0",disp ); :}9.194 +MOV.L @(disp, PC), Rn {: snprintf( buf, len, "MOV.L @($%xh), R%d ; <- #%08x", disp + (pc & 0xFFFFFFFC) + 4, Rn, sh4_read_long(disp+(pc&0xFFFFFFFC)+4) ); :}9.195 +MOV.L @(disp, Rm), Rn {: snprintf( buf, len, "MOV.L @(%d, R%d), @R%d", disp, Rm, Rn ); :}9.196 +MOV.W Rm, @Rn {: snprintf( buf, len, "MOV.W R%d, @R%d", Rm, Rn ); :}9.197 +MOV.W Rm, @-Rn {: snprintf( buf, len, "MOV.W R%d, @-R%d", Rm, Rn ); :}9.198 +MOV.W Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.W R%d, @(R0, R%d)", Rm, Rn ); :}9.199 +MOV.W R0, @(disp, GBR) {: snprintf( buf, len, "MOV.W R0, @(%d, GBR)", disp); :}9.200 +MOV.W R0, @(disp, Rn) {: snprintf( buf, len, "MOV.W R0, @(%d, Rn)", disp, Rn ); :}9.201 +MOV.W @Rm, Rn {: snprintf( buf, len, "MOV.W @R%d, R%d", Rm, Rn ); :}9.202 +MOV.W @Rm+, Rn {: snprintf( buf, len, "MOV.W @R%d+, R%d", Rm, Rn ); :}9.203 +MOV.W @(R0, Rm), Rn {: snprintf( buf, len, "MOV.W @(R0, R%d), R%d", Rm, Rn ); :}9.204 +MOV.W @(disp, GBR), R0 {: snprintf( buf, len, "MOV.W @(%d, GBR), R0", disp ); :}9.205 +MOV.W @(disp, PC), Rn {: snprintf( buf, len, "MOV.W @($%xh), R%d ; <- #%08x", disp + pc + 4, Rn, sh4_read_word(disp+pc+4) ); :}9.206 +MOV.W @(disp, Rm), R0 {: snprintf( buf, len, "MOV.W @(%d, R%d), R0", disp, Rm ); :}9.207 +MOVA @(disp, PC), R0 {: snprintf( buf, len, "MOVA @($%xh), R0", disp + (pc&0xFFFFFFFC) + 4 ); :}9.208 +MOVCA.L R0, @Rn {: snprintf( buf, len, "MOVCA.L R0, @R%d", Rn ); :}9.209 +MOVT Rn {: snprintf( buf, len, "MOVT R%d", Rn ); :}9.210 +MUL.L Rm, Rn {: snprintf( buf, len, "MUL.L R%d, R%d", Rm, Rn ); :}9.211 +MULS.W Rm, Rn {: snprintf( buf, len, "MULS.W R%d, R%d", Rm, Rn ); :}9.212 +MULU.W Rm, Rn {: snprintf( buf, len, "MULU.W R%d, R%d", Rm, Rn ); :}9.213 +NEG Rm, Rn {: snprintf( buf, len, "NEG R%d, R%d", Rm, Rn ); :}9.214 +NEGC Rm, Rn {: snprintf( buf, len, "NEGC R%d, R%d", Rm, Rn ); :}9.215 +NOP {: snprintf( buf, len, "NOP " ); :}9.216 +NOT Rm, Rn {: snprintf( buf, len, "NOT R%d, R%d", Rm, Rn ); :}9.217 +OCBI @Rn {: snprintf( buf, len, "OCBI @R%d", Rn ); :}9.218 +OCBP @Rn {: snprintf( buf, len, "OCBP @R%d", Rn ); :}9.219 +OCBWB @Rn {: snprintf( buf, len, "OCBWB @R%d", Rn ); :}9.220 +OR Rm, Rn {: snprintf( buf, len, "OR R%d, R%d", Rm, Rn ); :}9.221 +OR #imm, R0 {: snprintf( buf, len, "OR #%d, R0", imm ); :}9.222 +OR.B #imm, @(R0, GBR) {: snprintf( buf, len, "OR.B #%d, @(R0, GBR)", imm ); :}9.223 +PREF @Rn {: snprintf( buf, len, "PREF R%d", Rn ); :}9.224 +ROTCL Rn {: snprintf( buf, len, "ROTCL R%d", Rn ); :}9.225 +ROTCR Rn {: snprintf( buf, len, "ROTCR R%d", Rn ); :}9.226 +ROTL Rn {: snprintf( buf, len, "ROTL R%d", Rn ); :}9.227 +ROTR Rn {: snprintf( buf, len, "ROTR R%d", Rn ); :}9.228 +RTE {: snprintf( buf, len, "RTE " ); :}9.229 +RTS {: snprintf( buf, len, "RTS " ); :}9.230 +SETS {: snprintf( buf, len, "SETS " ); :}9.231 +SETT {: snprintf( buf, len, "SETT " ); :}9.232 +SHAD Rm, Rn {: snprintf( buf, len, "SHAD R%d, R%d", Rm, Rn ); :}9.233 +SHAL Rn {: snprintf( buf, len, "SHAL R%d", Rn ); :}9.234 +SHAR Rn {: snprintf( buf, len, "SHAR R%d", Rn ); :}9.235 +SHLD Rm, Rn {: snprintf( buf, len, "SHLD R%d, R%d", Rm, Rn ); :}9.236 +SHLL Rn {: snprintf( buf, len, "SHLL R%d", Rn ); :}9.237 +SHLL2 Rn {: snprintf( buf, len, "SHLL2 R%d", Rn ); :}9.238 +SHLL8 Rn {: snprintf( buf, len, "SHLL8 R%d", Rn ); :}9.239 +SHLL16 Rn {: snprintf( buf, len, "SHLL16 R%d", Rn ); :}9.240 +SHLR Rn {: snprintf( buf, len, "SHLR R%d", Rn ); :}9.241 +SHLR2 Rn {: snprintf( buf, len, "SHLR2 R%d", Rn ); :}9.242 +SHLR8 Rn {: snprintf( buf, len, "SHLR8 R%d", Rn ); :}9.243 +SHLR16 Rn {: snprintf( buf, len, "SHLR16 R%d", Rn ); :}9.244 +SLEEP {: snprintf( buf, len, "SLEEP " ); :}9.245 +STC SR, Rn {: snprintf( buf, len, "STC SR, R%d", Rn ); :}9.246 +STC GBR, Rn {: snprintf( buf, len, "STC GBR, R%d", Rn ); :}9.247 +STC VBR, Rn {: snprintf( buf, len, "STC VBR, R%d", Rn ); :}9.248 +STC SSR, Rn {: snprintf( buf, len, "STC SSR, R%d", Rn ); :}9.249 +STC SPC, Rn {: snprintf( buf, len, "STC SPC, R%d", Rn ); :}9.250 +STC SGR, Rn {: snprintf( buf, len, "STC SGR, R%d", Rn ); :}9.251 +STC DBR, Rn {: snprintf( buf, len, "STC DBR, R%d", Rn ); :}9.252 +STC Rm_BANK, Rn {: snprintf( buf, len, "STC R%d_BANK, R%d", Rm_BANK, Rn ); :}9.253 +STS FPSCR, Rn {: snprintf( buf, len, "STS FPSCR, R%d", Rn ); :}9.254 +STS FPUL, Rn {: snprintf( buf, len, "STS FPUL, R%d", Rn ); :}9.255 +STS MACH, Rn {: snprintf( buf, len, "STS MACH, R%d", Rn ); :}9.256 +STS MACL, Rn {: snprintf( buf, len, "STS MACL, R%d", Rn ); :}9.257 +STS PR, Rn {: snprintf( buf, len, "STS PR, R%d", Rn ); :}9.258 +STC.L SR, @-Rn {: snprintf( buf, len, "STC.L SR, @-R%d", Rn ); :}9.259 +STC.L GBR, @-Rn {: snprintf( buf, len, "STC.L GBR, @-R%d", Rn ); :}9.260 +STC.L VBR, @-Rn {: snprintf( buf, len, "STC.L VBR, @-R%d", Rn ); :}9.261 +STC.L SSR, @-Rn {: snprintf( buf, len, "STC.L SSR, @-R%d", Rn ); :}9.262 +STC.L SPC, @-Rn {: snprintf( buf, len, "STC.L SPC, @-R%d", Rn ); :}9.263 +STC.L SGR, @-Rn {: snprintf( buf, len, "STC.L SGR, @-R%d", Rn ); :}9.264 +STC.L DBR, @-Rn {: snprintf( buf, len, "STC.L DBR, @-R%d", Rn ); :}9.265 +STC.L Rm_BANK, @-Rn {: snprintf( buf, len, "STC.L @-R%d_BANK, @-R%d", Rm_BANK, Rn ); :}9.266 +STS.L FPSCR, @-Rn{: snprintf( buf, len, "STS.L FPSCR, @-R%d", Rn ); :}9.267 +STS.L FPUL, @-Rn {: snprintf( buf, len, "STS.L FPUL, @-R%d", Rn ); :}9.268 +STS.L MACH, @-Rn {: snprintf( buf, len, "STS.L MACH, @-R%d", Rn ); :}9.269 +STS.L MACL, @-Rn {: snprintf( buf, len, "STS.L MACL, @-R%d", Rn ); :}9.270 +STS.L PR, @-Rn {: snprintf( buf, len, "STS.L PR, @-R%d", Rn ); :}9.271 +SUB Rm, Rn {: snprintf( buf, len, "SUB R%d, R%d", Rm, Rn ); :}9.272 +SUBC Rm, Rn {: snprintf( buf, len, "SUBC R%d, R%d", Rm, Rn ); :}9.273 +SUBV Rm, Rn {: snprintf( buf, len, "SUBV R%d, R%d", Rm, Rn ); :}9.274 +SWAP.B Rm, Rn {: snprintf( buf, len, "SWAP.B R%d, R%d", Rm, Rn ); :}9.275 +SWAP.W Rm, Rn {: snprintf( buf, len, "SWAP.W R%d, R%d", Rm, Rn ); :}9.276 +TAS.B @Rn {: snprintf( buf, len, "TAS.B R%d", Rn ); :}9.277 +TRAPA #imm {: snprintf( buf, len, "TRAPA #%d", imm ); :}9.278 +TST Rm, Rn {: snprintf( buf, len, "TST R%d, R%d", Rm, Rn ); :}9.279 +TST #imm, R0 {: snprintf( buf, len, "TST #%d, R0", imm ); :}9.280 +TST.B #imm, @(R0, GBR) {: snprintf( buf, len, "TST.B #%d, @(R0, GBR)", imm ); :}9.281 +XOR Rm, Rn {: snprintf( buf, len, "XOR R%d, R%d", Rm, Rn ); :}9.282 +XOR #imm, R0 {: snprintf( buf, len, "XOR #%d, R0", imm ); :}9.283 +XOR.B #imm, @(R0, GBR) {: snprintf( buf, len, "XOR.B #%d, @(R0, GBR)", imm ); :}9.284 +XTRCT Rm, Rn {: snprintf( buf, len, "XTRCT R%d, R%d", Rm, Rn ); :}9.285 +UNDEF {: snprintf( buf, len, "UNDEF " ); :}9.286 +%%9.287 + return pc+2;9.288 +}9.289 +9.290 +9.291 +void sh4_disasm_region( const gchar *filename, int from, int to )9.292 +{9.293 + int pc;9.294 + char buf[80];9.295 + char opcode[16];9.296 + FILE *f;9.297 +9.298 + f = fopen( filename, "w" );9.299 + for( pc = from; pc < to; pc+=2 ) {9.300 + buf[0] = '\0';9.301 + sh4_disasm_instruction( pc,9.302 + buf, sizeof(buf), opcode );9.303 + fprintf( f, " %08x: %s %s\n", pc, opcode, buf );9.304 + }9.305 + fclose(f);9.306 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000010.2 +++ b/src/sh4/sh4trans.c Thu Aug 23 12:33:27 2007 +000010.3 @@ -0,0 +1,105 @@10.4 +/**10.5 + * $Id: sh4trans.c,v 1.1 2007-08-23 12:33:27 nkeynes Exp $10.6 + *10.7 + * SH4 translation core module. This part handles the non-target-specific10.8 + * section of the translation.10.9 + *10.10 + * Copyright (c) 2005 Nathan Keynes.10.11 + *10.12 + * This program is free software; you can redistribute it and/or modify10.13 + * it under the terms of the GNU General Public License as published by10.14 + * the Free Software Foundation; either version 2 of the License, or10.15 + * (at your option) any later version.10.16 + *10.17 + * This program is distributed in the hope that it will be useful,10.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of10.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the10.20 + * GNU General Public License for more details.10.21 + */10.22 +10.23 +#include "sh4core.h"10.24 +#include "sh4trans.h"10.25 +#include "xltcache.h"10.26 +10.27 +/**10.28 + * Execute a timeslice using translated code only (ie translate/execute loop)10.29 + * Note this version does not support breakpoints10.30 + */10.31 +uint32_t sh4_xlat_run_slice( uint32_t nanosecs )10.32 +{10.33 + int i, result = 1;10.34 + sh4r.slice_cycle = 0;10.35 +10.36 + if( sh4r.sh4_state != SH4_STATE_RUNNING ) {10.37 + if( sh4r.event_pending < nanosecs ) {10.38 + sh4r.sh4_state = SH4_STATE_RUNNING;10.39 + sh4r.slice_cycle = sh4r.event_pending;10.40 + }10.41 + }10.42 +10.43 + for( ; sh4r.slice_cycle < nanosecs && result != 0; sh4r.slice_cycle ) {10.44 + if( SH4_EVENT_PENDING() ) {10.45 + if( sh4r.event_types & PENDING_EVENT ) {10.46 + event_execute();10.47 + }10.48 + /* Eventq execute may (quite likely) deliver an immediate IRQ */10.49 + if( sh4r.event_types & PENDING_IRQ ) {10.50 + sh4_accept_interrupt();10.51 + }10.52 + }10.53 +10.54 + int (*code)() = xlat_get_code(sh4r.pc);10.55 + if( code == NULL ) {10.56 + code = sh4_translate_basic_block( sh4r.pc );10.57 + }10.58 + result = code();10.59 + sh4r.slice_cycle += result;10.60 + }10.61 +10.62 + /* If we aborted early, but the cpu is still technically running,10.63 + * we're doing a hard abort - cut the timeslice back to what we10.64 + * actually executed10.65 + */10.66 + if( sh4r.slice_cycle < nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {10.67 + nanosecs = sh4r.slice_cycle;10.68 + }10.69 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {10.70 + TMU_run_slice( nanosecs );10.71 + SCIF_run_slice( nanosecs );10.72 + }10.73 + return nanosecs;10.74 +}10.75 +10.76 +uint8_t *xlat_output;10.77 +10.78 +/**10.79 + * Translate a linear basic block, ie all instructions from the start address10.80 + * (inclusive) until the next branch/jump instruction or the end of the page10.81 + * is reached.10.82 + * @return the address of the translated block10.83 + * eg due to lack of buffer space.10.84 + */10.85 +void * sh4_translate_basic_block( sh4addr_t start )10.86 +{10.87 + uint32_t pc = start;10.88 + int done;10.89 + xlat_cache_block_t block = xlat_start_block( start );10.90 + xlat_output = (uint8_t *)block->code;10.91 + uint8_t *eob = xlat_output + block->size;10.92 + sh4_translate_begin_block();10.93 +10.94 + while( (done = sh4_x86_translate_instruction( pc )) == 0 ) {10.95 + if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {10.96 + uint8_t *oldstart = block->code;10.97 + block = xlat_extend_block();10.98 + xlat_output = block->code + (xlat_output - oldstart);10.99 + eob = block->code + block->size;10.100 + }10.101 + pc += 2;10.102 + }10.103 + sh4_translate_end_block(done);10.104 + xlat_commit_block( xlat_output - block->size, pc-start );10.105 + return block->code;10.106 +}10.107 +10.108 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000011.2 +++ b/src/sh4/sh4trans.h Thu Aug 23 12:33:27 2007 +000011.3 @@ -0,0 +1,46 @@11.4 +/**11.5 + * $Id: sh4trans.h,v 1.1 2007-08-23 12:33:27 nkeynes Exp $11.6 + *11.7 + * SH4->x86 translation module11.8 + *11.9 + * Copyright (c) 2005 Nathan Keynes.11.10 + *11.11 + * This program is free software; you can redistribute it and/or modify11.12 + * it under the terms of the GNU General Public License as published by11.13 + * the Free Software Foundation; either version 2 of the License, or11.14 + * (at your option) any later version.11.15 + *11.16 + * This program is distributed in the hope that it will be useful,11.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of11.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11.19 + * GNU General Public License for more details.11.20 + */11.21 +11.22 +#include "dream.h"11.23 +#include "mem.h"11.24 +11.25 +/** Maximum size of a translated instruction, in bytes. This includes potentially11.26 + * writing the entire epilogue11.27 + */11.28 +#define MAX_INSTRUCTION_SIZE 3211.29 +11.30 +/**11.31 +11.32 + */11.33 +uint32_t sh4_xlat_run_slice( uint32_t nanosecs );11.34 +11.35 +/**11.36 + * Translate the specified block of code starting from the specified start11.37 + * address until the first branch/jump instruction.11.38 + */11.39 +void *sh4_translate_basic_block( sh4addr_t start );11.40 +11.41 +extern uint8_t *xlat_output;11.42 +11.43 +/************** Output generation ***************/11.44 +11.45 +void sh4_translate_begin_block();11.46 +11.47 +uint32_t sh4_x86_translate_instruction( sh4addr_t pc );11.48 +11.49 +void sh4_translate_end_block( sh4addr_t pc );
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000012.2 +++ b/src/sh4/sh4x86.c Thu Aug 23 12:33:27 2007 +000012.3 @@ -0,0 +1,1779 @@12.4 +/**12.5 + * $Id: sh4x86.c,v 1.1 2007-08-23 12:33:27 nkeynes Exp $12.6 + *12.7 + * SH4 => x86 translation. This version does no real optimization, it just12.8 + * outputs straight-line x86 code - it mainly exists to provide a baseline12.9 + * to test the optimizing versions against.12.10 + *12.11 + * Copyright (c) 2007 Nathan Keynes.12.12 + *12.13 + * This program is free software; you can redistribute it and/or modify12.14 + * it under the terms of the GNU General Public License as published by12.15 + * the Free Software Foundation; either version 2 of the License, or12.16 + * (at your option) any later version.12.17 + *12.18 + * This program is distributed in the hope that it will be useful,12.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of12.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12.21 + * GNU General Public License for more details.12.22 + */12.23 +12.24 +#include "sh4core.h"12.25 +#include "sh4trans.h"12.26 +#include "x86op.h"12.27 +12.28 +/**12.29 + * Emit an instruction to load an SH4 reg into a real register12.30 + */12.31 +static inline void load_reg( int x86reg, int sh4reg )12.32 +{12.33 + /* mov [bp+n], reg */12.34 + OP(0x89);12.35 + OP(0x45 + x86reg<<3);12.36 + OP(REG_OFFSET(r[sh4reg]));12.37 +}12.38 +12.39 +static inline void load_spreg( int x86reg, int regoffset )12.40 +{12.41 + /* mov [bp+n], reg */12.42 + OP(0x89);12.43 + OP(0x45 + x86reg<<3);12.44 + OP(regoffset);12.45 +}12.46 +12.47 +#define UNDEF()12.48 +#define MEM_READ_BYTE( addr_reg, value_reg )12.49 +#define MEM_READ_WORD( addr_reg, value_reg )12.50 +#define MEM_READ_LONG( addr_reg, value_reg )12.51 +#define MEM_WRITE_BYTE( addr_reg, value_reg )12.52 +#define MEM_WRITE_WORD( addr_reg, value_reg )12.53 +#define MEM_WRITE_LONG( addr_reg, value_reg )12.54 +12.55 +/**12.56 + * Emit an instruction to load an immediate value into a register12.57 + */12.58 +static inline void load_imm32( int x86reg, uint32_t value ) {12.59 + /* mov #value, reg */12.60 + OP(0xB8 + x86reg);12.61 + OP32(value);12.62 +}12.63 +12.64 +/**12.65 + * Emit an instruction to store an SH4 reg (RN)12.66 + */12.67 +void static inline store_reg( int x86reg, int sh4reg ) {12.68 + /* mov reg, [bp+n] */12.69 + OP(0x8B);12.70 + OP(0x45 + x86reg<<3);12.71 + OP(REG_OFFSET(r[sh4reg]));12.72 +}12.73 +void static inline store_spreg( int x86reg, int regoffset ) {12.74 + /* mov reg, [bp+n] */12.75 + OP(0x8B);12.76 + OP(0x45 + x86reg<<3);12.77 + OP(regoffset);12.78 +}12.79 +12.80 +12.81 +/**12.82 + * Emit the 'start of block' assembly. Sets up the stack frame and save12.83 + * SI/DI as required12.84 + */12.85 +void sh4_translate_begin_block() {12.86 + /* push ebp */12.87 + *xlat_output++ = 0x50 + R_EBP;12.88 +12.89 + /* mov &sh4r, ebp */12.90 + load_imm32( R_EBP, (uint32_t)&sh4r );12.91 +12.92 + /* load carry from SR */12.93 +}12.94 +12.95 +/**12.96 + * Flush any open regs back to memory, restore SI/DI/, update PC, etc12.97 + */12.98 +void sh4_translate_end_block( sh4addr_t pc ) {12.99 + /* pop ebp */12.100 + *xlat_output++ = 0x58 + R_EBP;12.101 +12.102 + /* ret */12.103 + *xlat_output++ = 0xC3;12.104 +}12.105 +12.106 +/**12.107 + * Translate a single instruction. Delayed branches are handled specially12.108 + * by translating both branch and delayed instruction as a single unit (as12.109 + *12.110 + *12.111 + * @return true if the instruction marks the end of a basic block12.112 + * (eg a branch or12.113 + */12.114 +uint32_t sh4_x86_translate_instruction( uint32_t pc )12.115 +{12.116 + uint16_t ir = 0;12.117 +12.118 + switch( (ir&0xF000) >> 12 ) {12.119 + case 0x0:12.120 + switch( ir&0xF ) {12.121 + case 0x2:12.122 + switch( (ir&0x80) >> 7 ) {12.123 + case 0x0:12.124 + switch( (ir&0x70) >> 4 ) {12.125 + case 0x0:12.126 + { /* STC SR, Rn */12.127 + uint32_t Rn = ((ir>>8)&0xF);12.128 + /* TODO */12.129 + }12.130 + break;12.131 + case 0x1:12.132 + { /* STC GBR, Rn */12.133 + uint32_t Rn = ((ir>>8)&0xF);12.134 + load_spreg( R_EAX, R_GBR );12.135 + store_reg( R_EAX, Rn );12.136 + }12.137 + break;12.138 + case 0x2:12.139 + { /* STC VBR, Rn */12.140 + uint32_t Rn = ((ir>>8)&0xF);12.141 + load_spreg( R_EAX, R_VBR );12.142 + store_reg( R_EAX, Rn );12.143 + }12.144 + break;12.145 + case 0x3:12.146 + { /* STC SSR, Rn */12.147 + uint32_t Rn = ((ir>>8)&0xF);12.148 + load_spreg( R_EAX, R_SSR );12.149 + store_reg( R_EAX, Rn );12.150 + }12.151 + break;12.152 + case 0x4:12.153 + { /* STC SPC, Rn */12.154 + uint32_t Rn = ((ir>>8)&0xF);12.155 + load_spreg( R_EAX, R_SPC );12.156 + store_reg( R_EAX, Rn );12.157 + }12.158 + break;12.159 + default:12.160 + UNDEF();12.161 + break;12.162 + }12.163 + break;12.164 + case 0x1:12.165 + { /* STC Rm_BANK, Rn */12.166 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);12.167 + /* TODO */12.168 + }12.169 + break;12.170 + }12.171 + break;12.172 + case 0x3:12.173 + switch( (ir&0xF0) >> 4 ) {12.174 + case 0x0:12.175 + { /* BSRF Rn */12.176 + uint32_t Rn = ((ir>>8)&0xF);12.177 + }12.178 + break;12.179 + case 0x2:12.180 + { /* BRAF Rn */12.181 + uint32_t Rn = ((ir>>8)&0xF);12.182 + }12.183 + break;12.184 + case 0x8:12.185 + { /* PREF @Rn */12.186 + uint32_t Rn = ((ir>>8)&0xF);12.187 + }12.188 + break;12.189 + case 0x9:12.190 + { /* OCBI @Rn */12.191 + uint32_t Rn = ((ir>>8)&0xF);12.192 + }12.193 + break;12.194 + case 0xA:12.195 + { /* OCBP @Rn */12.196 + uint32_t Rn = ((ir>>8)&0xF);12.197 + }12.198 + break;12.199 + case 0xB:12.200 + { /* OCBWB @Rn */12.201 + uint32_t Rn = ((ir>>8)&0xF);12.202 + }12.203 + break;12.204 + case 0xC:12.205 + { /* MOVCA.L R0, @Rn */12.206 + uint32_t Rn = ((ir>>8)&0xF);12.207 + }12.208 + break;12.209 + default:12.210 + UNDEF();12.211 + break;12.212 + }12.213 + break;12.214 + case 0x4:12.215 + { /* MOV.B Rm, @(R0, Rn) */12.216 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.217 + load_reg( R_EAX, 0 );12.218 + load_reg( R_ECX, Rn );12.219 + ADD_r32_r32( R_EAX, R_ECX );12.220 + load_reg( R_EAX, Rm );12.221 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.222 + }12.223 + break;12.224 + case 0x5:12.225 + { /* MOV.W Rm, @(R0, Rn) */12.226 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.227 + }12.228 + break;12.229 + case 0x6:12.230 + { /* MOV.L Rm, @(R0, Rn) */12.231 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.232 + }12.233 + break;12.234 + case 0x7:12.235 + { /* MUL.L Rm, Rn */12.236 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.237 + }12.238 + break;12.239 + case 0x8:12.240 + switch( (ir&0xFF0) >> 4 ) {12.241 + case 0x0:12.242 + { /* CLRT */12.243 + }12.244 + break;12.245 + case 0x1:12.246 + { /* SETT */12.247 + }12.248 + break;12.249 + case 0x2:12.250 + { /* CLRMAC */12.251 + }12.252 + break;12.253 + case 0x3:12.254 + { /* LDTLB */12.255 + }12.256 + break;12.257 + case 0x4:12.258 + { /* CLRS */12.259 + }12.260 + break;12.261 + case 0x5:12.262 + { /* SETS */12.263 + }12.264 + break;12.265 + default:12.266 + UNDEF();12.267 + break;12.268 + }12.269 + break;12.270 + case 0x9:12.271 + switch( (ir&0xF0) >> 4 ) {12.272 + case 0x0:12.273 + { /* NOP */12.274 + /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */12.275 + }12.276 + break;12.277 + case 0x1:12.278 + { /* DIV0U */12.279 + }12.280 + break;12.281 + case 0x2:12.282 + { /* MOVT Rn */12.283 + uint32_t Rn = ((ir>>8)&0xF);12.284 + load_spreg( R_EAX, R_T );12.285 + store_reg( R_EAX, Rn );12.286 + }12.287 + break;12.288 + default:12.289 + UNDEF();12.290 + break;12.291 + }12.292 + break;12.293 + case 0xA:12.294 + switch( (ir&0xF0) >> 4 ) {12.295 + case 0x0:12.296 + { /* STS MACH, Rn */12.297 + uint32_t Rn = ((ir>>8)&0xF);12.298 + load_spreg( R_EAX, R_MACH );12.299 + store_reg( R_EAX, Rn );12.300 + }12.301 + break;12.302 + case 0x1:12.303 + { /* STS MACL, Rn */12.304 + uint32_t Rn = ((ir>>8)&0xF);12.305 + load_spreg( R_EAX, R_MACL );12.306 + store_reg( R_EAX, Rn );12.307 + }12.308 + break;12.309 + case 0x2:12.310 + { /* STS PR, Rn */12.311 + uint32_t Rn = ((ir>>8)&0xF);12.312 + load_spreg( R_EAX, R_PR );12.313 + store_reg( R_EAX, Rn );12.314 + }12.315 + break;12.316 + case 0x3:12.317 + { /* STC SGR, Rn */12.318 + uint32_t Rn = ((ir>>8)&0xF);12.319 + load_spreg( R_EAX, R_SGR );12.320 + store_reg( R_EAX, Rn );12.321 + }12.322 + break;12.323 + case 0x5:12.324 + { /* STS FPUL, Rn */12.325 + uint32_t Rn = ((ir>>8)&0xF);12.326 + load_spreg( R_EAX, R_FPUL );12.327 + store_reg( R_EAX, Rn );12.328 + }12.329 + break;12.330 + case 0x6:12.331 + { /* STS FPSCR, Rn */12.332 + uint32_t Rn = ((ir>>8)&0xF);12.333 + load_spreg( R_EAX, R_FPSCR );12.334 + store_reg( R_EAX, Rn );12.335 + }12.336 + break;12.337 + case 0xF:12.338 + { /* STC DBR, Rn */12.339 + uint32_t Rn = ((ir>>8)&0xF);12.340 + load_spreg( R_EAX, R_DBR );12.341 + store_reg( R_EAX, Rn );12.342 + }12.343 + break;12.344 + default:12.345 + UNDEF();12.346 + break;12.347 + }12.348 + break;12.349 + case 0xB:12.350 + switch( (ir&0xFF0) >> 4 ) {12.351 + case 0x0:12.352 + { /* RTS */12.353 + }12.354 + break;12.355 + case 0x1:12.356 + { /* SLEEP */12.357 + }12.358 + break;12.359 + case 0x2:12.360 + { /* RTE */12.361 + }12.362 + break;12.363 + default:12.364 + UNDEF();12.365 + break;12.366 + }12.367 + break;12.368 + case 0xC:12.369 + { /* MOV.B @(R0, Rm), Rn */12.370 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.371 + load_reg( R_EAX, 0 );12.372 + load_reg( R_ECX, Rm );12.373 + ADD_r32_r32( R_EAX, R_ECX );12.374 + MEM_READ_BYTE( R_ECX, R_EAX );12.375 + store_reg( R_EAX, Rn );12.376 + }12.377 + break;12.378 + case 0xD:12.379 + { /* MOV.W @(R0, Rm), Rn */12.380 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.381 + }12.382 + break;12.383 + case 0xE:12.384 + { /* MOV.L @(R0, Rm), Rn */12.385 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.386 + }12.387 + break;12.388 + case 0xF:12.389 + { /* MAC.L @Rm+, @Rn+ */12.390 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.391 + }12.392 + break;12.393 + default:12.394 + UNDEF();12.395 + break;12.396 + }12.397 + break;12.398 + case 0x1:12.399 + { /* MOV.L Rm, @(disp, Rn) */12.400 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;12.401 + }12.402 + break;12.403 + case 0x2:12.404 + switch( ir&0xF ) {12.405 + case 0x0:12.406 + { /* MOV.B Rm, @Rn */12.407 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.408 + load_reg( R_EAX, Rm );12.409 + load_reg( R_ECX, Rn );12.410 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.411 + }12.412 + break;12.413 + case 0x1:12.414 + { /* MOV.W Rm, @Rn */12.415 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.416 + }12.417 + break;12.418 + case 0x2:12.419 + { /* MOV.L Rm, @Rn */12.420 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.421 + }12.422 + break;12.423 + case 0x4:12.424 + { /* MOV.B Rm, @-Rn */12.425 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.426 + load_reg( R_EAX, Rm );12.427 + load_reg( R_ECX, Rn );12.428 + ADD_imm8s_r32( -1, Rn );12.429 + store_reg( R_ECX, Rn );12.430 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.431 + }12.432 + break;12.433 + case 0x5:12.434 + { /* MOV.W Rm, @-Rn */12.435 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.436 + }12.437 + break;12.438 + case 0x6:12.439 + { /* MOV.L Rm, @-Rn */12.440 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.441 + }12.442 + break;12.443 + case 0x7:12.444 + { /* DIV0S Rm, Rn */12.445 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.446 + }12.447 + break;12.448 + case 0x8:12.449 + { /* TST Rm, Rn */12.450 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.451 + }12.452 + break;12.453 + case 0x9:12.454 + { /* AND Rm, Rn */12.455 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.456 + load_reg( R_EAX, Rm );12.457 + load_reg( R_ECX, Rn );12.458 + AND_r32_r32( R_EAX, R_ECX );12.459 + store_reg( R_ECX, Rn );12.460 + }12.461 + break;12.462 + case 0xA:12.463 + { /* XOR Rm, Rn */12.464 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.465 + load_reg( R_EAX, Rm );12.466 + load_reg( R_ECX, Rn );12.467 + XOR_r32_r32( R_EAX, R_ECX );12.468 + store_reg( R_ECX, Rn );12.469 + }12.470 + break;12.471 + case 0xB:12.472 + { /* OR Rm, Rn */12.473 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.474 + load_reg( R_EAX, Rm );12.475 + load_reg( R_ECX, Rn );12.476 + OR_r32_r32( R_EAX, R_ECX );12.477 + store_reg( R_ECX, Rn );12.478 + }12.479 + break;12.480 + case 0xC:12.481 + { /* CMP/STR Rm, Rn */12.482 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.483 + }12.484 + break;12.485 + case 0xD:12.486 + { /* XTRCT Rm, Rn */12.487 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.488 + }12.489 + break;12.490 + case 0xE:12.491 + { /* MULU.W Rm, Rn */12.492 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.493 + }12.494 + break;12.495 + case 0xF:12.496 + { /* MULS.W Rm, Rn */12.497 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.498 + }12.499 + break;12.500 + default:12.501 + UNDEF();12.502 + break;12.503 + }12.504 + break;12.505 + case 0x3:12.506 + switch( ir&0xF ) {12.507 + case 0x0:12.508 + { /* CMP/EQ Rm, Rn */12.509 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.510 + load_reg( R_EAX, Rm );12.511 + load_reg( R_ECX, Rn );12.512 + CMP_r32_r32( R_EAX, R_ECX );12.513 + SETE_t();12.514 + }12.515 + break;12.516 + case 0x2:12.517 + { /* CMP/HS Rm, Rn */12.518 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.519 + load_reg( R_EAX, Rm );12.520 + load_reg( R_ECX, Rn );12.521 + CMP_r32_r32( R_EAX, R_ECX );12.522 + SETAE_t();12.523 + }12.524 + break;12.525 + case 0x3:12.526 + { /* CMP/GE Rm, Rn */12.527 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.528 + load_reg( R_EAX, Rm );12.529 + load_reg( R_ECX, Rn );12.530 + CMP_r32_r32( R_EAX, R_ECX );12.531 + SETGE_t();12.532 + }12.533 + break;12.534 + case 0x4:12.535 + { /* DIV1 Rm, Rn */12.536 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.537 + }12.538 + break;12.539 + case 0x5:12.540 + { /* DMULU.L Rm, Rn */12.541 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.542 + }12.543 + break;12.544 + case 0x6:12.545 + { /* CMP/HI Rm, Rn */12.546 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.547 + load_reg( R_EAX, Rm );12.548 + load_reg( R_ECX, Rn );12.549 + CMP_r32_r32( R_EAX, R_ECX );12.550 + SETA_t();12.551 + }12.552 + break;12.553 + case 0x7:12.554 + { /* CMP/GT Rm, Rn */12.555 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.556 + load_reg( R_EAX, Rm );12.557 + load_reg( R_ECX, Rn );12.558 + CMP_r32_r32( R_EAX, R_ECX );12.559 + SETG_t();12.560 + }12.561 + break;12.562 + case 0x8:12.563 + { /* SUB Rm, Rn */12.564 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.565 + load_reg( R_EAX, Rm );12.566 + load_reg( R_ECX, Rn );12.567 + SUB_r32_r32( R_EAX, R_ECX );12.568 + store_reg( R_ECX, Rn );12.569 + }12.570 + break;12.571 + case 0xA:12.572 + { /* SUBC Rm, Rn */12.573 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.574 + load_reg( R_EAX, Rm );12.575 + load_reg( R_ECX, Rn );12.576 + LDC_t();12.577 + SBB_r32_r32( R_EAX, R_ECX );12.578 + store_reg( R_ECX, Rn );12.579 + }12.580 + break;12.581 + case 0xB:12.582 + { /* SUBV Rm, Rn */12.583 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.584 + load_reg( R_EAX, Rm );12.585 + load_reg( R_ECX, Rn );12.586 + SUB_r32_r32( R_EAX, R_ECX );12.587 + store_reg( R_ECX, Rn );12.588 + SETO_t();12.589 + }12.590 + break;12.591 + case 0xC:12.592 + { /* ADD Rm, Rn */12.593 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.594 + load_reg( R_EAX, Rm );12.595 + load_reg( R_ECX, Rn );12.596 + ADD_r32_r32( R_EAX, R_ECX );12.597 + store_reg( R_ECX, Rn );12.598 + }12.599 + break;12.600 + case 0xD:12.601 + { /* DMULS.L Rm, Rn */12.602 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.603 + }12.604 + break;12.605 + case 0xE:12.606 + { /* ADDC Rm, Rn */12.607 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.608 + load_reg( R_EAX, Rm );12.609 + load_reg( R_ECX, Rn );12.610 + LDC_t();12.611 + ADC_r32_r32( R_EAX, R_ECX );12.612 + store_reg( R_ECX, Rn );12.613 + SETC_t();12.614 + }12.615 + break;12.616 + case 0xF:12.617 + { /* ADDV Rm, Rn */12.618 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.619 + load_reg( R_EAX, Rm );12.620 + load_reg( R_ECX, Rn );12.621 + ADD_r32_r32( R_EAX, R_ECX );12.622 + store_reg( R_ECX, Rn );12.623 + SETO_t();12.624 + }12.625 + break;12.626 + default:12.627 + UNDEF();12.628 + break;12.629 + }12.630 + break;12.631 + case 0x4:12.632 + switch( ir&0xF ) {12.633 + case 0x0:12.634 + switch( (ir&0xF0) >> 4 ) {12.635 + case 0x0:12.636 + { /* SHLL Rn */12.637 + uint32_t Rn = ((ir>>8)&0xF);12.638 + load_reg( R_EAX, Rn );12.639 + SHL1_r32( R_EAX );12.640 + store_reg( R_EAX, Rn );12.641 + }12.642 + break;12.643 + case 0x1:12.644 + { /* DT Rn */12.645 + uint32_t Rn = ((ir>>8)&0xF);12.646 + load_reg( R_EAX, Rn );12.647 + ADD_imm8s_r32( -1, Rn );12.648 + store_reg( R_EAX, Rn );12.649 + SETE_t();12.650 + }12.651 + break;12.652 + case 0x2:12.653 + { /* SHAL Rn */12.654 + uint32_t Rn = ((ir>>8)&0xF);12.655 + load_reg( R_EAX, Rn );12.656 + SHL1_r32( R_EAX );12.657 + store_reg( R_EAX, Rn );12.658 + }12.659 + break;12.660 + default:12.661 + UNDEF();12.662 + break;12.663 + }12.664 + break;12.665 + case 0x1:12.666 + switch( (ir&0xF0) >> 4 ) {12.667 + case 0x0:12.668 + { /* SHLR Rn */12.669 + uint32_t Rn = ((ir>>8)&0xF);12.670 + load_reg( R_EAX, Rn );12.671 + SHR1_r32( R_EAX );12.672 + store_reg( R_EAX, Rn );12.673 + }12.674 + break;12.675 + case 0x1:12.676 + { /* CMP/PZ Rn */12.677 + uint32_t Rn = ((ir>>8)&0xF);12.678 + load_reg( R_EAX, Rn );12.679 + CMP_imm8s_r32( 0, R_EAX );12.680 + SETGE_t();12.681 + }12.682 + break;12.683 + case 0x2:12.684 + { /* SHAR Rn */12.685 + uint32_t Rn = ((ir>>8)&0xF);12.686 + load_reg( R_EAX, Rn );12.687 + SAR1_r32( R_EAX );12.688 + store_reg( R_EAX, Rn );12.689 + }12.690 + break;12.691 + default:12.692 + UNDEF();12.693 + break;12.694 + }12.695 + break;12.696 + case 0x2:12.697 + switch( (ir&0xF0) >> 4 ) {12.698 + case 0x0:12.699 + { /* STS.L MACH, @-Rn */12.700 + uint32_t Rn = ((ir>>8)&0xF);12.701 + load_reg( R_ECX, Rn );12.702 + ADD_imm8s_r32( -4, Rn );12.703 + store_reg( R_ECX, Rn );12.704 + load_spreg( R_EAX, R_MACH );12.705 + MEM_WRITE_LONG( R_ECX, R_EAX );12.706 + }12.707 + break;12.708 + case 0x1:12.709 + { /* STS.L MACL, @-Rn */12.710 + uint32_t Rn = ((ir>>8)&0xF);12.711 + load_reg( R_ECX, Rn );12.712 + ADD_imm8s_r32( -4, Rn );12.713 + store_reg( R_ECX, Rn );12.714 + load_spreg( R_EAX, R_MACL );12.715 + MEM_WRITE_LONG( R_ECX, R_EAX );12.716 + }12.717 + break;12.718 + case 0x2:12.719 + { /* STS.L PR, @-Rn */12.720 + uint32_t Rn = ((ir>>8)&0xF);12.721 + load_reg( R_ECX, Rn );12.722 + ADD_imm8s_r32( -4, Rn );12.723 + store_reg( R_ECX, Rn );12.724 + load_spreg( R_EAX, R_PR );12.725 + MEM_WRITE_LONG( R_ECX, R_EAX );12.726 + }12.727 + break;12.728 + case 0x3:12.729 + { /* STC.L SGR, @-Rn */12.730 + uint32_t Rn = ((ir>>8)&0xF);12.731 + load_reg( R_ECX, Rn );12.732 + ADD_imm8s_r32( -4, Rn );12.733 + store_reg( R_ECX, Rn );12.734 + load_spreg( R_EAX, R_SGR );12.735 + MEM_WRITE_LONG( R_ECX, R_EAX );12.736 + }12.737 + break;12.738 + case 0x5:12.739 + { /* STS.L FPUL, @-Rn */12.740 + uint32_t Rn = ((ir>>8)&0xF);12.741 + load_reg( R_ECX, Rn );12.742 + ADD_imm8s_r32( -4, Rn );12.743 + store_reg( R_ECX, Rn );12.744 + load_spreg( R_EAX, R_FPUL );12.745 + MEM_WRITE_LONG( R_ECX, R_EAX );12.746 + }12.747 + break;12.748 + case 0x6:12.749 + { /* STS.L FPSCR, @-Rn */12.750 + uint32_t Rn = ((ir>>8)&0xF);12.751 + load_reg( R_ECX, Rn );12.752 + ADD_imm8s_r32( -4, Rn );12.753 + store_reg( R_ECX, Rn );12.754 + load_spreg( R_EAX, R_FPSCR );12.755 + MEM_WRITE_LONG( R_ECX, R_EAX );12.756 + }12.757 + break;12.758 + case 0xF:12.759 + { /* STC.L DBR, @-Rn */12.760 + uint32_t Rn = ((ir>>8)&0xF);12.761 + load_reg( R_ECX, Rn );12.762 + ADD_imm8s_r32( -4, Rn );12.763 + store_reg( R_ECX, Rn );12.764 + load_spreg( R_EAX, R_DBR );12.765 + MEM_WRITE_LONG( R_ECX, R_EAX );12.766 + }12.767 + break;12.768 + default:12.769 + UNDEF();12.770 + break;12.771 + }12.772 + break;12.773 + case 0x3:12.774 + switch( (ir&0x80) >> 7 ) {12.775 + case 0x0:12.776 + switch( (ir&0x70) >> 4 ) {12.777 + case 0x0:12.778 + { /* STC.L SR, @-Rn */12.779 + uint32_t Rn = ((ir>>8)&0xF);12.780 + /* TODO */12.781 + }12.782 + break;12.783 + case 0x1:12.784 + { /* STC.L GBR, @-Rn */12.785 + uint32_t Rn = ((ir>>8)&0xF);12.786 + load_reg( R_ECX, Rn );12.787 + ADD_imm8s_r32( -4, Rn );12.788 + store_reg( R_ECX, Rn );12.789 + load_spreg( R_EAX, R_GBR );12.790 + MEM_WRITE_LONG( R_ECX, R_EAX );12.791 + }12.792 + break;12.793 + case 0x2:12.794 + { /* STC.L VBR, @-Rn */12.795 + uint32_t Rn = ((ir>>8)&0xF);12.796 + load_reg( R_ECX, Rn );12.797 + ADD_imm8s_r32( -4, Rn );12.798 + store_reg( R_ECX, Rn );12.799 + load_spreg( R_EAX, R_VBR );12.800 + MEM_WRITE_LONG( R_ECX, R_EAX );12.801 + }12.802 + break;12.803 + case 0x3:12.804 + { /* STC.L SSR, @-Rn */12.805 + uint32_t Rn = ((ir>>8)&0xF);12.806 + load_reg( R_ECX, Rn );12.807 + ADD_imm8s_r32( -4, Rn );12.808 + store_reg( R_ECX, Rn );12.809 + load_spreg( R_EAX, R_SSR );12.810 + MEM_WRITE_LONG( R_ECX, R_EAX );12.811 + }12.812 + break;12.813 + case 0x4:12.814 + { /* STC.L SPC, @-Rn */12.815 + uint32_t Rn = ((ir>>8)&0xF);12.816 + load_reg( R_ECX, Rn );12.817 + ADD_imm8s_r32( -4, Rn );12.818 + store_reg( R_ECX, Rn );12.819 + load_spreg( R_EAX, R_SPC );12.820 + MEM_WRITE_LONG( R_ECX, R_EAX );12.821 + }12.822 + break;12.823 + default:12.824 + UNDEF();12.825 + break;12.826 + }12.827 + break;12.828 + case 0x1:12.829 + { /* STC.L Rm_BANK, @-Rn */12.830 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);12.831 + }12.832 + break;12.833 + }12.834 + break;12.835 + case 0x4:12.836 + switch( (ir&0xF0) >> 4 ) {12.837 + case 0x0:12.838 + { /* ROTL Rn */12.839 + uint32_t Rn = ((ir>>8)&0xF);12.840 + load_reg( R_EAX, Rn );12.841 + ROL1_r32( R_EAX );12.842 + store_reg( R_EAX, Rn );12.843 + SETC_t();12.844 + }12.845 + break;12.846 + case 0x2:12.847 + { /* ROTCL Rn */12.848 + uint32_t Rn = ((ir>>8)&0xF);12.849 + load_reg( R_EAX, Rn );12.850 + LDC_t();12.851 + RCL1_r32( R_EAX );12.852 + store_reg( R_EAX, Rn );12.853 + SETC_t();12.854 + }12.855 + break;12.856 + default:12.857 + UNDEF();12.858 + break;12.859 + }12.860 + break;12.861 + case 0x5:12.862 + switch( (ir&0xF0) >> 4 ) {12.863 + case 0x0:12.864 + { /* ROTR Rn */12.865 + uint32_t Rn = ((ir>>8)&0xF);12.866 + load_reg( R_EAX, Rn );12.867 + ROR1_r32( R_EAX );12.868 + store_reg( R_EAX, Rn );12.869 + SETC_t();12.870 + }12.871 + break;12.872 + case 0x1:12.873 + { /* CMP/PL Rn */12.874 + uint32_t Rn = ((ir>>8)&0xF);12.875 + load_reg( R_EAX, Rn );12.876 + CMP_imm8s_r32( 0, R_EAX );12.877 + SETG_t();12.878 + }12.879 + break;12.880 + case 0x2:12.881 + { /* ROTCR Rn */12.882 + uint32_t Rn = ((ir>>8)&0xF);12.883 + load_reg( R_EAX, Rn );12.884 + LDC_t();12.885 + RCR1_r32( R_EAX );12.886 + store_reg( R_EAX, Rn );12.887 + SETC_t();12.888 + }12.889 + break;12.890 + default:12.891 + UNDEF();12.892 + break;12.893 + }12.894 + break;12.895 + case 0x6:12.896 + switch( (ir&0xF0) >> 4 ) {12.897 + case 0x0:12.898 + { /* LDS.L @Rm+, MACH */12.899 + uint32_t Rm = ((ir>>8)&0xF);12.900 + load_reg( R_EAX, Rm );12.901 + MOV_r32_r32( R_EAX, R_ECX );12.902 + ADD_imm8s_r32( 4, R_EAX );12.903 + store_reg( R_EAX, Rm );12.904 + MEM_READ_LONG( R_ECX, R_EAX );12.905 + store_spreg( R_EAX, R_MACH );12.906 + }12.907 + break;12.908 + case 0x1:12.909 + { /* LDS.L @Rm+, MACL */12.910 + uint32_t Rm = ((ir>>8)&0xF);12.911 + load_reg( R_EAX, Rm );12.912 + MOV_r32_r32( R_EAX, R_ECX );12.913 + ADD_imm8s_r32( 4, R_EAX );12.914 + store_reg( R_EAX, Rm );12.915 + MEM_READ_LONG( R_ECX, R_EAX );12.916 + store_spreg( R_EAX, R_MACL );12.917 + }12.918 + break;12.919 + case 0x2:12.920 + { /* LDS.L @Rm+, PR */12.921 + uint32_t Rm = ((ir>>8)&0xF);12.922 + load_reg( R_EAX, Rm );12.923 + MOV_r32_r32( R_EAX, R_ECX );12.924 + ADD_imm8s_r32( 4, R_EAX );12.925 + store_reg( R_EAX, Rm );12.926 + MEM_READ_LONG( R_ECX, R_EAX );12.927 + store_spreg( R_EAX, R_PR );12.928 + }12.929 + break;12.930 + case 0x3:12.931 + { /* LDC.L @Rm+, SGR */12.932 + uint32_t Rm = ((ir>>8)&0xF);12.933 + load_reg( R_EAX, Rm );12.934 + MOV_r32_r32( R_EAX, R_ECX );12.935 + ADD_imm8s_r32( 4, R_EAX );12.936 + store_reg( R_EAX, Rm );12.937 + MEM_READ_LONG( R_ECX, R_EAX );12.938 + store_spreg( R_EAX, R_SGR );12.939 + }12.940 + break;12.941 + case 0x5:12.942 + { /* LDS.L @Rm+, FPUL */12.943 + uint32_t Rm = ((ir>>8)&0xF);12.944 + load_reg( R_EAX, Rm );12.945 + MOV_r32_r32( R_EAX, R_ECX );12.946 + ADD_imm8s_r32( 4, R_EAX );12.947 + store_reg( R_EAX, Rm );12.948 + MEM_READ_LONG( R_ECX, R_EAX );12.949 + store_spreg( R_EAX, R_FPUL );12.950 + }12.951 + break;12.952 + case 0x6:12.953 + { /* LDS.L @Rm+, FPSCR */12.954 + uint32_t Rm = ((ir>>8)&0xF);12.955 + load_reg( R_EAX, Rm );12.956 + MOV_r32_r32( R_EAX, R_ECX );12.957 + ADD_imm8s_r32( 4, R_EAX );12.958 + store_reg( R_EAX, Rm );12.959 + MEM_READ_LONG( R_ECX, R_EAX );12.960 + store_spreg( R_EAX, R_FPSCR );12.961 + }12.962 + break;12.963 + case 0xF:12.964 + { /* LDC.L @Rm+, DBR */12.965 + uint32_t Rm = ((ir>>8)&0xF);12.966 + load_reg( R_EAX, Rm );12.967 + MOV_r32_r32( R_EAX, R_ECX );12.968 + ADD_imm8s_r32( 4, R_EAX );12.969 + store_reg( R_EAX, Rm );12.970 + MEM_READ_LONG( R_ECX, R_EAX );12.971 + store_spreg( R_EAX, R_DBR );12.972 + }12.973 + break;12.974 + default:12.975 + UNDEF();12.976 + break;12.977 + }12.978 + break;12.979 + case 0x7:12.980 + switch( (ir&0x80) >> 7 ) {12.981 + case 0x0:12.982 + switch( (ir&0x70) >> 4 ) {12.983 + case 0x0:12.984 + { /* LDC.L @Rm+, SR */12.985 + uint32_t Rm = ((ir>>8)&0xF);12.986 + }12.987 + break;12.988 + case 0x1:12.989 + { /* LDC.L @Rm+, GBR */12.990 + uint32_t Rm = ((ir>>8)&0xF);12.991 + load_reg( R_EAX, Rm );12.992 + MOV_r32_r32( R_EAX, R_ECX );12.993 + ADD_imm8s_r32( 4, R_EAX );12.994 + store_reg( R_EAX, Rm );12.995 + MEM_READ_LONG( R_ECX, R_EAX );12.996 + store_spreg( R_EAX, R_GBR );12.997 + }12.998 + break;12.999 + case 0x2:12.1000 + { /* LDC.L @Rm+, VBR */12.1001 + uint32_t Rm = ((ir>>8)&0xF);12.1002 + load_reg( R_EAX, Rm );12.1003 + MOV_r32_r32( R_EAX, R_ECX );12.1004 + ADD_imm8s_r32( 4, R_EAX );12.1005 + store_reg( R_EAX, Rm );12.1006 + MEM_READ_LONG( R_ECX, R_EAX );12.1007 + store_spreg( R_EAX, R_VBR );12.1008 + }12.1009 + break;12.1010 + case 0x3:12.1011 + { /* LDC.L @Rm+, SSR */12.1012 + uint32_t Rm = ((ir>>8)&0xF);12.1013 + load_reg( R_EAX, Rm );12.1014 + MOV_r32_r32( R_EAX, R_ECX );12.1015 + ADD_imm8s_r32( 4, R_EAX );12.1016 + store_reg( R_EAX, Rm );12.1017 + MEM_READ_LONG( R_ECX, R_EAX );12.1018 + store_spreg( R_EAX, R_SSR );12.1019 + }12.1020 + break;12.1021 + case 0x4:12.1022 + { /* LDC.L @Rm+, SPC */12.1023 + uint32_t Rm = ((ir>>8)&0xF);12.1024 + load_reg( R_EAX, Rm );12.1025 + MOV_r32_r32( R_EAX, R_ECX );12.1026 + ADD_imm8s_r32( 4, R_EAX );12.1027 + store_reg( R_EAX, Rm );12.1028 + MEM_READ_LONG( R_ECX, R_EAX );12.1029 + store_spreg( R_EAX, R_SPC );12.1030 + }12.1031 + break;12.1032 + default:12.1033 + UNDEF();12.1034 + break;12.1035 + }12.1036 + break;12.1037 + case 0x1:12.1038 + { /* LDC.L @Rm+, Rn_BANK */12.1039 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);12.1040 + }12.1041 + break;12.1042 + }12.1043 + break;12.1044 + case 0x8:12.1045 + switch( (ir&0xF0) >> 4 ) {12.1046 + case 0x0:12.1047 + { /* SHLL2 Rn */12.1048 + uint32_t Rn = ((ir>>8)&0xF);12.1049 + load_reg( R_EAX, Rn );12.1050 + SHL_imm8_r32( 2, R_EAX );12.1051 + store_reg( R_EAX, Rn );12.1052 + }12.1053 + break;12.1054 + case 0x1:12.1055 + { /* SHLL8 Rn */12.1056 + uint32_t Rn = ((ir>>8)&0xF);12.1057 + load_reg( R_EAX, Rn );12.1058 + SHL_imm8_r32( 8, R_EAX );12.1059 + store_reg( R_EAX, Rn );12.1060 + }12.1061 + break;12.1062 + case 0x2:12.1063 + { /* SHLL16 Rn */12.1064 + uint32_t Rn = ((ir>>8)&0xF);12.1065 + load_reg( R_EAX, Rn );12.1066 + SHL_imm8_r32( 16, R_EAX );12.1067 + store_reg( R_EAX, Rn );12.1068 + }12.1069 + break;12.1070 + default:12.1071 + UNDEF();12.1072 + break;12.1073 + }12.1074 + break;12.1075 + case 0x9:12.1076 + switch( (ir&0xF0) >> 4 ) {12.1077 + case 0x0:12.1078 + { /* SHLR2 Rn */12.1079 + uint32_t Rn = ((ir>>8)&0xF);12.1080 + load_reg( R_EAX, Rn );12.1081 + SHR_imm8_r32( 2, R_EAX );12.1082 + store_reg( R_EAX, Rn );12.1083 + }12.1084 + break;12.1085 + case 0x1:12.1086 + { /* SHLR8 Rn */12.1087 + uint32_t Rn = ((ir>>8)&0xF);12.1088 + load_reg( R_EAX, Rn );12.1089 + SHR_imm8_r32( 8, R_EAX );12.1090 + store_reg( R_EAX, Rn );12.1091 + }12.1092 + break;12.1093 + case 0x2:12.1094 + { /* SHLR16 Rn */12.1095 + uint32_t Rn = ((ir>>8)&0xF);12.1096 + load_reg( R_EAX, Rn );12.1097 + SHR_imm8_r32( 16, R_EAX );12.1098 + store_reg( R_EAX, Rn );12.1099 + }12.1100 + break;12.1101 + default:12.1102 + UNDEF();12.1103 + break;12.1104 + }12.1105 + break;12.1106 + case 0xA:12.1107 + switch( (ir&0xF0) >> 4 ) {12.1108 + case 0x0:12.1109 + { /* LDS Rm, MACH */12.1110 + uint32_t Rm = ((ir>>8)&0xF);12.1111 + load_reg( R_EAX, Rm );12.1112 + store_spreg( R_EAX, R_MACH );12.1113 + }12.1114 + break;12.1115 + case 0x1:12.1116 + { /* LDS Rm, MACL */12.1117 + uint32_t Rm = ((ir>>8)&0xF);12.1118 + load_reg( R_EAX, Rm );12.1119 + store_spreg( R_EAX, R_MACL );12.1120 + }12.1121 + break;12.1122 + case 0x2:12.1123 + { /* LDS Rm, PR */12.1124 + uint32_t Rm = ((ir>>8)&0xF);12.1125 + load_reg( R_EAX, Rm );12.1126 + store_spreg( R_EAX, R_PR );12.1127 + }12.1128 + break;12.1129 + case 0x3:12.1130 + { /* LDC Rm, SGR */12.1131 + uint32_t Rm = ((ir>>8)&0xF);12.1132 + load_reg( R_EAX, Rm );12.1133 + store_spreg( R_EAX, R_SGR );12.1134 + }12.1135 + break;12.1136 + case 0x5:12.1137 + { /* LDS Rm, FPUL */12.1138 + uint32_t Rm = ((ir>>8)&0xF);12.1139 + load_reg( R_EAX, Rm );12.1140 + store_spreg( R_EAX, R_FPUL );12.1141 + }12.1142 + break;12.1143 + case 0x6:12.1144 + { /* LDS Rm, FPSCR */12.1145 + uint32_t Rm = ((ir>>8)&0xF);12.1146 + load_reg( R_EAX, Rm );12.1147 + store_spreg( R_EAX, R_FPSCR );12.1148 + }12.1149 + break;12.1150 + case 0xF:12.1151 + { /* LDC Rm, DBR */12.1152 + uint32_t Rm = ((ir>>8)&0xF);12.1153 + load_reg( R_EAX, Rm );12.1154 + store_spreg( R_EAX, R_DBR );12.1155 + }12.1156 + break;12.1157 + default:12.1158 + UNDEF();12.1159 + break;12.1160 + }12.1161 + break;12.1162 + case 0xB:12.1163 + switch( (ir&0xF0) >> 4 ) {12.1164 + case 0x0:12.1165 + { /* JSR @Rn */12.1166 + uint32_t Rn = ((ir>>8)&0xF);12.1167 + }12.1168 + break;12.1169 + case 0x1:12.1170 + { /* TAS.B @Rn */12.1171 + uint32_t Rn = ((ir>>8)&0xF);12.1172 + }12.1173 + break;12.1174 + case 0x2:12.1175 + { /* JMP @Rn */12.1176 + uint32_t Rn = ((ir>>8)&0xF);12.1177 + }12.1178 + break;12.1179 + default:12.1180 + UNDEF();12.1181 + break;12.1182 + }12.1183 + break;12.1184 + case 0xC:12.1185 + { /* SHAD Rm, Rn */12.1186 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1187 + /* Annoyingly enough, not directly convertible */12.1188 + }12.1189 + break;12.1190 + case 0xD:12.1191 + { /* SHLD Rm, Rn */12.1192 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1193 + }12.1194 + break;12.1195 + case 0xE:12.1196 + switch( (ir&0x80) >> 7 ) {12.1197 + case 0x0:12.1198 + switch( (ir&0x70) >> 4 ) {12.1199 + case 0x0:12.1200 + { /* LDC Rm, SR */12.1201 + uint32_t Rm = ((ir>>8)&0xF);12.1202 + /* We need to be a little careful about SR */12.1203 + }12.1204 + break;12.1205 + case 0x1:12.1206 + { /* LDC Rm, GBR */12.1207 + uint32_t Rm = ((ir>>8)&0xF);12.1208 + load_reg( R_EAX, Rm );12.1209 + store_spreg( R_EAX, R_GBR );12.1210 + }12.1211 + break;12.1212 + case 0x2:12.1213 + { /* LDC Rm, VBR */12.1214 + uint32_t Rm = ((ir>>8)&0xF);12.1215 + load_reg( R_EAX, Rm );12.1216 + store_spreg( R_EAX, R_VBR );12.1217 + }12.1218 + break;12.1219 + case 0x3:12.1220 + { /* LDC Rm, SSR */12.1221 + uint32_t Rm = ((ir>>8)&0xF);12.1222 + load_reg( R_EAX, Rm );12.1223 + store_spreg( R_EAX, R_SSR );12.1224 + }12.1225 + break;12.1226 + case 0x4:12.1227 + { /* LDC Rm, SPC */12.1228 + uint32_t Rm = ((ir>>8)&0xF);12.1229 + load_reg( R_EAX, Rm );12.1230 + store_spreg( R_EAX, R_SPC );12.1231 + }12.1232 + break;12.1233 + default:12.1234 + UNDEF();12.1235 + break;12.1236 + }12.1237 + break;12.1238 + case 0x1:12.1239 + { /* LDC Rm, Rn_BANK */12.1240 + uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);12.1241 + }12.1242 + break;12.1243 + }12.1244 + break;12.1245 + case 0xF:12.1246 + { /* MAC.W @Rm+, @Rn+ */12.1247 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1248 + }12.1249 + break;12.1250 + }12.1251 + break;12.1252 + case 0x5:12.1253 + { /* MOV.L @(disp, Rm), Rn */12.1254 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;12.1255 + }12.1256 + break;12.1257 + case 0x6:12.1258 + switch( ir&0xF ) {12.1259 + case 0x0:12.1260 + { /* MOV.B @Rm, Rn */12.1261 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1262 + load_reg( R_ECX, Rm );12.1263 + MEM_READ_BYTE( R_ECX, R_EAX );12.1264 + store_reg( R_ECX, Rn );12.1265 + }12.1266 + break;12.1267 + case 0x1:12.1268 + { /* MOV.W @Rm, Rn */12.1269 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1270 + }12.1271 + break;12.1272 + case 0x2:12.1273 + { /* MOV.L @Rm, Rn */12.1274 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1275 + }12.1276 + break;12.1277 + case 0x3:12.1278 + { /* MOV Rm, Rn */12.1279 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1280 + load_reg( R_EAX, Rm );12.1281 + store_reg( R_EAX, Rn );12.1282 + }12.1283 + break;12.1284 + case 0x4:12.1285 + { /* MOV.B @Rm+, Rn */12.1286 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1287 + load_reg( R_ECX, Rm );12.1288 + MOV_r32_r32( R_ECX, R_EAX );12.1289 + ADD_imm8s_r32( 1, R_EAX );12.1290 + store_reg( R_EAX, Rm );12.1291 + MEM_READ_BYTE( R_ECX, R_EAX );12.1292 + store_reg( R_EAX, Rn );12.1293 + }12.1294 + break;12.1295 + case 0x5:12.1296 + { /* MOV.W @Rm+, Rn */12.1297 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1298 + }12.1299 + break;12.1300 + case 0x6:12.1301 + { /* MOV.L @Rm+, Rn */12.1302 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1303 + }12.1304 + break;12.1305 + case 0x7:12.1306 + { /* NOT Rm, Rn */12.1307 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1308 + load_reg( R_EAX, Rm );12.1309 + NOT_r32( R_EAX );12.1310 + store_reg( R_EAX, Rn );12.1311 + }12.1312 + break;12.1313 + case 0x8:12.1314 + { /* SWAP.B Rm, Rn */12.1315 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1316 + load_reg( R_EAX, Rm );12.1317 + XCHG_r8_r8( R_AL, R_AH );12.1318 + store_reg( R_EAX, Rn );12.1319 + }12.1320 + break;12.1321 + case 0x9:12.1322 + { /* SWAP.W Rm, Rn */12.1323 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1324 + load_reg( R_EAX, Rm );12.1325 + MOV_r32_r32( R_EAX, R_ECX );12.1326 + SHL_imm8_r32( 16, R_ECX );12.1327 + SHR_imm8_r32( 16, R_EAX );12.1328 + OR_r32_r32( R_EAX, R_ECX );12.1329 + store_reg( R_ECX, Rn );12.1330 + }12.1331 + break;12.1332 + case 0xA:12.1333 + { /* NEGC Rm, Rn */12.1334 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1335 + load_reg( R_EAX, Rm );12.1336 + XOR_r32_r32( R_ECX, R_ECX );12.1337 + LDC_t();12.1338 + SBB_r32_r32( R_EAX, R_ECX );12.1339 + store_reg( R_ECX, Rn );12.1340 + SETC_t();12.1341 + }12.1342 + break;12.1343 + case 0xB:12.1344 + { /* NEG Rm, Rn */12.1345 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1346 + load_reg( R_EAX, Rm );12.1347 + NEG_r32( R_EAX );12.1348 + store_reg( R_EAX, Rn );12.1349 + }12.1350 + break;12.1351 + case 0xC:12.1352 + { /* EXTU.B Rm, Rn */12.1353 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1354 + }12.1355 + break;12.1356 + case 0xD:12.1357 + { /* EXTU.W Rm, Rn */12.1358 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1359 + }12.1360 + break;12.1361 + case 0xE:12.1362 + { /* EXTS.B Rm, Rn */12.1363 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1364 + load_reg( R_EAX, Rm );12.1365 + MOVSX_r8_r32( R_EAX, R_EAX );12.1366 + store_reg( R_EAX, Rn );12.1367 + }12.1368 + break;12.1369 + case 0xF:12.1370 + { /* EXTS.W Rm, Rn */12.1371 + uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1372 + }12.1373 + break;12.1374 + }12.1375 + break;12.1376 + case 0x7:12.1377 + { /* ADD #imm, Rn */12.1378 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);12.1379 + load_reg( R_EAX, Rn );12.1380 + ADD_imm8s_r32( imm, R_EAX );12.1381 + store_reg( R_EAX, Rn );12.1382 + }12.1383 + break;12.1384 + case 0x8:12.1385 + switch( (ir&0xF00) >> 8 ) {12.1386 + case 0x0:12.1387 + { /* MOV.B R0, @(disp, Rn) */12.1388 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);12.1389 + load_reg( R_EAX, 0 );12.1390 + load_reg( R_ECX, Rn );12.1391 + ADD_imm32_r32( disp, R_ECX );12.1392 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.1393 + }12.1394 + break;12.1395 + case 0x1:12.1396 + { /* MOV.W R0, @(disp, Rn) */12.1397 + uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;12.1398 + }12.1399 + break;12.1400 + case 0x4:12.1401 + { /* MOV.B @(disp, Rm), R0 */12.1402 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);12.1403 + load_reg( R_ECX, Rm );12.1404 + ADD_imm32_r32( disp, R_ECX );12.1405 + MEM_READ_BYTE( R_ECX, R_EAX );12.1406 + store_reg( R_EAX, 0 );12.1407 + }12.1408 + break;12.1409 + case 0x5:12.1410 + { /* MOV.W @(disp, Rm), R0 */12.1411 + uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;12.1412 + }12.1413 + break;12.1414 + case 0x8:12.1415 + { /* CMP/EQ #imm, R0 */12.1416 + int32_t imm = SIGNEXT8(ir&0xFF);12.1417 + load_reg( R_EAX, 0 );12.1418 + CMP_imm8s_r32(imm, R_EAX);12.1419 + SETE_t();12.1420 + }12.1421 + break;12.1422 + case 0x9:12.1423 + { /* BT disp */12.1424 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;12.1425 + /* If true, result PC += 4 + disp. else result PC = pc+2 */12.1426 + return pc + 2;12.1427 + }12.1428 + break;12.1429 + case 0xB:12.1430 + { /* BF disp */12.1431 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;12.1432 + }12.1433 + break;12.1434 + case 0xD:12.1435 + { /* BT/S disp */12.1436 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;12.1437 + return pc + 4;12.1438 + }12.1439 + break;12.1440 + case 0xF:12.1441 + { /* BF/S disp */12.1442 + int32_t disp = SIGNEXT8(ir&0xFF)<<1;12.1443 + }12.1444 + break;12.1445 + default:12.1446 + UNDEF();12.1447 + break;12.1448 + }12.1449 + break;12.1450 + case 0x9:12.1451 + { /* MOV.W @(disp, PC), Rn */12.1452 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;12.1453 + }12.1454 + break;12.1455 + case 0xA:12.1456 + { /* BRA disp */12.1457 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;12.1458 + }12.1459 + break;12.1460 + case 0xB:12.1461 + { /* BSR disp */12.1462 + int32_t disp = SIGNEXT12(ir&0xFFF)<<1;12.1463 + }12.1464 + break;12.1465 + case 0xC:12.1466 + switch( (ir&0xF00) >> 8 ) {12.1467 + case 0x0:12.1468 + { /* MOV.B R0, @(disp, GBR) */12.1469 + uint32_t disp = (ir&0xFF);12.1470 + load_reg( R_EAX, 0 );12.1471 + load_spreg( R_ECX, R_GBR );12.1472 + ADD_imm32_r32( disp, R_ECX );12.1473 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.1474 + }12.1475 + break;12.1476 + case 0x1:12.1477 + { /* MOV.W R0, @(disp, GBR) */12.1478 + uint32_t disp = (ir&0xFF)<<1;12.1479 + }12.1480 + break;12.1481 + case 0x2:12.1482 + { /* MOV.L R0, @(disp, GBR) */12.1483 + uint32_t disp = (ir&0xFF)<<2;12.1484 + }12.1485 + break;12.1486 + case 0x3:12.1487 + { /* TRAPA #imm */12.1488 + uint32_t imm = (ir&0xFF);12.1489 + }12.1490 + break;12.1491 + case 0x4:12.1492 + { /* MOV.B @(disp, GBR), R0 */12.1493 + uint32_t disp = (ir&0xFF);12.1494 + load_spreg( R_ECX, R_GBR );12.1495 + ADD_imm32_r32( disp, R_ECX );12.1496 + MEM_READ_BYTE( R_ECX, R_EAX );12.1497 + store_reg( R_EAX, 0 );12.1498 + }12.1499 + break;12.1500 + case 0x5:12.1501 + { /* MOV.W @(disp, GBR), R0 */12.1502 + uint32_t disp = (ir&0xFF)<<1;12.1503 + }12.1504 + break;12.1505 + case 0x6:12.1506 + { /* MOV.L @(disp, GBR), R0 */12.1507 + uint32_t disp = (ir&0xFF)<<2;12.1508 + }12.1509 + break;12.1510 + case 0x7:12.1511 + { /* MOVA @(disp, PC), R0 */12.1512 + uint32_t disp = (ir&0xFF)<<2;12.1513 + }12.1514 + break;12.1515 + case 0x8:12.1516 + { /* TST #imm, R0 */12.1517 + uint32_t imm = (ir&0xFF);12.1518 + }12.1519 + break;12.1520 + case 0x9:12.1521 + { /* AND #imm, R0 */12.1522 + uint32_t imm = (ir&0xFF);12.1523 + // Note: x86 AND imm8 sign-extends, SH4 version zero-extends. So12.1524 + // need to use the imm32 version12.1525 + load_reg( R_EAX, 0 );12.1526 + AND_imm32_r32(imm, R_EAX);12.1527 + store_reg( R_EAX, 0 );12.1528 + }12.1529 + break;12.1530 + case 0xA:12.1531 + { /* XOR #imm, R0 */12.1532 + uint32_t imm = (ir&0xFF);12.1533 + load_reg( R_EAX, 0 );12.1534 + XOR_imm32_r32( imm, R_EAX );12.1535 + store_reg( R_EAX, 0 );12.1536 + }12.1537 + break;12.1538 + case 0xB:12.1539 + { /* OR #imm, R0 */12.1540 + uint32_t imm = (ir&0xFF);12.1541 + load_reg( R_EAX, 0 );12.1542 + OR_imm32_r32(imm, R_EAX);12.1543 + store_reg( R_EAX, 0 );12.1544 + }12.1545 + break;12.1546 + case 0xC:12.1547 + { /* TST.B #imm, @(R0, GBR) */12.1548 + uint32_t imm = (ir&0xFF);12.1549 + }12.1550 + break;12.1551 + case 0xD:12.1552 + { /* AND.B #imm, @(R0, GBR) */12.1553 + uint32_t imm = (ir&0xFF);12.1554 + load_reg( R_EAX, 0 );12.1555 + load_spreg( R_ECX, R_GBR );12.1556 + ADD_r32_r32( R_EAX, R_EBX );12.1557 + MEM_READ_BYTE( R_ECX, R_EAX );12.1558 + AND_imm32_r32(imm, R_ECX );12.1559 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.1560 + }12.1561 + break;12.1562 + case 0xE:12.1563 + { /* XOR.B #imm, @(R0, GBR) */12.1564 + uint32_t imm = (ir&0xFF);12.1565 + load_reg( R_EAX, 0 );12.1566 + load_spreg( R_ECX, R_GBR );12.1567 + ADD_r32_r32( R_EAX, R_ECX );12.1568 + MEM_READ_BYTE( R_ECX, R_EAX );12.1569 + XOR_imm32_r32( imm, R_EAX );12.1570 + MEM_WRITE_BYTE( R_ECX, R_EAX );12.1571 + }12.1572 + break;12.1573 + case 0xF:12.1574 + { /* OR.B #imm, @(R0, GBR) */12.1575 + uint32_t imm = (ir&0xFF);12.1576 + }12.1577 + break;12.1578 + }12.1579 + break;12.1580 + case 0xD:12.1581 + { /* MOV.L @(disp, PC), Rn */12.1582 + uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;12.1583 + }12.1584 + break;12.1585 + case 0xE:12.1586 + { /* MOV #imm, Rn */12.1587 + uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);12.1588 + load_imm32( R_EAX, imm );12.1589 + store_reg( R_EAX, Rn );12.1590 + }12.1591 + break;12.1592 + case 0xF:12.1593 + switch( ir&0xF ) {12.1594 + case 0x0:12.1595 + { /* FADD FRm, FRn */12.1596 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1597 + }12.1598 + break;12.1599 + case 0x1:12.1600 + { /* FSUB FRm, FRn */12.1601 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1602 + }12.1603 + break;12.1604 + case 0x2:12.1605 + { /* FMUL FRm, FRn */12.1606 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1607 + }12.1608 + break;12.1609 + case 0x3:12.1610 + { /* FDIV FRm, FRn */12.1611 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1612 + }12.1613 + break;12.1614 + case 0x4:12.1615 + { /* FCMP/EQ FRm, FRn */12.1616 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1617 + }12.1618 + break;12.1619 + case 0x5:12.1620 + { /* FCMP/GT FRm, FRn */12.1621 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1622 + }12.1623 + break;12.1624 + case 0x6:12.1625 + { /* FMOV @(R0, Rm), FRn */12.1626 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1627 + }12.1628 + break;12.1629 + case 0x7:12.1630 + { /* FMOV FRm, @(R0, Rn) */12.1631 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1632 + }12.1633 + break;12.1634 + case 0x8:12.1635 + { /* FMOV @Rm, FRn */12.1636 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1637 + }12.1638 + break;12.1639 + case 0x9:12.1640 + { /* FMOV @Rm+, FRn */12.1641 + uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);12.1642 + }12.1643 + break;12.1644 + case 0xA:12.1645 + { /* FMOV FRm, @Rn */12.1646 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1647 + }12.1648 + break;12.1649 + case 0xB:12.1650 + { /* FMOV FRm, @-Rn */12.1651 + uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1652 + }12.1653 + break;12.1654 + case 0xC:12.1655 + { /* FMOV FRm, FRn */12.1656 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1657 + }12.1658 + break;12.1659 + case 0xD:12.1660 + switch( (ir&0xF0) >> 4 ) {12.1661 + case 0x0:12.1662 + { /* FSTS FPUL, FRn */12.1663 + uint32_t FRn = ((ir>>8)&0xF);12.1664 + }12.1665 + break;12.1666 + case 0x1:12.1667 + { /* FLDS FRm, FPUL */12.1668 + uint32_t FRm = ((ir>>8)&0xF);12.1669 + }12.1670 + break;12.1671 + case 0x2:12.1672 + { /* FLOAT FPUL, FRn */12.1673 + uint32_t FRn = ((ir>>8)&0xF);12.1674 + }12.1675 + break;12.1676 + case 0x3:12.1677 + { /* FTRC FRm, FPUL */12.1678 + uint32_t FRm = ((ir>>8)&0xF);12.1679 + }12.1680 + break;12.1681 + case 0x4:12.1682 + { /* FNEG FRn */12.1683 + uint32_t FRn = ((ir>>8)&0xF);12.1684 + }12.1685 + break;12.1686 + case 0x5:12.1687 + { /* FABS FRn */12.1688 + uint32_t FRn = ((ir>>8)&0xF);12.1689 + }12.1690 + break;12.1691 + case 0x6:12.1692 + { /* FSQRT FRn */12.1693 + uint32_t FRn = ((ir>>8)&0xF);12.1694 + }12.1695 + break;12.1696 + case 0x7:12.1697 + { /* FSRRA FRn */12.1698 + uint32_t FRn = ((ir>>8)&0xF);12.1699 + }12.1700 + break;12.1701 + case 0x8:12.1702 + { /* FLDI0 FRn */12.1703 + uint32_t FRn = ((ir>>8)&0xF);12.1704 + }12.1705 + break;12.1706 + case 0x9:12.1707 + { /* FLDI1 FRn */12.1708 + uint32_t FRn = ((ir>>8)&0xF);12.1709 + }12.1710 + break;12.1711 + case 0xA:12.1712 + { /* FCNVSD FPUL, FRn */12.1713 + uint32_t FRn = ((ir>>8)&0xF);12.1714 + }12.1715 + break;12.1716 + case 0xB:12.1717 + { /* FCNVDS FRm, FPUL */12.1718 + uint32_t FRm = ((ir>>8)&0xF);12.1719 + }12.1720 + break;12.1721 + case 0xE:12.1722 + { /* FIPR FVm, FVn */12.1723 + uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);12.1724 + }12.1725 + break;12.1726 + case 0xF:12.1727 + switch( (ir&0x100) >> 8 ) {12.1728 + case 0x0:12.1729 + { /* FSCA FPUL, FRn */12.1730 + uint32_t FRn = ((ir>>9)&0x7)<<1;12.1731 + }12.1732 + break;12.1733 + case 0x1:12.1734 + switch( (ir&0x200) >> 9 ) {12.1735 + case 0x0:12.1736 + { /* FTRV XMTRX, FVn */12.1737 + uint32_t FVn = ((ir>>10)&0x3);12.1738 + }12.1739 + break;12.1740 + case 0x1:12.1741 + switch( (ir&0xC00) >> 10 ) {12.1742 + case 0x0:12.1743 + { /* FSCHG */12.1744 + }12.1745 + break;12.1746 + case 0x2:12.1747 + { /* FRCHG */12.1748 + }12.1749 + break;12.1750 + case 0x3:12.1751 + { /* UNDEF */12.1752 + }12.1753 + break;12.1754 + default:12.1755 + UNDEF();12.1756 + break;12.1757 + }12.1758 + break;12.1759 + }12.1760 + break;12.1761 + }12.1762 + break;12.1763 + default:12.1764 + UNDEF();12.1765 + break;12.1766 + }12.1767 + break;12.1768 + case 0xE:12.1769 + { /* FMAC FR0, FRm, FRn */12.1770 + uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);12.1771 + }12.1772 + break;12.1773 + default:12.1774 + UNDEF();12.1775 + break;12.1776 + }12.1777 + break;12.1778 + }12.1779 +12.1780 +12.1781 + return 0;12.1782 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000013.2 +++ b/src/sh4/sh4x86.in Thu Aug 23 12:33:27 2007 +000013.3 @@ -0,0 +1,843 @@13.4 +/**13.5 + * $Id: sh4x86.in,v 1.1 2007-08-23 12:33:27 nkeynes Exp $13.6 + *13.7 + * SH4 => x86 translation. This version does no real optimization, it just13.8 + * outputs straight-line x86 code - it mainly exists to provide a baseline13.9 + * to test the optimizing versions against.13.10 + *13.11 + * Copyright (c) 2007 Nathan Keynes.13.12 + *13.13 + * This program is free software; you can redistribute it and/or modify13.14 + * it under the terms of the GNU General Public License as published by13.15 + * the Free Software Foundation; either version 2 of the License, or13.16 + * (at your option) any later version.13.17 + *13.18 + * This program is distributed in the hope that it will be useful,13.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of13.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13.21 + * GNU General Public License for more details.13.22 + */13.23 +13.24 +#include "sh4core.h"13.25 +#include "sh4trans.h"13.26 +#include "x86op.h"13.27 +13.28 +/**13.29 + * Emit an instruction to load an SH4 reg into a real register13.30 + */13.31 +static inline void load_reg( int x86reg, int sh4reg )13.32 +{13.33 + /* mov [bp+n], reg */13.34 + OP(0x89);13.35 + OP(0x45 + x86reg<<3);13.36 + OP(REG_OFFSET(r[sh4reg]));13.37 +}13.38 +13.39 +static inline void load_spreg( int x86reg, int regoffset )13.40 +{13.41 + /* mov [bp+n], reg */13.42 + OP(0x89);13.43 + OP(0x45 + x86reg<<3);13.44 + OP(regoffset);13.45 +}13.46 +13.47 +#define UNDEF()13.48 +#define MEM_READ_BYTE( addr_reg, value_reg )13.49 +#define MEM_READ_WORD( addr_reg, value_reg )13.50 +#define MEM_READ_LONG( addr_reg, value_reg )13.51 +#define MEM_WRITE_BYTE( addr_reg, value_reg )13.52 +#define MEM_WRITE_WORD( addr_reg, value_reg )13.53 +#define MEM_WRITE_LONG( addr_reg, value_reg )13.54 +13.55 +/**13.56 + * Emit an instruction to load an immediate value into a register13.57 + */13.58 +static inline void load_imm32( int x86reg, uint32_t value ) {13.59 + /* mov #value, reg */13.60 + OP(0xB8 + x86reg);13.61 + OP32(value);13.62 +}13.63 +13.64 +/**13.65 + * Emit an instruction to store an SH4 reg (RN)13.66 + */13.67 +void static inline store_reg( int x86reg, int sh4reg ) {13.68 + /* mov reg, [bp+n] */13.69 + OP(0x8B);13.70 + OP(0x45 + x86reg<<3);13.71 + OP(REG_OFFSET(r[sh4reg]));13.72 +}13.73 +void static inline store_spreg( int x86reg, int regoffset ) {13.74 + /* mov reg, [bp+n] */13.75 + OP(0x8B);13.76 + OP(0x45 + x86reg<<3);13.77 + OP(regoffset);13.78 +}13.79 +13.80 +13.81 +/**13.82 + * Emit the 'start of block' assembly. Sets up the stack frame and save13.83 + * SI/DI as required13.84 + */13.85 +void sh4_translate_begin_block() {13.86 + /* push ebp */13.87 + *xlat_output++ = 0x50 + R_EBP;13.88 +13.89 + /* mov &sh4r, ebp */13.90 + load_imm32( R_EBP, (uint32_t)&sh4r );13.91 +13.92 + /* load carry from SR */13.93 +}13.94 +13.95 +/**13.96 + * Flush any open regs back to memory, restore SI/DI/, update PC, etc13.97 + */13.98 +void sh4_translate_end_block( sh4addr_t pc ) {13.99 + /* pop ebp */13.100 + *xlat_output++ = 0x58 + R_EBP;13.101 +13.102 + /* ret */13.103 + *xlat_output++ = 0xC3;13.104 +}13.105 +13.106 +/**13.107 + * Translate a single instruction. Delayed branches are handled specially13.108 + * by translating both branch and delayed instruction as a single unit (as13.109 + *13.110 + *13.111 + * @return true if the instruction marks the end of a basic block13.112 + * (eg a branch or13.113 + */13.114 +uint32_t sh4_x86_translate_instruction( uint32_t pc )13.115 +{13.116 + uint16_t ir = 0;13.117 +13.118 +%%13.119 +/* ALU operations */13.120 +ADD Rm, Rn {:13.121 + load_reg( R_EAX, Rm );13.122 + load_reg( R_ECX, Rn );13.123 + ADD_r32_r32( R_EAX, R_ECX );13.124 + store_reg( R_ECX, Rn );13.125 +:}13.126 +ADD #imm, Rn {:13.127 + load_reg( R_EAX, Rn );13.128 + ADD_imm8s_r32( imm, R_EAX );13.129 + store_reg( R_EAX, Rn );13.130 +:}13.131 +ADDC Rm, Rn {:13.132 + load_reg( R_EAX, Rm );13.133 + load_reg( R_ECX, Rn );13.134 + LDC_t();13.135 + ADC_r32_r32( R_EAX, R_ECX );13.136 + store_reg( R_ECX, Rn );13.137 + SETC_t();13.138 +:}13.139 +ADDV Rm, Rn {:13.140 + load_reg( R_EAX, Rm );13.141 + load_reg( R_ECX, Rn );13.142 + ADD_r32_r32( R_EAX, R_ECX );13.143 + store_reg( R_ECX, Rn );13.144 + SETO_t();13.145 +:}13.146 +AND Rm, Rn {:13.147 + load_reg( R_EAX, Rm );13.148 + load_reg( R_ECX, Rn );13.149 + AND_r32_r32( R_EAX, R_ECX );13.150 + store_reg( R_ECX, Rn );13.151 +:}13.152 +AND #imm, R0 {:13.153 + // Note: x86 AND imm8 sign-extends, SH4 version zero-extends. So13.154 + // need to use the imm32 version13.155 + load_reg( R_EAX, 0 );13.156 + AND_imm32_r32(imm, R_EAX);13.157 + store_reg( R_EAX, 0 );13.158 +:}13.159 +AND.B #imm, @(R0, GBR) {:13.160 + load_reg( R_EAX, 0 );13.161 + load_spreg( R_ECX, R_GBR );13.162 + ADD_r32_r32( R_EAX, R_EBX );13.163 + MEM_READ_BYTE( R_ECX, R_EAX );13.164 + AND_imm32_r32(imm, R_ECX );13.165 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.166 +:}13.167 +CMP/EQ Rm, Rn {:13.168 + load_reg( R_EAX, Rm );13.169 + load_reg( R_ECX, Rn );13.170 + CMP_r32_r32( R_EAX, R_ECX );13.171 + SETE_t();13.172 +:}13.173 +CMP/EQ #imm, R0 {:13.174 + load_reg( R_EAX, 0 );13.175 + CMP_imm8s_r32(imm, R_EAX);13.176 + SETE_t();13.177 +:}13.178 +CMP/GE Rm, Rn {:13.179 + load_reg( R_EAX, Rm );13.180 + load_reg( R_ECX, Rn );13.181 + CMP_r32_r32( R_EAX, R_ECX );13.182 + SETGE_t();13.183 +:}13.184 +CMP/GT Rm, Rn {:13.185 + load_reg( R_EAX, Rm );13.186 + load_reg( R_ECX, Rn );13.187 + CMP_r32_r32( R_EAX, R_ECX );13.188 + SETG_t();13.189 +:}13.190 +CMP/HI Rm, Rn {:13.191 + load_reg( R_EAX, Rm );13.192 + load_reg( R_ECX, Rn );13.193 + CMP_r32_r32( R_EAX, R_ECX );13.194 + SETA_t();13.195 +:}13.196 +CMP/HS Rm, Rn {:13.197 + load_reg( R_EAX, Rm );13.198 + load_reg( R_ECX, Rn );13.199 + CMP_r32_r32( R_EAX, R_ECX );13.200 + SETAE_t();13.201 + :}13.202 +CMP/PL Rn {:13.203 + load_reg( R_EAX, Rn );13.204 + CMP_imm8s_r32( 0, R_EAX );13.205 + SETG_t();13.206 +:}13.207 +CMP/PZ Rn {:13.208 + load_reg( R_EAX, Rn );13.209 + CMP_imm8s_r32( 0, R_EAX );13.210 + SETGE_t();13.211 +:}13.212 +CMP/STR Rm, Rn {: :}13.213 +DIV0S Rm, Rn {: :}13.214 +DIV0U {: :}13.215 +DIV1 Rm, Rn {: :}13.216 +DMULS.L Rm, Rn {: :}13.217 +DMULU.L Rm, Rn {: :}13.218 +DT Rn {:13.219 + load_reg( R_EAX, Rn );13.220 + ADD_imm8s_r32( -1, Rn );13.221 + store_reg( R_EAX, Rn );13.222 + SETE_t();13.223 +:}13.224 +EXTS.B Rm, Rn {:13.225 + load_reg( R_EAX, Rm );13.226 + MOVSX_r8_r32( R_EAX, R_EAX );13.227 + store_reg( R_EAX, Rn );13.228 +:}13.229 +EXTS.W Rm, Rn {: :}13.230 +EXTU.B Rm, Rn {: :}13.231 +EXTU.W Rm, Rn {: :}13.232 +MAC.L @Rm+, @Rn+ {: :}13.233 +MAC.W @Rm+, @Rn+ {: :}13.234 +MOVT Rn {:13.235 + load_spreg( R_EAX, R_T );13.236 + store_reg( R_EAX, Rn );13.237 +:}13.238 +MUL.L Rm, Rn {: :}13.239 +MULS.W Rm, Rn {: :}13.240 +MULU.W Rm, Rn {: :}13.241 +NEG Rm, Rn {:13.242 + load_reg( R_EAX, Rm );13.243 + NEG_r32( R_EAX );13.244 + store_reg( R_EAX, Rn );13.245 +:}13.246 +NEGC Rm, Rn {:13.247 + load_reg( R_EAX, Rm );13.248 + XOR_r32_r32( R_ECX, R_ECX );13.249 + LDC_t();13.250 + SBB_r32_r32( R_EAX, R_ECX );13.251 + store_reg( R_ECX, Rn );13.252 + SETC_t();13.253 +:}13.254 +NOT Rm, Rn {:13.255 + load_reg( R_EAX, Rm );13.256 + NOT_r32( R_EAX );13.257 + store_reg( R_EAX, Rn );13.258 +:}13.259 +OR Rm, Rn {:13.260 + load_reg( R_EAX, Rm );13.261 + load_reg( R_ECX, Rn );13.262 + OR_r32_r32( R_EAX, R_ECX );13.263 + store_reg( R_ECX, Rn );13.264 +:}13.265 +OR #imm, R0 {:13.266 + load_reg( R_EAX, 0 );13.267 + OR_imm32_r32(imm, R_EAX);13.268 + store_reg( R_EAX, 0 );13.269 +:}13.270 +OR.B #imm, @(R0, GBR) {: :}13.271 +ROTCL Rn {:13.272 + load_reg( R_EAX, Rn );13.273 + LDC_t();13.274 + RCL1_r32( R_EAX );13.275 + store_reg( R_EAX, Rn );13.276 + SETC_t();13.277 +:}13.278 +ROTCR Rn {:13.279 + load_reg( R_EAX, Rn );13.280 + LDC_t();13.281 + RCR1_r32( R_EAX );13.282 + store_reg( R_EAX, Rn );13.283 + SETC_t();13.284 +:}13.285 +ROTL Rn {:13.286 + load_reg( R_EAX, Rn );13.287 + ROL1_r32( R_EAX );13.288 + store_reg( R_EAX, Rn );13.289 + SETC_t();13.290 +:}13.291 +ROTR Rn {:13.292 + load_reg( R_EAX, Rn );13.293 + ROR1_r32( R_EAX );13.294 + store_reg( R_EAX, Rn );13.295 + SETC_t();13.296 +:}13.297 +SHAD Rm, Rn {:13.298 + /* Annoyingly enough, not directly convertible */13.299 +:}13.300 +SHLD Rm, Rn {:13.301 +:}13.302 +SHAL Rn {:13.303 + load_reg( R_EAX, Rn );13.304 + SHL1_r32( R_EAX );13.305 + store_reg( R_EAX, Rn );13.306 +:}13.307 +SHAR Rn {:13.308 + load_reg( R_EAX, Rn );13.309 + SAR1_r32( R_EAX );13.310 + store_reg( R_EAX, Rn );13.311 +:}13.312 +SHLL Rn {:13.313 + load_reg( R_EAX, Rn );13.314 + SHL1_r32( R_EAX );13.315 + store_reg( R_EAX, Rn );13.316 +:}13.317 +SHLL2 Rn {:13.318 + load_reg( R_EAX, Rn );13.319 + SHL_imm8_r32( 2, R_EAX );13.320 + store_reg( R_EAX, Rn );13.321 +:}13.322 +SHLL8 Rn {:13.323 + load_reg( R_EAX, Rn );13.324 + SHL_imm8_r32( 8, R_EAX );13.325 + store_reg( R_EAX, Rn );13.326 +:}13.327 +SHLL16 Rn {:13.328 + load_reg( R_EAX, Rn );13.329 + SHL_imm8_r32( 16, R_EAX );13.330 + store_reg( R_EAX, Rn );13.331 +:}13.332 +SHLR Rn {:13.333 + load_reg( R_EAX, Rn );13.334 + SHR1_r32( R_EAX );13.335 + store_reg( R_EAX, Rn );13.336 +:}13.337 +SHLR2 Rn {:13.338 + load_reg( R_EAX, Rn );13.339 + SHR_imm8_r32( 2, R_EAX );13.340 + store_reg( R_EAX, Rn );13.341 +:}13.342 +SHLR8 Rn {:13.343 + load_reg( R_EAX, Rn );13.344 + SHR_imm8_r32( 8, R_EAX );13.345 + store_reg( R_EAX, Rn );13.346 +:}13.347 +SHLR16 Rn {:13.348 + load_reg( R_EAX, Rn );13.349 + SHR_imm8_r32( 16, R_EAX );13.350 + store_reg( R_EAX, Rn );13.351 +:}13.352 +SUB Rm, Rn {:13.353 + load_reg( R_EAX, Rm );13.354 + load_reg( R_ECX, Rn );13.355 + SUB_r32_r32( R_EAX, R_ECX );13.356 + store_reg( R_ECX, Rn );13.357 +:}13.358 +SUBC Rm, Rn {:13.359 + load_reg( R_EAX, Rm );13.360 + load_reg( R_ECX, Rn );13.361 + LDC_t();13.362 + SBB_r32_r32( R_EAX, R_ECX );13.363 + store_reg( R_ECX, Rn );13.364 +:}13.365 +SUBV Rm, Rn {:13.366 + load_reg( R_EAX, Rm );13.367 + load_reg( R_ECX, Rn );13.368 + SUB_r32_r32( R_EAX, R_ECX );13.369 + store_reg( R_ECX, Rn );13.370 + SETO_t();13.371 +:}13.372 +SWAP.B Rm, Rn {:13.373 + load_reg( R_EAX, Rm );13.374 + XCHG_r8_r8( R_AL, R_AH );13.375 + store_reg( R_EAX, Rn );13.376 +:}13.377 +SWAP.W Rm, Rn {:13.378 + load_reg( R_EAX, Rm );13.379 + MOV_r32_r32( R_EAX, R_ECX );13.380 + SHL_imm8_r32( 16, R_ECX );13.381 + SHR_imm8_r32( 16, R_EAX );13.382 + OR_r32_r32( R_EAX, R_ECX );13.383 + store_reg( R_ECX, Rn );13.384 +:}13.385 +TAS.B @Rn {: :}13.386 +TST Rm, Rn {: :}13.387 +TST #imm, R0 {: :}13.388 +TST.B #imm, @(R0, GBR) {: :}13.389 +XOR Rm, Rn {:13.390 + load_reg( R_EAX, Rm );13.391 + load_reg( R_ECX, Rn );13.392 + XOR_r32_r32( R_EAX, R_ECX );13.393 + store_reg( R_ECX, Rn );13.394 +:}13.395 +XOR #imm, R0 {:13.396 + load_reg( R_EAX, 0 );13.397 + XOR_imm32_r32( imm, R_EAX );13.398 + store_reg( R_EAX, 0 );13.399 +:}13.400 +XOR.B #imm, @(R0, GBR) {:13.401 + load_reg( R_EAX, 0 );13.402 + load_spreg( R_ECX, R_GBR );13.403 + ADD_r32_r32( R_EAX, R_ECX );13.404 + MEM_READ_BYTE( R_ECX, R_EAX );13.405 + XOR_imm32_r32( imm, R_EAX );13.406 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.407 +:}13.408 +XTRCT Rm, Rn {:13.409 +:}13.410 +13.411 +/* Data move instructions */13.412 +MOV Rm, Rn {:13.413 + load_reg( R_EAX, Rm );13.414 + store_reg( R_EAX, Rn );13.415 +:}13.416 +MOV #imm, Rn {:13.417 + load_imm32( R_EAX, imm );13.418 + store_reg( R_EAX, Rn );13.419 +:}13.420 +MOV.B Rm, @Rn {:13.421 + load_reg( R_EAX, Rm );13.422 + load_reg( R_ECX, Rn );13.423 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.424 +:}13.425 +MOV.B Rm, @-Rn {:13.426 + load_reg( R_EAX, Rm );13.427 + load_reg( R_ECX, Rn );13.428 + ADD_imm8s_r32( -1, Rn );13.429 + store_reg( R_ECX, Rn );13.430 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.431 +:}13.432 +MOV.B Rm, @(R0, Rn) {:13.433 + load_reg( R_EAX, 0 );13.434 + load_reg( R_ECX, Rn );13.435 + ADD_r32_r32( R_EAX, R_ECX );13.436 + load_reg( R_EAX, Rm );13.437 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.438 +:}13.439 +MOV.B R0, @(disp, GBR) {:13.440 + load_reg( R_EAX, 0 );13.441 + load_spreg( R_ECX, R_GBR );13.442 + ADD_imm32_r32( disp, R_ECX );13.443 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.444 +:}13.445 +MOV.B R0, @(disp, Rn) {:13.446 + load_reg( R_EAX, 0 );13.447 + load_reg( R_ECX, Rn );13.448 + ADD_imm32_r32( disp, R_ECX );13.449 + MEM_WRITE_BYTE( R_ECX, R_EAX );13.450 +:}13.451 +MOV.B @Rm, Rn {:13.452 + load_reg( R_ECX, Rm );13.453 + MEM_READ_BYTE( R_ECX, R_EAX );13.454 + store_reg( R_ECX, Rn );13.455 +:}13.456 +MOV.B @Rm+, Rn {:13.457 + load_reg( R_ECX, Rm );13.458 + MOV_r32_r32( R_ECX, R_EAX );13.459 + ADD_imm8s_r32( 1, R_EAX );13.460 + store_reg( R_EAX, Rm );13.461 + MEM_READ_BYTE( R_ECX, R_EAX );13.462 + store_reg( R_EAX, Rn );13.463 +:}13.464 +MOV.B @(R0, Rm), Rn {:13.465 + load_reg( R_EAX, 0 );13.466 + load_reg( R_ECX, Rm );13.467 + ADD_r32_r32( R_EAX, R_ECX );13.468 + MEM_READ_BYTE( R_ECX, R_EAX );13.469 + store_reg( R_EAX, Rn );13.470 +:}13.471 +MOV.B @(disp, GBR), R0 {:13.472 + load_spreg( R_ECX, R_GBR );13.473 + ADD_imm32_r32( disp, R_ECX );13.474 + MEM_READ_BYTE( R_ECX, R_EAX );13.475 + store_reg( R_EAX, 0 );13.476 +:}13.477 +MOV.B @(disp, Rm), R0 {:13.478 + load_reg( R_ECX, Rm );13.479 + ADD_imm32_r32( disp, R_ECX );13.480 + MEM_READ_BYTE( R_ECX, R_EAX );13.481 + store_reg( R_EAX, 0 );13.482 +:}13.483 +MOV.L Rm, @Rn {: :}13.484 +MOV.L Rm, @-Rn {: :}13.485 +MOV.L Rm, @(R0, Rn) {: :}13.486 +MOV.L R0, @(disp, GBR) {: :}13.487 +MOV.L Rm, @(disp, Rn) {: :}13.488 +MOV.L @Rm, Rn {: :}13.489 +MOV.L @Rm+, Rn {: :}13.490 +MOV.L @(R0, Rm), Rn {: :}13.491 +MOV.L @(disp, GBR), R0 {: :}13.492 +MOV.L @(disp, PC), Rn {: :}13.493 +MOV.L @(disp, Rm), Rn {: :}13.494 +MOV.W Rm, @Rn {: :}13.495 +MOV.W Rm, @-Rn {: :}13.496 +MOV.W Rm, @(R0, Rn) {: :}13.497 +MOV.W R0, @(disp, GBR) {: :}13.498 +MOV.W R0, @(disp, Rn) {: :}13.499 +MOV.W @Rm, Rn {: :}13.500 +MOV.W @Rm+, Rn {: :}13.501 +MOV.W @(R0, Rm), Rn {: :}13.502 +MOV.W @(disp, GBR), R0 {: :}13.503 +MOV.W @(disp, PC), Rn {: :}13.504 +MOV.W @(disp, Rm), R0 {: :}13.505 +MOVA @(disp, PC), R0 {: :}13.506 +MOVCA.L R0, @Rn {: :}13.507 +13.508 +/* Control transfer instructions */13.509 +BF disp {: :}13.510 +BF/S disp {: :}13.511 +BRA disp {: :}13.512 +BRAF Rn {: :}13.513 +BSR disp {: :}13.514 +BSRF Rn {: :}13.515 +BT disp {: /* If true, result PC += 4 + disp. else result PC = pc+2 */13.516 + return pc + 2;13.517 +:}13.518 +BT/S disp {:13.519 +13.520 + return pc + 4;13.521 +:}13.522 +JMP @Rn {: :}13.523 +JSR @Rn {: :}13.524 +RTE {: :}13.525 +RTS {: :}13.526 +TRAPA #imm {: :}13.527 +UNDEF {: :}13.528 +13.529 +CLRMAC {: :}13.530 +CLRS {: :}13.531 +CLRT {: :}13.532 +SETS {: :}13.533 +SETT {: :}13.534 +13.535 +/* Floating point instructions */13.536 +FABS FRn {: :}13.537 +FADD FRm, FRn {: :}13.538 +FCMP/EQ FRm, FRn {: :}13.539 +FCMP/GT FRm, FRn {: :}13.540 +FCNVDS FRm, FPUL {: :}13.541 +FCNVSD FPUL, FRn {: :}13.542 +FDIV FRm, FRn {: :}13.543 +FIPR FVm, FVn {: :}13.544 +FLDS FRm, FPUL {: :}13.545 +FLDI0 FRn {: :}13.546 +FLDI1 FRn {: :}13.547 +FLOAT FPUL, FRn {: :}13.548 +FMAC FR0, FRm, FRn {: :}13.549 +FMOV FRm, FRn {: :}13.550 +FMOV FRm, @Rn {: :}13.551 +FMOV FRm, @-Rn {: :}13.552 +FMOV FRm, @(R0, Rn) {: :}13.553 +FMOV @Rm, FRn {: :}13.554 +FMOV @Rm+, FRn {: :}13.555 +FMOV @(R0, Rm), FRn {: :}13.556 +FMUL FRm, FRn {: :}13.557 +FNEG FRn {: :}13.558 +FRCHG {: :}13.559 +FSCA FPUL, FRn {: :}13.560 +FSCHG {: :}13.561 +FSQRT FRn {: :}13.562 +FSRRA FRn {: :}13.563 +FSTS FPUL, FRn {: :}13.564 +FSUB FRm, FRn {: :}13.565 +FTRC FRm, FPUL {: :}13.566 +FTRV XMTRX, FVn {: :}13.567 +13.568 +/* Processor control instructions */13.569 +LDC Rm, SR {: /* We need to be a little careful about SR */ :}13.570 +LDC Rm, GBR {:13.571 + load_reg( R_EAX, Rm );13.572 + store_spreg( R_EAX, R_GBR );13.573 +:}13.574 +LDC Rm, VBR {:13.575 + load_reg( R_EAX, Rm );13.576 + store_spreg( R_EAX, R_VBR );13.577 +:}13.578 +LDC Rm, SSR {:13.579 + load_reg( R_EAX, Rm );13.580 + store_spreg( R_EAX, R_SSR );13.581 +:}13.582 +LDC Rm, SGR {:13.583 + load_reg( R_EAX, Rm );13.584 + store_spreg( R_EAX, R_SGR );13.585 +:}13.586 +LDC Rm, SPC {:13.587 + load_reg( R_EAX, Rm );13.588 + store_spreg( R_EAX, R_SPC );13.589 +:}13.590 +LDC Rm, DBR {:13.591 + load_reg( R_EAX, Rm );13.592 + store_spreg( R_EAX, R_DBR );13.593 +:}13.594 +LDC Rm, Rn_BANK {: :}13.595 +LDC.L @Rm+, GBR {:13.596 + load_reg( R_EAX, Rm );13.597 + MOV_r32_r32( R_EAX, R_ECX );13.598 + ADD_imm8s_r32( 4, R_EAX );13.599 + store_reg( R_EAX, Rm );13.600 + MEM_READ_LONG( R_ECX, R_EAX );13.601 + store_spreg( R_EAX, R_GBR );13.602 +:}13.603 +LDC.L @Rm+, SR {:13.604 +:}13.605 +LDC.L @Rm+, VBR {:13.606 + load_reg( R_EAX, Rm );13.607 + MOV_r32_r32( R_EAX, R_ECX );13.608 + ADD_imm8s_r32( 4, R_EAX );13.609 + store_reg( R_EAX, Rm );13.610 + MEM_READ_LONG( R_ECX, R_EAX );13.611 + store_spreg( R_EAX, R_VBR );13.612 +:}13.613 +LDC.L @Rm+, SSR {:13.614 + load_reg( R_EAX, Rm );13.615 + MOV_r32_r32( R_EAX, R_ECX );13.616 + ADD_imm8s_r32( 4, R_EAX );13.617 + store_reg( R_EAX, Rm );13.618 + MEM_READ_LONG( R_ECX, R_EAX );13.619 + store_spreg( R_EAX, R_SSR );13.620 +:}13.621 +LDC.L @Rm+, SGR {:13.622 + load_reg( R_EAX, Rm );13.623 + MOV_r32_r32( R_EAX, R_ECX );13.624 + ADD_imm8s_r32( 4, R_EAX );13.625 + store_reg( R_EAX, Rm );13.626 + MEM_READ_LONG( R_ECX, R_EAX );13.627 + store_spreg( R_EAX, R_SGR );13.628 +:}13.629 +LDC.L @Rm+, SPC {:13.630 + load_reg( R_EAX, Rm );13.631 + MOV_r32_r32( R_EAX, R_ECX );13.632 + ADD_imm8s_r32( 4, R_EAX );13.633 + store_reg( R_EAX, Rm );13.634 + MEM_READ_LONG( R_ECX, R_EAX );13.635 + store_spreg( R_EAX, R_SPC );13.636 +:}13.637 +LDC.L @Rm+, DBR {:13.638 + load_reg( R_EAX, Rm );13.639 + MOV_r32_r32( R_EAX, R_ECX );13.640 + ADD_imm8s_r32( 4, R_EAX );13.641 + store_reg( R_EAX, Rm );13.642 + MEM_READ_LONG( R_ECX, R_EAX );13.643 + store_spreg( R_EAX, R_DBR );13.644 +:}13.645 +LDC.L @Rm+, Rn_BANK {:13.646 +:}13.647 +LDS Rm, FPSCR {:13.648 + load_reg( R_EAX, Rm );13.649 + store_spreg( R_EAX, R_FPSCR );13.650 +:}13.651 +LDS.L @Rm+, FPSCR {:13.652 + load_reg( R_EAX, Rm );13.653 + MOV_r32_r32( R_EAX, R_ECX );13.654 + ADD_imm8s_r32( 4, R_EAX );13.655 + store_reg( R_EAX, Rm );13.656 + MEM_READ_LONG( R_ECX, R_EAX );13.657 + store_spreg( R_EAX, R_FPSCR );13.658 +:}13.659 +LDS Rm, FPUL {:13.660 + load_reg( R_EAX, Rm );13.661 + store_spreg( R_EAX, R_FPUL );13.662 +:}13.663 +LDS.L @Rm+, FPUL {:13.664 + load_reg( R_EAX, Rm );13.665 + MOV_r32_r32( R_EAX, R_ECX );13.666 + ADD_imm8s_r32( 4, R_EAX );13.667 + store_reg( R_EAX, Rm );13.668 + MEM_READ_LONG( R_ECX, R_EAX );13.669 + store_spreg( R_EAX, R_FPUL );13.670 +:}13.671 +LDS Rm, MACH {:13.672 + load_reg( R_EAX, Rm );13.673 + store_spreg( R_EAX, R_MACH );13.674 +:}13.675 +LDS.L @Rm+, MACH {:13.676 + load_reg( R_EAX, Rm );13.677 + MOV_r32_r32( R_EAX, R_ECX );13.678 + ADD_imm8s_r32( 4, R_EAX );13.679 + store_reg( R_EAX, Rm );13.680 + MEM_READ_LONG( R_ECX, R_EAX );13.681 + store_spreg( R_EAX, R_MACH );13.682 +:}13.683 +LDS Rm, MACL {:13.684 + load_reg( R_EAX, Rm );13.685 + store_spreg( R_EAX, R_MACL );13.686 +:}13.687 +LDS.L @Rm+, MACL {:13.688 + load_reg( R_EAX, Rm );13.689 + MOV_r32_r32( R_EAX, R_ECX );13.690 + ADD_imm8s_r32( 4, R_EAX );13.691 + store_reg( R_EAX, Rm );13.692 + MEM_READ_LONG( R_ECX, R_EAX );13.693 + store_spreg( R_EAX, R_MACL );13.694 +:}13.695 +LDS Rm, PR {:13.696 + load_reg( R_EAX, Rm );13.697 + store_spreg( R_EAX, R_PR );13.698 +:}13.699 +LDS.L @Rm+, PR {:13.700 + load_reg( R_EAX, Rm );13.701 + MOV_r32_r32( R_EAX, R_ECX );13.702 + ADD_imm8s_r32( 4, R_EAX );13.703 + store_reg( R_EAX, Rm );13.704 + MEM_READ_LONG( R_ECX, R_EAX );13.705 + store_spreg( R_EAX, R_PR );13.706 +:}13.707 +LDTLB {: :}13.708 +OCBI @Rn {: :}13.709 +OCBP @Rn {: :}13.710 +OCBWB @Rn {: :}13.711 +PREF @Rn {: :}13.712 +SLEEP {: :}13.713 + STC SR, Rn {: /* TODO */13.714 +:}13.715 +STC GBR, Rn {:13.716 + load_spreg( R_EAX, R_GBR );13.717 + store_reg( R_EAX, Rn );13.718 +:}13.719 +STC VBR, Rn {:13.720 + load_spreg( R_EAX, R_VBR );13.721 + store_reg( R_EAX, Rn );13.722 +:}13.723 +STC SSR, Rn {:13.724 + load_spreg( R_EAX, R_SSR );13.725 + store_reg( R_EAX, Rn );13.726 +:}13.727 +STC SPC, Rn {:13.728 + load_spreg( R_EAX, R_SPC );13.729 + store_reg( R_EAX, Rn );13.730 +:}13.731 +STC SGR, Rn {:13.732 + load_spreg( R_EAX, R_SGR );13.733 + store_reg( R_EAX, Rn );13.734 +:}13.735 +STC DBR, Rn {:13.736 + load_spreg( R_EAX, R_DBR );13.737 + store_reg( R_EAX, Rn );13.738 +:}13.739 + STC Rm_BANK, Rn {: /* TODO */13.740 +:}13.741 + STC.L SR, @-Rn {: /* TODO */13.742 +:}13.743 +STC.L VBR, @-Rn {:13.744 + load_reg( R_ECX, Rn );13.745 + ADD_imm8s_r32( -4, Rn );13.746 + store_reg( R_ECX, Rn );13.747 + load_spreg( R_EAX, R_VBR );13.748 + MEM_WRITE_LONG( R_ECX, R_EAX );13.749 +:}13.750 +STC.L SSR, @-Rn {:13.751 + load_reg( R_ECX, Rn );13.752 + ADD_imm8s_r32( -4, Rn );13.753 + store_reg( R_ECX, Rn );13.754 + load_spreg( R_EAX, R_SSR );13.755 + MEM_WRITE_LONG( R_ECX, R_EAX );13.756 +:}13.757 +STC.L SPC, @-Rn {:13.758 + load_reg( R_ECX, Rn );13.759 + ADD_imm8s_r32( -4, Rn );13.760 + store_reg( R_ECX, Rn );13.761 + load_spreg( R_EAX, R_SPC );13.762 + MEM_WRITE_LONG( R_ECX, R_EAX );13.763 +:}13.764 +STC.L SGR, @-Rn {:13.765 + load_reg( R_ECX, Rn );13.766 + ADD_imm8s_r32( -4, Rn );13.767 + store_reg( R_ECX, Rn );13.768 + load_spreg( R_EAX, R_SGR );13.769 + MEM_WRITE_LONG( R_ECX, R_EAX );13.770 +:}13.771 +STC.L DBR, @-Rn {:13.772 + load_reg( R_ECX, Rn );13.773 + ADD_imm8s_r32( -4, Rn );13.774 + store_reg( R_ECX, Rn );13.775 + load_spreg( R_EAX, R_DBR );13.776 + MEM_WRITE_LONG( R_ECX, R_EAX );13.777 +:}13.778 +STC.L Rm_BANK, @-Rn {: :}13.779 +STC.L GBR, @-Rn {:13.780 + load_reg( R_ECX, Rn );13.781 + ADD_imm8s_r32( -4, Rn );13.782 + store_reg( R_ECX, Rn );13.783 + load_spreg( R_EAX, R_GBR );13.784 + MEM_WRITE_LONG( R_ECX, R_EAX );13.785 +:}13.786 +STS FPSCR, Rn {:13.787 + load_spreg( R_EAX, R_FPSCR );13.788 + store_reg( R_EAX, Rn );13.789 +:}13.790 +STS.L FPSCR, @-Rn {:13.791 + load_reg( R_ECX, Rn );13.792 + ADD_imm8s_r32( -4, Rn );13.793 + store_reg( R_ECX, Rn );13.794 + load_spreg( R_EAX, R_FPSCR );13.795 + MEM_WRITE_LONG( R_ECX, R_EAX );13.796 +:}13.797 +STS FPUL, Rn {:13.798 + load_spreg( R_EAX, R_FPUL );13.799 + store_reg( R_EAX, Rn );13.800 +:}13.801 +STS.L FPUL, @-Rn {:13.802 + load_reg( R_ECX, Rn );13.803 + ADD_imm8s_r32( -4, Rn );13.804 + store_reg( R_ECX, Rn );13.805 + load_spreg( R_EAX, R_FPUL );13.806 + MEM_WRITE_LONG( R_ECX, R_EAX );13.807 +:}13.808 +STS MACH, Rn {:13.809 + load_spreg( R_EAX, R_MACH );13.810 + store_reg( R_EAX, Rn );13.811 +:}13.812 +STS.L MACH, @-Rn {:13.813 + load_reg( R_ECX, Rn );13.814 + ADD_imm8s_r32( -4, Rn );13.815 + store_reg( R_ECX, Rn );13.816 + load_spreg( R_EAX, R_MACH );13.817 + MEM_WRITE_LONG( R_ECX, R_EAX );13.818 +:}13.819 +STS MACL, Rn {:13.820 + load_spreg( R_EAX, R_MACL );13.821 + store_reg( R_EAX, Rn );13.822 +:}13.823 +STS.L MACL, @-Rn {:13.824 + load_reg( R_ECX, Rn );13.825 + ADD_imm8s_r32( -4, Rn );13.826 + store_reg( R_ECX, Rn );13.827 + load_spreg( R_EAX, R_MACL );13.828 + MEM_WRITE_LONG( R_ECX, R_EAX );13.829 +:}13.830 +STS PR, Rn {:13.831 + load_spreg( R_EAX, R_PR );13.832 + store_reg( R_EAX, Rn );13.833 +:}13.834 +STS.L PR, @-Rn {:13.835 + load_reg( R_ECX, Rn );13.836 + ADD_imm8s_r32( -4, Rn );13.837 + store_reg( R_ECX, Rn );13.838 + load_spreg( R_EAX, R_PR );13.839 + MEM_WRITE_LONG( R_ECX, R_EAX );13.840 +:}13.841 +13.842 +NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}13.843 +%%13.844 +13.845 + return 0;13.846 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000014.2 +++ b/src/sh4/x86op.h Thu Aug 23 12:33:27 2007 +000014.3 @@ -0,0 +1,157 @@14.4 +/**14.5 + * $Id: x86op.h,v 1.1 2007-08-23 12:33:27 nkeynes Exp $14.6 + *14.7 + * Definitions of x86 opcodes for use by the translator.14.8 + *14.9 + * Copyright (c) 2007 Nathan Keynes.14.10 + *14.11 + * This program is free software; you can redistribute it and/or modify14.12 + * it under the terms of the GNU General Public License as published by14.13 + * the Free Software Foundation; either version 2 of the License, or14.14 + * (at your option) any later version.14.15 + *14.16 + * This program is distributed in the hope that it will be useful,14.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of14.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14.19 + * GNU General Public License for more details.14.20 + */14.21 +14.22 +#ifndef __lxdream_x86op_H14.23 +#define __lxdream_x86op_H14.24 +14.25 +#define R_NONE -114.26 +#define R_EAX 014.27 +#define R_ECX 114.28 +#define R_EDX 214.29 +#define R_EBX 314.30 +#define R_ESP 414.31 +#define R_EBP 514.32 +#define R_ESI 614.33 +#define R_EDI 714.34 +14.35 +#define R_AL 014.36 +#define R_CL 114.37 +#define R_DL 214.38 +#define R_BL 314.39 +#define R_AH 414.40 +#define R_CH 514.41 +#define R_DH 614.42 +#define R_BH 714.43 +14.44 +14.45 +#define OP(x) *xlat_output++ = x14.46 +#define OP32(x) *((uint32_t *)xlat_output) = x; xlat_output+=214.47 +14.48 +/* Offset of a reg relative to the sh4r structure */14.49 +#define REG_OFFSET(reg) (((char *)&sh4r.reg) - ((char *)&sh4r))14.50 +14.51 +#define R_T REG_OFFSET(t)14.52 +#define R_GBR REG_OFFSET(gbr)14.53 +#define R_SSR REG_OFFSET(ssr)14.54 +#define R_SPC REG_OFFSET(spc)14.55 +#define R_VBR REG_OFFSET(vbr)14.56 +#define R_MACH REG_OFFSET(mac)+414.57 +#define R_MACL REG_OFFSET(mac)14.58 +#define R_PR REG_OFFSET(pr)14.59 +#define R_SGR REG_OFFSET(sgr)14.60 +#define R_FPUL REG_OFFSET(fpul)14.61 +#define R_FPSCR REG_OFFSET(fpscr)14.62 +#define R_DBR REG_OFFSET(dbr)14.63 +14.64 +/**************** Basic X86 operations *********************/14.65 +/* Note: operands follow SH4 convention (source, dest) rather than x8614.66 + * conventions (dest, source)14.67 + */14.68 +14.69 +/* Two-reg modrm form - first arg is the r32 reg, second arg is the r/m32 reg */14.70 +#define MODRM_r32_rm32(r1,r2) OP(0xC0 | (r1<<3) | r2)14.71 +#define MODRM_rm32_r32(r1,r2) OP(0xC0 | (r2<<3) | r1)14.72 +14.73 +/* ebp+disp8 modrm form */14.74 +#define MODRM_r32_ebp8(r1,disp) OP(0x45 | (r1<<3)); OP(disp)14.75 +14.76 +/* ebp+disp32 modrm form */14.77 +#define MODRM_r32_ebp32(r1,disp) OP(0x85 | (r1<<3)); OP32(disp)14.78 +14.79 +/* Major opcodes */14.80 +#define ADD_r32_r32(r1,r2) OP(0x03); MODRM_rm32_r32(r1,r2)14.81 +#define ADD_imm8s_r32(imm,r1) OP(0x83); MODRM_rm32_r32(r1, 0); OP(imm)14.82 +#define ADC_r32_r32(r1,r2) OP(0x13); MODRM_rm32_r32(r1,r2)14.83 +#define AND_r32_r32(r1,r2) OP(0x23); MODRM_rm32_r32(r1,r2)14.84 +#define AND_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,4); OP32(imm)14.85 +#define CMC() OP(0xF5)14.86 +#define CMP_r32_r32(r1,r2) OP(0x3B); MODRM_rm32_r32(r1,r2)14.87 +#define CMP_imm8s_r32(imm,r1) OP(0x83); MODRM_rm32_r32(r1,7); OP(imm)14.88 +#define MOV_r32_ebp8(r1,disp) OP(0x89); MODRM_r32_ebp8(r1,disp)14.89 +#define MOV_r32_ebp32(r1,disp) OP(0x89); MODRM_r32_ebp32(r1,disp)14.90 +#define MOV_ebp8_r32(r1,disp) OP(0x8B); MODRM_r32_ebp8(r1,disp)14.91 +#define MOV_ebp32_r32(r1,disp) OP(0x8B); MODRM_r32_ebp32(r1,disp)14.92 +#define MOVSX_r8_r32(r1,r2) OP(0x0F); OP(0xBE); MODRM_rm32_r32(r1,r2)14.93 +#define MOVSX_r16_r32(r1,r2) OP(0x0F); OP(0xBF); MODRM_rm32_r32(r1,r2)14.94 +#define MOVZX_r8_r32(r1,r2) OP(0x0F); OP(0xB6); MODRM_rm32_r32(r1,r2)14.95 +#define MOVZX_r16_r32(r1,r2) OP(0x0F); OP(0xB7); MODRM_rm32_r32(r1,r2)14.96 +#define NEG_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,3)14.97 +#define NOT_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,2)14.98 +#define OR_r32_r32(r1,r2) OP(0x0B); MODRM_rm32_r32(r1,r2)14.99 +#define OR_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,1); OP32(imm)14.100 +#define RCL1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,2)14.101 +#define RCR1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,3)14.102 +#define RET() OP(0xC3)14.103 +#define ROL1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,0)14.104 +#define ROR1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,1)14.105 +#define SAR1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,7)14.106 +#define SAR_imm8_r32(imm,r1) OP(0xC1); MODRM_rm32_r32(r1,7); OP(imm)14.107 +#define SBB_r32_r32(r1,r2) OP(0x1B); MODRM_rm32_r32(r1,r2)14.108 +#define SHL1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,4)14.109 +#define SHL_imm8_r32(imm,r1) OP(0xC1); MODRM_rm32_r32(r1,4); OP(imm)14.110 +#define SHR1_r32(r1) OP(0xD1); MODRM_rm32_r32(r1,5)14.111 +#define SHR_imm8_r32(imm,r1) OP(0xC1); MODRM_rm32_r32(r1,5); OP(imm)14.112 +#define SUB_r32_r32(r1,r2) OP(0x2B); MODRM_rm32_r32(r1,r2)14.113 +#define TEST_r32_r32(r1,r2) OP(0x85); MODRM_rm32_r32(r1,r2)14.114 +#define TEST_imm32_r32(imm,r1) OP(0xF7); MODRM_rm32_r32(r1,0); OP32(imm)14.115 +#define XOR_r32_r32(r1,r2) OP(0x33); MODRM_rm32_r32(r1,r2)14.116 +#define XOR_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,6); OP32(imm)14.117 +14.118 +#define ADD_imm32_r32(imm32,r1)14.119 +#define MOV_r32_r32(r1,r2)14.120 +#define XCHG_r8_r8(r1,r2)14.121 +14.122 +/* Conditional branches */14.123 +#define JE_rel8(rel) OP(0x74); OP(rel)14.124 +#define JA_rel8(rel) OP(0x77); OP(rel)14.125 +#define JAE_rel8(rel) OP(0x73); OP(rel)14.126 +#define JG_rel8(rel) OP(0x7F); OP(rel)14.127 +#define JGE_rel8(rel) OP(0x7D); OP(rel)14.128 +#define JC_rel8(rel) OP(0x72); OP(rel)14.129 +#define JO_rel8(rel) OP(0x70); OP(rel)14.130 +14.131 +/* Negated forms */14.132 +#define JNE_rel8(rel) OP(0x75); OP(rel)14.133 +#define JNA_rel8(rel) OP(0x76); OP(rel)14.134 +#define JNAE_rel8(rel) OP(0x72); OP(rel)14.135 +#define JNG_rel8(rel) OP(0x7E); OP(rel)14.136 +#define JNGE_rel8(rel) OP(0x7C); OP(rel)14.137 +#define JNC_rel8(rel) OP(0x73); OP(rel)14.138 +#define JNO_rel8(rel) OP(0x71); OP(rel)14.139 +14.140 +/* Conditional setcc - writeback to sh4r.t */14.141 +#define SETE_t() OP(0x0F); OP(0x94); MODRM_r32_ebp8(0, R_T);14.142 +#define SETA_t() OP(0x0F); OP(0x97); MODRM_r32_ebp8(0, R_T);14.143 +#define SETAE_t() OP(0x0F); OP(0x93); MODRM_r32_ebp8(0, R_T);14.144 +#define SETG_t() OP(0x0F); OP(0x9F); MODRM_r32_ebp8(0, R_T);14.145 +#define SETGE_t() OP(0x0F); OP(0x9D); MODRM_r32_ebp8(0, R_T);14.146 +#define SETC_t() OP(0x0F); OP(0x92); MODRM_r32_ebp8(0, R_T);14.147 +#define SETO_t() OP(0x0F); OP(0x90); MODRM_r32_ebp8(0, R_T);14.148 +14.149 +#define SETNE_t() OP(0x0F); OP(0x95); MODRM_r32_ebp8(0, R_T);14.150 +#define SETNA_t() OP(0x0F); OP(0x96); MODRM_r32_ebp8(0, R_T);14.151 +#define SETNAE_t() OP(0x0F); OP(0x92); MODRM_r32_ebp8(0, R_T);14.152 +#define SETNG_t() OP(0x0F); OP(0x9E); MODRM_r32_ebp8(0, R_T);14.153 +#define SETNGE_t() OP(0x0F); OP(0x9C); MODRM_r32_ebp8(0, R_T);14.154 +#define SETNC_t() OP(0x0F); OP(0x93); MODRM_r32_ebp8(0, R_T);14.155 +#define SETNO_t() OP(0x0F); OP(0x91); MODRM_r32_ebp8(0, R_T);14.156 +14.157 +/* Pseudo-op Load carry from T: CMP [EBP+t], #01 ; CMC */14.158 +#define LDC_t() OP(0x83); MODRM_r32_ebp8(7,R_T); OP(0x01); CMC()14.159 +14.160 +#endif /* !__lxdream_x86op_H */
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000015.2 +++ b/src/sh4/xltcache.c Thu Aug 23 12:33:27 2007 +000015.3 @@ -0,0 +1,347 @@15.4 +/**15.5 + * $Id: xltcache.c,v 1.1 2007-08-23 12:33:27 nkeynes Exp $15.6 + *15.7 + * Translation cache management. This part is architecture independent.15.8 + *15.9 + * Copyright (c) 2005 Nathan Keynes.15.10 + *15.11 + * This program is free software; you can redistribute it and/or modify15.12 + * it under the terms of the GNU General Public License as published by15.13 + * the Free Software Foundation; either version 2 of the License, or15.14 + * (at your option) any later version.15.15 + *15.16 + * This program is distributed in the hope that it will be useful,15.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of15.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15.19 + * GNU General Public License for more details.15.20 + */15.21 +15.22 +#include "sh4/xltcache.h"15.23 +#include "dreamcast.h"15.24 +#include <sys/mman.h>15.25 +#include <assert.h>15.26 +15.27 +#define XLAT_LUT_PAGE_BITS 1215.28 +#define XLAT_LUT_TOTAL_BITS 2815.29 +#define XLAT_LUT_PAGE(addr) (((addr)>>13) & 0xFFFF)15.30 +#define XLAT_LUT_ENTRY(addr) (((addr)&0x1FFE) >> 1)15.31 +15.32 +#define XLAT_LUT_PAGES (1<<(XLAT_LUT_TOTAL_BITS-XLAT_LUT_PAGE_BITS))15.33 +#define XLAT_LUT_PAGE_ENTRIES (1<<XLAT_LUT_PAGE_BITS)15.34 +#define XLAT_LUT_PAGE_SIZE (XLAT_LUT_PAGE_ENTRIES * sizeof(void *))15.35 +15.36 +#define XLAT_LUT_ENTRY_EMPTY (void *)015.37 +#define XLAT_LUT_ENTRY_USED (void *)115.38 +15.39 +#define NEXT(block) ( (xlat_cache_block_t)&((block)->code[(block)->size]))15.40 +#define BLOCK_FOR_CODE(code) (((xlat_cache_block_t)code)-1)15.41 +#define IS_ENTRY_POINT(ent) (ent > XLAT_LUT_ENTRY_USED)15.42 +#define IS_ENTRY_USED(ent) (ent != XLAT_LUT_ENTRY_EMPTY)15.43 +15.44 +#define MIN_BLOCK_SIZE 3215.45 +#define MIN_TOTAL_SIZE (sizeof(struct xlat_cache_block)+MIN_BLOCK_SIZE)15.46 +15.47 +#define BLOCK_INACTIVE 015.48 +#define BLOCK_ACTIVE 115.49 +#define BLOCK_USED 215.50 +15.51 +xlat_cache_block_t xlat_new_cache;15.52 +xlat_cache_block_t xlat_new_cache_ptr;15.53 +xlat_cache_block_t xlat_new_create_ptr;15.54 +xlat_cache_block_t xlat_temp_cache;15.55 +xlat_cache_block_t xlat_temp_cache_ptr;15.56 +xlat_cache_block_t xlat_old_cache;15.57 +xlat_cache_block_t xlat_old_cache_ptr;15.58 +static void ***xlat_lut;15.59 +static void **xlat_lut2; /* second-tier page info */15.60 +15.61 +void xlat_cache_init()15.62 +{15.63 + xlat_new_cache = mmap( NULL, XLAT_NEW_CACHE_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,15.64 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );15.65 + xlat_temp_cache = mmap( NULL, XLAT_TEMP_CACHE_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,15.66 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );15.67 + xlat_old_cache = mmap( NULL, XLAT_OLD_CACHE_SIZE, PROT_EXEC|PROT_READ|PROT_WRITE,15.68 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );15.69 + xlat_new_cache_ptr = xlat_new_cache;15.70 + xlat_temp_cache_ptr = xlat_temp_cache;15.71 + xlat_old_cache_ptr = xlat_old_cache;15.72 + xlat_new_create_ptr = xlat_new_cache;15.73 +15.74 + xlat_lut = mmap( NULL, XLAT_LUT_PAGES*sizeof(void *), PROT_READ|PROT_WRITE,15.75 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);15.76 + memset( xlat_lut, 0, XLAT_LUT_PAGES*sizeof(void *) );15.77 +15.78 + xlat_flush_cache();15.79 +}15.80 +15.81 +/**15.82 + * Reset the cache structure to its default state15.83 + */15.84 +void xlat_flush_cache()15.85 +{15.86 + xlat_cache_block_t tmp;15.87 + int i;15.88 + xlat_new_cache_ptr = xlat_new_cache;15.89 + xlat_new_cache_ptr->active = 0;15.90 + xlat_new_cache_ptr->size = XLAT_NEW_CACHE_SIZE - 2*sizeof(struct xlat_cache_block);15.91 + tmp = NEXT(xlat_new_cache_ptr);15.92 + tmp->active = 1;15.93 + tmp->size = 0;15.94 + xlat_temp_cache_ptr = xlat_temp_cache;15.95 + xlat_temp_cache_ptr->active = 0;15.96 + xlat_temp_cache_ptr->size = XLAT_TEMP_CACHE_SIZE - 2*sizeof(struct xlat_cache_block);15.97 + tmp = NEXT(xlat_temp_cache_ptr);15.98 + tmp->active = 1;15.99 + tmp->size = 0;15.100 + xlat_old_cache_ptr = xlat_old_cache;15.101 + xlat_old_cache_ptr->active = 0;15.102 + xlat_old_cache_ptr->size = XLAT_OLD_CACHE_SIZE - 2*sizeof(struct xlat_cache_block);15.103 + tmp = NEXT(xlat_old_cache_ptr);15.104 + tmp->active = 1;15.105 + tmp->size = 0;15.106 + for( i=0; i<XLAT_LUT_PAGES; i++ ) {15.107 + if( xlat_lut[i] != NULL ) {15.108 + memset( xlat_lut[i], 0, XLAT_LUT_PAGE_SIZE );15.109 + }15.110 + }15.111 +}15.112 +15.113 +void xlat_flush_page( sh4addr_t address )15.114 +{15.115 + int i;15.116 + void **page = xlat_lut[XLAT_LUT_PAGE(address)];15.117 + for( i=0; i<XLAT_LUT_PAGE_ENTRIES; i++ ) {15.118 + if( IS_ENTRY_POINT(page[i]) ) {15.119 + BLOCK_FOR_CODE(page[i])->active = 0;15.120 + }15.121 + page[i] = NULL;15.122 + }15.123 +}15.124 +15.125 +void *xlat_get_code( sh4addr_t address )15.126 +{15.127 + void **page = xlat_lut[XLAT_LUT_PAGE(address)];15.128 + if( page == NULL ) {15.129 + return NULL;15.130 + }15.131 + return page[XLAT_LUT_ENTRY(address)];15.132 +}15.133 +15.134 +/**15.135 + * Cut the specified block so that it has the given size, with the remaining data15.136 + * forming a new free block. If the free block would be less than the minimum size,15.137 + * the cut is not performed.15.138 + * @return the next block after the (possibly cut) block.15.139 + */15.140 +static inline xlat_cache_block_t xlat_cut_block( xlat_cache_block_t block, int cutsize )15.141 +{15.142 + if( block->size > cutsize + MIN_TOTAL_SIZE ) {15.143 + int oldsize = block->size;15.144 + block->size = cutsize;15.145 + xlat_cache_block_t next = NEXT(block);15.146 + next->active = 0;15.147 + next->size = oldsize - cutsize - sizeof(struct xlat_cache_block);15.148 + return next;15.149 + } else {15.150 + return NEXT(block);15.151 + }15.152 +}15.153 +15.154 +/**15.155 + * Promote a block in temp space (or elsewhere for that matter) to old space.15.156 + *15.157 + * @param block to promote.15.158 + */15.159 +static void xlat_promote_to_old_space( xlat_cache_block_t block )15.160 +{15.161 + int allocation = -sizeof(struct xlat_cache_block);15.162 + int size = block->size;15.163 + xlat_cache_block_t curr = xlat_old_cache_ptr;15.164 + xlat_cache_block_t start_block = curr;15.165 + do {15.166 + allocation += curr->size + sizeof(struct xlat_cache_block);15.167 + curr = NEXT(curr);15.168 + if( allocation > size ) {15.169 + break; /* done */15.170 + }15.171 + if( curr->size == 0 ) { /* End-of-cache Sentinel */15.172 + /* Leave what we just released as free space and start again from the15.173 + * top of the cache15.174 + */15.175 + start_block->active = 0;15.176 + start_block->size = allocation;15.177 + allocation = -sizeof(struct xlat_cache_block);15.178 + start_block = curr = xlat_old_cache;15.179 + }15.180 + } while(1);15.181 + start_block->active = 1;15.182 + start_block->size = allocation;15.183 + start_block->lut_entry = block->lut_entry;15.184 + *block->lut_entry = &start_block->code;15.185 + memcpy( start_block->code, block->code, block->size );15.186 + xlat_old_cache_ptr = xlat_cut_block(start_block, size );15.187 + if( xlat_old_cache_ptr->size == 0 ) {15.188 + xlat_old_cache_ptr = xlat_old_cache;15.189 + }15.190 +}15.191 +15.192 +/**15.193 + * Similarly to the above method, promotes a block to temp space.15.194 + * TODO: Try to combine these - they're nearly identical15.195 + */15.196 +void xlat_promote_to_temp_space( xlat_cache_block_t block )15.197 +{15.198 + int size = block->size;15.199 + int allocation = -sizeof(struct xlat_cache_block);15.200 + xlat_cache_block_t curr = xlat_temp_cache_ptr;15.201 + xlat_cache_block_t start_block = curr;15.202 + do {15.203 + if( curr->active == BLOCK_USED ) {15.204 + xlat_promote_to_old_space( curr );15.205 + }15.206 + allocation += curr->size + sizeof(struct xlat_cache_block);15.207 + curr = NEXT(curr);15.208 + if( allocation > size ) {15.209 + break; /* done */15.210 + }15.211 + if( curr->size == 0 ) { /* End-of-cache Sentinel */15.212 + /* Leave what we just released as free space and start again from the15.213 + * top of the cache15.214 + */15.215 + start_block->active = 0;15.216 + start_block->size = allocation;15.217 + allocation = -sizeof(struct xlat_cache_block);15.218 + start_block = curr = xlat_temp_cache;15.219 + }15.220 + } while(1);15.221 + start_block->active = 1;15.222 + start_block->size = allocation;15.223 + start_block->lut_entry = block->lut_entry;15.224 + *block->lut_entry = &start_block->code;15.225 + memcpy( start_block->code, block->code, block->size );15.226 + xlat_temp_cache_ptr = xlat_cut_block(start_block, size );15.227 + if( xlat_temp_cache_ptr->size == 0 ) {15.228 + xlat_temp_cache_ptr = xlat_temp_cache;15.229 + }15.230 +15.231 +}15.232 +15.233 +/**15.234 + * Returns the next block in the new cache list that can be written to by the15.235 + * translator. If the next block is active, it is evicted first.15.236 + */15.237 +xlat_cache_block_t xlat_start_block( sh4addr_t address )15.238 +{15.239 + if( xlat_new_cache_ptr->size == 0 ) {15.240 + xlat_new_cache_ptr = xlat_new_cache;15.241 + }15.242 +15.243 + if( xlat_new_cache_ptr->active ) {15.244 + xlat_promote_to_temp_space( xlat_new_cache_ptr );15.245 + }15.246 + xlat_new_create_ptr = xlat_new_cache_ptr;15.247 + xlat_new_create_ptr->active = 1;15.248 + xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr);15.249 +15.250 + /* Add the LUT entry for the block */15.251 + if( xlat_lut[XLAT_LUT_PAGE(address)] == NULL ) {15.252 + xlat_lut[XLAT_LUT_PAGE(address)] =15.253 + mmap( NULL, XLAT_LUT_PAGE_SIZE, PROT_READ|PROT_WRITE,15.254 + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );15.255 + memset( xlat_lut[XLAT_LUT_PAGE(address)], 0, XLAT_LUT_PAGE_SIZE );15.256 + }15.257 +15.258 + if( IS_ENTRY_POINT(xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)]) ) {15.259 + xlat_cache_block_t oldblock = BLOCK_FOR_CODE(xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)]);15.260 + oldblock->active = 0;15.261 + }15.262 +15.263 + xlat_lut[XLAT_LUT_PAGE(address)][XLAT_LUT_ENTRY(address)] =15.264 + &xlat_new_create_ptr->code;15.265 + xlat_new_create_ptr->lut_entry = xlat_lut[XLAT_LUT_PAGE(address)] + XLAT_LUT_ENTRY(address);15.266 +15.267 + return xlat_new_create_ptr;15.268 +}15.269 +15.270 +xlat_cache_block_t xlat_extend_block()15.271 +{15.272 + if( xlat_new_cache_ptr->size == 0 ) {15.273 + /* Migrate to the front of the cache to keep it contiguous */15.274 + xlat_new_create_ptr->active = 0;15.275 + char *olddata = xlat_new_create_ptr->code;15.276 + int oldsize = xlat_new_create_ptr->size;15.277 + int size = oldsize + MIN_BLOCK_SIZE; /* minimum expansion */15.278 + void **lut_entry = xlat_new_create_ptr->lut_entry;15.279 + int allocation = -sizeof(struct xlat_cache_block);15.280 + xlat_new_cache_ptr = xlat_new_cache;15.281 + do {15.282 + if( xlat_new_cache_ptr->active ) {15.283 + xlat_promote_to_temp_space( xlat_new_cache_ptr );15.284 + }15.285 + allocation += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block);15.286 + xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr);15.287 + } while( allocation < size );15.288 + xlat_new_create_ptr = xlat_new_cache;15.289 + xlat_new_create_ptr->active = 1;15.290 + xlat_new_create_ptr->size = allocation;15.291 + xlat_new_create_ptr->lut_entry = lut_entry;15.292 + *lut_entry = &xlat_new_create_ptr->code;15.293 + memmove( xlat_new_create_ptr->code, olddata, oldsize );15.294 + } else {15.295 + if( xlat_new_cache_ptr->active ) {15.296 + xlat_promote_to_temp_space( xlat_new_cache_ptr );15.297 + }15.298 + xlat_new_create_ptr->size += xlat_new_cache_ptr->size + sizeof(struct xlat_cache_block);15.299 + xlat_new_cache_ptr = NEXT(xlat_new_cache_ptr);15.300 + }15.301 + return xlat_new_create_ptr;15.302 +15.303 +}15.304 +15.305 +void xlat_commit_block( uint32_t destsize, uint32_t srcsize )15.306 +{15.307 + void **ptr = xlat_new_create_ptr->lut_entry;15.308 + void **endptr = ptr + (srcsize>>2);15.309 + while( ptr < endptr ) {15.310 + if( *ptr == NULL ) {15.311 + *ptr = XLAT_LUT_ENTRY_USED;15.312 + }15.313 + ptr++;15.314 + }15.315 +15.316 + xlat_new_cache_ptr = xlat_cut_block( xlat_new_create_ptr, destsize );15.317 +}15.318 +15.319 +void xlat_delete_block( xlat_cache_block_t block )15.320 +{15.321 + block->active = 0;15.322 + *block->lut_entry = NULL;15.323 +}15.324 +15.325 +void xlat_check_cache_integrity( xlat_cache_block_t cache, xlat_cache_block_t ptr, int size )15.326 +{15.327 + int foundptr = 0;15.328 + xlat_cache_block_t tail =15.329 + (xlat_cache_block_t)(((char *)cache) + size - sizeof(struct xlat_cache_block));15.330 +15.331 + assert( tail->active == 1 );15.332 + assert( tail->size == 0 );15.333 + while( cache < tail ) {15.334 + assert( cache->active >= 0 && cache->active <= 2 );15.335 + assert( cache->size >= 0 && cache->size < size );15.336 + if( cache == ptr ) {15.337 + foundptr = 1;15.338 + }15.339 + cache = NEXT(cache);15.340 + }15.341 + assert( cache == tail );15.342 + assert( foundptr == 1 );15.343 +}15.344 +15.345 +void xlat_check_integrity( )15.346 +{15.347 + xlat_check_cache_integrity( xlat_new_cache, xlat_new_cache_ptr, XLAT_NEW_CACHE_SIZE );15.348 + xlat_check_cache_integrity( xlat_temp_cache, xlat_temp_cache_ptr, XLAT_TEMP_CACHE_SIZE );15.349 + xlat_check_cache_integrity( xlat_old_cache, xlat_old_cache_ptr, XLAT_OLD_CACHE_SIZE );15.350 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000016.2 +++ b/src/sh4/xltcache.h Thu Aug 23 12:33:27 2007 +000016.3 @@ -0,0 +1,75 @@16.4 +/**16.5 + * $Id: xltcache.h,v 1.1 2007-08-23 12:33:27 nkeynes Exp $16.6 + *16.7 + * Translation cache support (architecture independent)16.8 + *16.9 + * Copyright (c) 2005 Nathan Keynes.16.10 + *16.11 + * This program is free software; you can redistribute it and/or modify16.12 + * it under the terms of the GNU General Public License as published by16.13 + * the Free Software Foundation; either version 2 of the License, or16.14 + * (at your option) any later version.16.15 + *16.16 + * This program is distributed in the hope that it will be useful,16.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of16.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16.19 + * GNU General Public License for more details.16.20 + */16.21 +16.22 +#include "dream.h"16.23 +#include "mem.h"16.24 +16.25 +typedef struct xlat_cache_block {16.26 + int active; /* 0 = deleted, 1 = normal. 2 = accessed (temp-space only) */16.27 + uint32_t size;16.28 + void **lut_entry; /* For deletion */16.29 + unsigned char code[0];16.30 +} *xlat_cache_block_t;16.31 +16.32 +/**16.33 + * Returns the next block in the new cache list that can be written to by the16.34 + * translator.16.35 + */16.36 +xlat_cache_block_t xlat_start_block(sh4addr_t address);16.37 +16.38 +/**16.39 + * Increases the current block size (only valid between calls to xlat_start_block()16.40 + * and xlat_commit_block()).16.41 + * @return the new block, which may be different from the old block.16.42 + */16.43 +xlat_cache_block_t xlat_extend_block();16.44 +16.45 +/**16.46 + * Commit the current translation block16.47 + * @param addr target address (for the lookup table)16.48 + * @param destsize final size of the translation in bytes.16.49 + * @param srcsize size of the original data that was translated in bytes16.50 + */16.51 +void xlat_commit_block( uint32_t destsize, uint32_t srcsize );16.52 +16.53 +/**16.54 + * Delete (deactivate) the specified block from the cache. Caller is responsible16.55 + * for ensuring that there really is a block there.16.56 + */16.57 +void xlat_delete_block( xlat_cache_block_t block );16.58 +16.59 +/**16.60 + * Retrieve the entry point for the translated code corresponding to the given16.61 + * SH4 address, or NULL if there is no code for that address.16.62 + */16.63 +void *xlat_get_code( sh4addr_t address );16.64 +16.65 +/**16.66 + * Flush the code cache for the page containing the given address16.67 + */16.68 +void xlat_flush_page( sh4addr_t address );16.69 +16.70 +/**16.71 + * Flush the entire code cache. This isn't as cheap as one might like16.72 + */16.73 +void xlat_flush_cache();16.74 +16.75 +/**16.76 + * Check the internal integrity of the cache16.77 + */16.78 +void xlat_check_integrity();
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000017.2 +++ b/src/tools/actparse.c Thu Aug 23 12:33:27 2007 +000017.3 @@ -0,0 +1,123 @@17.4 +#include <stdlib.h>17.5 +#include <stdio.h>17.6 +#include <string.h>17.7 +#include <ctype.h>17.8 +#include <sys/stat.h>17.9 +#include <glib/gstrfuncs.h>17.10 +#include "tools/gendec.h"17.11 +17.12 +static int yyline;17.13 +17.14 +struct rule *new_action() {17.15 + struct action *action = malloc( sizeof( struct action ) );17.16 + memset( action, 0, sizeof( struct action ) );17.17 + return action;17.18 +}17.19 +17.20 +int add_action( struct actionset *actions, struct ruleset *rules, char *operation, char *action )17.21 +{17.22 + char *act = g_strchomp(action);17.23 +17.24 + char opclean[strlen(operation)];17.25 + char *p = operation, *q = opclean;17.26 + int i;17.27 +17.28 + // Strip c-style comments17.29 + while( *p ) {17.30 + if( *p == '/' && *(p+1) == '*' ) {17.31 + p+=2;17.32 + while( *p ) {17.33 + if( *p == '*' && *(p+1) == '/' ) {17.34 + p+=2;17.35 + break;17.36 + }17.37 + p++;17.38 + }17.39 + } else if( *p == '/' && *(p+1) == '/' ) {17.40 + p+=2;17.41 + while( *p && *p != '\n' ) {17.42 + p++;17.43 + }17.44 + } else {17.45 + *q++ = *p++;17.46 + }17.47 + }17.48 + *q = '\0';17.49 + strcpy( operation, g_strstrip(opclean) );17.50 +17.51 + for( i=0; i<rules->rule_count; i++ ) {17.52 + if( strcasecmp(rules->rules[i]->format, operation) == 0 ) {17.53 + if( actions->actions[i] != NULL ) {17.54 + fprintf( stderr, "Duplicate actions for operation '%s'\n", operation );17.55 + return -1;17.56 + }17.57 + actions->actions[i] = act;17.58 + return 0;17.59 + }17.60 + }17.61 + fprintf(stderr, "No operation found matching '%s'\n", operation );17.62 + return -1;17.63 +}17.64 +17.65 +17.66 +struct actionset *parse_action_file( struct ruleset *rules, FILE *f )17.67 +{17.68 + struct actionset *actions = malloc( sizeof(struct actionset ) );17.69 + struct stat st;17.70 + char *text;17.71 + int i, length;17.72 +17.73 + memset( actions, 0, sizeof( struct actionset ) );17.74 + /* Read whole file in (for convenience) */17.75 + fstat( fileno(f), &st );17.76 + length = st.st_size;17.77 + text = malloc( length+1 );17.78 + fread( text, length, 1, f );17.79 + text[length] = '\0';17.80 + yyline = 0;17.81 + actions->pretext = text;17.82 + for( i=0; i<length; i++ ) {17.83 + if( text[i] == '\n' ) {17.84 + yyline++;17.85 + if( i+3 < length && text[i+1] == '%' && text[i+2] == '%' ) {17.86 + text[i+1] = '\0';17.87 + i+=3;17.88 + break;17.89 + }17.90 + }17.91 + }17.92 +17.93 + char *operation = &text[i];17.94 + for( ; i<length; i++ ) {17.95 + if( text[i] == '\n' ) {17.96 + yyline++;17.97 + if( i+3 < length && text[i+1] == '%' && text[i+2] == '%' ) {17.98 + i+=3;17.99 + break;17.100 + }17.101 + }17.102 +17.103 + if( text[i] == '{' && text[i+1] == ':' ) {17.104 + text[i] = '\0';17.105 + i+=2;17.106 + char *action = &text[i];17.107 + for( ;i<length; i++ ) {17.108 + if( text[i] == ':' && text[i+1] == '}' ) {17.109 + text[i] = '\0';17.110 + i++;17.111 + if( add_action( actions, rules, operation, action ) != 0 ) {17.112 + free(actions);17.113 + free(text);17.114 + return NULL;17.115 + }17.116 + operation = &text[i+1];17.117 + break;17.118 + }17.119 + }17.120 + }17.121 + }17.122 +17.123 + actions->posttext = &text[i];17.124 +17.125 + return actions;17.126 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000018.2 +++ b/src/tools/gendec.c Thu Aug 23 12:33:27 2007 +000018.3 @@ -0,0 +1,353 @@18.4 +/**18.5 + * $Id: gendec.c,v 1.1 2007-08-23 12:33:27 nkeynes Exp $18.6 + *18.7 + * Parse the instruction and action files and generate an appropriate18.8 + * instruction decoder.18.9 + *18.10 + * Copyright (c) 2005 Nathan Keynes.18.11 + *18.12 + * This program is free software; you can redistribute it and/or modify18.13 + * it under the terms of the GNU General Public License as published by18.14 + * the Free Software Foundation; either version 2 of the License, or18.15 + * (at your option) any later version.18.16 + *18.17 + * This program is distributed in the hope that it will be useful,18.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of18.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the18.20 + * GNU General Public License for more details.18.21 + */18.22 +18.23 +#include <stdio.h>18.24 +#include <stdlib.h>18.25 +#include <string.h>18.26 +#include <getopt.h>18.27 +#include <errno.h>18.28 +#include <ctype.h>18.29 +#include <glib/gstrfuncs.h>18.30 +#include <assert.h>18.31 +#include "tools/gendec.h"18.32 +18.33 +#define DEFAULT_OUT_EXT ".c"18.34 +18.35 +const char *ins_filename = NULL;18.36 +const char *act_filename = NULL;18.37 +const char *out_filename = NULL;18.38 +18.39 +#define GEN_SOURCE 118.40 +#define GEN_TEMPLATE 218.41 +18.42 +FILE *ins_file, *act_file, *out_file;18.43 +18.44 +char *option_list = "tmho:";18.45 +int gen_mode = GEN_SOURCE;18.46 +struct option longopts[1] = { { NULL, 0, 0, 0 } };18.47 +18.48 +void usage() {18.49 + printf( "gendec <instruction-file> <action-file> [ -o <output-file> ]\n" );18.50 +}18.51 +18.52 +int main( int argc, char *argv[] )18.53 +{18.54 + int opt, i;18.55 +18.56 + /* Parse the command line */18.57 + while( (opt = getopt_long( argc, argv, option_list, longopts, NULL )) != -1 ) {18.58 + switch( opt ) {18.59 + case 't':18.60 + gen_mode = GEN_TEMPLATE;18.61 + break;18.62 + case 'o':18.63 + out_filename = optarg;18.64 + break;18.65 + case 'h':18.66 + usage();18.67 + exit(0);18.68 + }18.69 + }18.70 + if( optind < argc ) {18.71 + ins_filename = argv[optind++];18.72 + }18.73 + if( optind < argc ) {18.74 + act_filename = argv[optind++];18.75 + }18.76 +18.77 + if( optind < argc || ins_filename == NULL || act_filename == NULL ) {18.78 + usage();18.79 + exit(1);18.80 + }18.81 +18.82 + if( out_filename == NULL ) {18.83 + if( gen_mode == GEN_TEMPLATE ) {18.84 + out_filename = act_filename;18.85 + } else {18.86 + char tmp[strlen(act_filename)+1];18.87 + strcpy( tmp, act_filename);18.88 + char *c = strrchr( tmp, '.' );18.89 + if( c != NULL ) {18.90 + *c = '\0';18.91 + }18.92 + out_filename = g_strconcat( tmp, DEFAULT_OUT_EXT );18.93 + }18.94 + }18.95 +18.96 + /* Open the files */18.97 + ins_file = fopen( ins_filename, "ro" );18.98 + if( ins_file == NULL ) {18.99 + fprintf( stderr, "Unable to open '%s' for reading (%s)\n", ins_filename, strerror(errno) );18.100 + exit(2);18.101 + }18.102 +18.103 + act_file = fopen( act_filename, "ro" );18.104 + if( act_file == NULL ) {18.105 + fprintf( stderr, "Unable to open '%s' for reading (%s)\n", act_filename, strerror(errno) );18.106 + exit(3);18.107 + }18.108 +18.109 + /* Parse the input */18.110 + struct ruleset *rules = parse_ruleset_file( ins_file );18.111 + fclose( ins_file );18.112 + if( rules == NULL ) {18.113 + exit(5);18.114 + }18.115 +18.116 + struct actionset *actions = parse_action_file( rules, act_file );18.117 + fclose( act_file );18.118 + if( actions == NULL ) {18.119 + exit(6);18.120 + }18.121 +18.122 + /* Finally write out the results */18.123 + out_file = fopen( out_filename, "wo" );18.124 + if( out_file == NULL ) {18.125 + fprintf( stderr, "Unable to open '%s' for writing (%s)\n", out_filename, strerror(errno) );18.126 + exit(4);18.127 + }18.128 +18.129 + switch( gen_mode ) {18.130 + case GEN_SOURCE:18.131 + if( generate_decoder( rules, actions, out_file ) != 0 ) {18.132 + exit(7);18.133 + }18.134 + break;18.135 + case GEN_TEMPLATE:18.136 + if( generate_template( rules, actions, out_file ) != 0 ) {18.137 + exit(7);18.138 + }18.139 + break;18.140 + }18.141 + fclose( out_file );18.142 + return 0;18.143 +}18.144 +18.145 +/**18.146 + * Find a mask that can be used to split up the given rules18.147 + */18.148 +uint32_t find_mask( struct ruleset *rules, int ruleidx[], int rule_count,18.149 + uint32_t input_mask )18.150 +{18.151 + int i;18.152 + uint32_t mask = rules->rules[ruleidx[0]]->mask;18.153 +18.154 + for( i=1; i<rule_count; i++ ) {18.155 + mask = mask & rules->rules[ruleidx[i]]->mask;18.156 + }18.157 +18.158 + assert( (mask & input_mask) == input_mask ); /* input_mask should always be included in the mask */18.159 +18.160 + return mask & (~input_mask); /* but we don't want to see the input mask again */18.161 +}18.162 +18.163 +int get_option_count_for_mask( uint32_t mask ) {18.164 + int count = 0;18.165 +18.166 + while( mask ) {18.167 + if( mask&1 )18.168 + count++;18.169 + mask >>= 1;18.170 + }18.171 + return 1<<count;18.172 +}18.173 +18.174 +int get_bitshift_for_mask( uint32_t mask ) {18.175 + int shift = 0;18.176 + while( mask && !(mask&1) ) {18.177 + shift++;18.178 + mask >>= 1;18.179 + }18.180 + return shift;18.181 +}18.182 +18.183 +void get_option_values_for_mask( uint32_t *options,18.184 + uint32_t mask )18.185 +{18.186 + /* This could be a lot smarter. But it's not */18.187 + int i;18.188 + *options = 0;18.189 + for( i=1; i<=mask; i++ ) {18.190 + if( (i & mask) > *options ) {18.191 + options++;18.192 + *options = (i&mask);18.193 + }18.194 + }18.195 +}18.196 +18.197 +fprint_indent( char *action, int depth, FILE *f )18.198 +{18.199 + int spaces = 0, needed = depth*8, i;18.200 + char *text = action;18.201 +18.202 + /* Determine number of spaces in first line of input */18.203 + for( i=0; isspace(action[i]); i++ ) {18.204 + if( action[i] == '\n' ) {18.205 + spaces = 0;18.206 + text = &action[i+1];18.207 + } else {18.208 + spaces++;18.209 + }18.210 + }18.211 +18.212 + needed -= spaces;18.213 + fprintf( f, "%*c", needed, ' ' );18.214 + for( i=0; text[i] != '\0'; i++ ) {18.215 + fputc( text[i], f );18.216 + if( text[i] == '\n' && text[i+1] != '\0' ) {18.217 + fprintf( f, "%*c", needed, ' ' );18.218 + }18.219 + }18.220 + if( text[i-1] != '\n' ) {18.221 + fprintf( f, "\n" );18.222 + }18.223 +}18.224 +18.225 +fprint_action( struct rule *rule, char *action, int depth, FILE *f )18.226 +{18.227 + int i;18.228 + char tmp[64];18.229 + if( action == NULL ) {18.230 + fprintf( f, "%*cUNIMP(ir); /* %s */\n", depth*8, ' ', rule->format );18.231 + } else {18.232 + fprintf( f, "%*c{ /* %s */", depth*8, ' ', rule->format );18.233 + if( rule->operand_count != 0 ) {18.234 + fprintf( f, "\n%*c", depth*8, ' ' );18.235 + for( i=0; i<rule->operand_count; i++ ) {18.236 + if( rule->operands[i].is_signed ) {18.237 + fprintf( f, "int32_t %s = SIGNEXT%d", rule->operands[i].name, rule->operands[i].bit_count );18.238 + } else {18.239 + fprintf( f, "uint32_t %s = ", rule->operands[i].name );18.240 + }18.241 + if( rule->operands[i].bit_shift == 0 ) {18.242 + fprintf( f, "(ir&0x%X)", (1<<(rule->operands[i].bit_count))-1 );18.243 + } else {18.244 + fprintf( f, "((ir>>%d)&0x%X)", rule->operands[i].bit_shift,18.245 + (1<<(rule->operands[i].bit_count))-1 );18.246 + }18.247 + if( rule->operands[i].left_shift != 0 ) {18.248 + fprintf( f, "<<%d", rule->operands[i].left_shift );18.249 + }18.250 + fprintf( f, "; " );18.251 + }18.252 + }18.253 + fputs( "\n", f );18.254 + if( action[0] != '\0' ) {18.255 + fprint_indent( action, depth, f );18.256 + }18.257 + fprintf( f, "%*c}\n", depth*8, ' ' );18.258 + }18.259 +}18.260 +18.261 +int split_and_generate( struct ruleset *rules, struct actionset *actions,18.262 + int ruleidx[], int rule_count, int input_mask,18.263 + int depth, FILE *f ) {18.264 + char tmp[64];18.265 + uint32_t mask;18.266 + int i,j;18.267 +18.268 + if( rule_count == 0 ) {18.269 + fprintf( f, "%*cUNDEF(ir);\n", depth*8, ' ' );18.270 + } else if( rule_count == 1 ) {18.271 + fprint_action( rules->rules[ruleidx[0]], actions->actions[ruleidx[0]], depth, f );18.272 + } else {18.273 +18.274 + mask = find_mask(rules, ruleidx, rule_count, input_mask);18.275 + if( mask == 0 ) { /* No matching mask? */18.276 + fprintf( stderr, "Error: unable to find a valid bitmask (%d rules, %08X input mask)\n", rule_count, input_mask );18.277 + dump_rulesubset( rules, ruleidx, rule_count, stderr );18.278 + return -1;18.279 + }18.280 +18.281 + /* break up the rules into sub-sets, and process each sub-set.18.282 + * NB: We could do this in one pass at the cost of more complex18.283 + * data structures. For now though, this keeps it simple18.284 + */18.285 + int option_count = get_option_count_for_mask( mask );18.286 + uint32_t options[option_count];18.287 + int subruleidx[rule_count];18.288 + int subrule_count;18.289 + int mask_shift = get_bitshift_for_mask( mask );18.290 + int has_empty_options = 0;18.291 + get_option_values_for_mask( options, mask );18.292 +18.293 + if( mask_shift == 0 ) {18.294 + fprintf( f, "%*cswitch( ir&0x%X ) {\n", depth*8, ' ', mask );18.295 + } else {18.296 + fprintf( f, "%*cswitch( (ir&0x%X) >> %d ) {\n", depth*8, ' ',18.297 + mask, mask_shift);18.298 + }18.299 + for( i=0; i<option_count; i++ ) {18.300 + subrule_count = 0;18.301 + for( j=0; j<rule_count; j++ ) {18.302 + int match = rules->rules[ruleidx[j]]->bits & mask;18.303 + if( match == options[i] ) {18.304 + subruleidx[subrule_count++] = ruleidx[j];18.305 + }18.306 + }18.307 + if( subrule_count == 0 ) {18.308 + has_empty_options = 1;18.309 + } else {18.310 + fprintf( f, "%*ccase 0x%X:\n", depth*8+4, ' ', options[i]>>mask_shift );18.311 + split_and_generate( rules, actions, subruleidx, subrule_count,18.312 + mask|input_mask, depth+1, f );18.313 + fprintf( f, "%*cbreak;\n", depth*8+8, ' ' );18.314 + }18.315 + }18.316 + if( has_empty_options ) {18.317 + fprintf( f, "%*cdefault:\n%*cUNDEF();\n%*cbreak;\n",18.318 + depth*8+4, ' ', depth*8+8, ' ', depth*8 + 8, ' ' );18.319 + }18.320 + fprintf( f, "%*c}\n", depth*8, ' ' );18.321 + }18.322 +}18.323 +18.324 +int generate_decoder( struct ruleset *rules, struct actionset *actions, FILE *f )18.325 +{18.326 + int ruleidx[rules->rule_count];18.327 + int i;18.328 +18.329 + for( i=0; i<rules->rule_count; i++ ) {18.330 + ruleidx[i] = i;18.331 + }18.332 +18.333 + fputs( actions->pretext, f );18.334 +18.335 + split_and_generate( rules, actions, ruleidx, rules->rule_count, 0, 1, f );18.336 +18.337 + fputs( actions->posttext, f );18.338 +18.339 + return 0;18.340 +}18.341 +18.342 +int generate_template( struct ruleset *rules, struct actionset *actions, FILE *f )18.343 +{18.344 + int i;18.345 + fputs( actions->pretext, f );18.346 + fputs( "%%\n", f );18.347 +18.348 + for( i=0; i<rules->rule_count; i++ ) {18.349 + fprintf( f, "%s {: %s :}\n", rules->rules[i]->format,18.350 + actions->actions[i] == NULL ? "" : actions->actions[i] );18.351 + }18.352 + fputs( "%%\n", f );18.353 + fputs( actions->posttext, f );18.354 +18.355 + return 0;18.356 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000019.2 +++ b/src/tools/gendec.h Thu Aug 23 12:33:27 2007 +000019.3 @@ -0,0 +1,84 @@19.4 +/**19.5 + * $Id: gendec.h,v 1.1 2007-08-23 12:33:27 nkeynes Exp $19.6 + *19.7 + * mem is responsible for creating and maintaining the overall system memory19.8 + * map, as visible from the SH4 processor. (Note the ARM has a different map)19.9 + *19.10 + * Copyright (c) 2005 Nathan Keynes.19.11 + *19.12 + * This program is free software; you can redistribute it and/or modify19.13 + * it under the terms of the GNU General Public License as published by19.14 + * the Free Software Foundation; either version 2 of the License, or19.15 + * (at your option) any later version.19.16 + *19.17 + * This program is distributed in the hope that it will be useful,19.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of19.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the19.20 + * GNU General Public License for more details.19.21 + */19.22 +19.23 +#ifndef gendec_H19.24 +#define gendec_H19.25 +19.26 +#include <stdint.h>19.27 +19.28 +#ifdef __cplusplus19.29 +extern "C" {19.30 +#endif19.31 +19.32 +#define MAX_OPERAND_NAME 819.33 +#define MAX_OPERANDS 419.34 +#define MAX_OPERATION_FORMAT 6419.35 +#define MAX_RULES 51219.36 +19.37 +#define USE_NONE 019.38 +#define USE_READ 119.39 +#define USE_WRITE 219.40 +#define USE_READWRITE 319.41 +19.42 +struct operand {19.43 + int bit_count;19.44 + int bit_shift;19.45 + int left_shift;19.46 + int is_signed;19.47 + int use_mode;19.48 + char name[MAX_OPERAND_NAME+1];19.49 +};19.50 +19.51 +struct rule {19.52 + uint32_t bits;19.53 + uint32_t mask;19.54 + int bit_count;19.55 + int operand_count;19.56 + int flags_use_mode;19.57 + struct operand operands[MAX_OPERANDS];19.58 + char format[MAX_OPERATION_FORMAT+1];19.59 +};19.60 +19.61 +struct ruleset {19.62 + uint32_t rule_count;19.63 + struct rule *rules[MAX_RULES];19.64 +};19.65 +19.66 +struct ruleset *parse_ruleset_file( FILE *f );19.67 + void dump_ruleset( struct ruleset *rules, FILE *f );19.68 +19.69 +struct action {19.70 + char operand_names[MAX_OPERANDS][MAX_OPERAND_NAME+1];19.71 + char *body;19.72 +};19.73 +19.74 +struct actionset {19.75 + char *pretext;19.76 + char *posttext;19.77 + char *actions[MAX_RULES];19.78 +};19.79 +19.80 +struct actionset *parse_action_file( struct ruleset *rules, FILE *f );19.81 +19.82 +int generate_decoder( struct ruleset *rules, struct actionset *actions, FILE *f );19.83 +19.84 +#ifdef __cplusplus19.85 +}19.86 +#endif19.87 +#endif
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000020.2 +++ b/src/tools/insparse.c Thu Aug 23 12:33:27 2007 +000020.3 @@ -0,0 +1,224 @@20.4 +#include <stdlib.h>20.5 +#include <stdio.h>20.6 +#include <string.h>20.7 +#include <ctype.h>20.8 +#include "tools/gendec.h"20.9 +20.10 +#define CONSUME_CHAR(x) if( **str != x ) { fprintf( stderr, "Unexpected input character '%c', expected '%c' at line %d\n", **str, x, yyline ); return -1; } else { (*str)++; }20.11 +static int yyline;20.12 +20.13 +struct rule *new_rule() {20.14 + struct rule *rule = malloc( sizeof( struct rule ) );20.15 + memset( rule, 0, sizeof( struct rule ) );20.16 + return rule;20.17 +}20.18 +20.19 +struct ruleset *parse_ruleset_file( FILE *f )20.20 +{20.21 + struct ruleset *rules = malloc( sizeof(struct ruleset ) );20.22 + char buf[512];20.23 +20.24 + rules->rule_count = 0;20.25 + yyline = 0;20.26 + while( fgets( buf, sizeof(buf), f ) != NULL ) {20.27 + yyline++;20.28 + if( strncasecmp(buf, "registers", 9) == 0 ) {20.29 + parse_registers_block(buf, sizeof(buf), f);20.30 + } else if( buf[0] != '\0' && buf[0] != '#' && buf[0] != '\n' ) {20.31 + struct rule *rule;20.32 + char *p = buf;20.33 + rule = new_rule();20.34 + if( parse_rule( &p, rule ) != 0 ) {20.35 + free( rule );20.36 + } else {20.37 + rules->rules[rules->rule_count++] = rule;20.38 + }20.39 + }20.40 + }20.41 + return rules;20.42 +}20.43 +20.44 +int parse_registers_block( char *buf, int buflen, FILE *f ) {20.45 + do {20.46 + if( strchr(buf, '}') != NULL ) {20.47 + break;20.48 + }20.49 + } while( fgets( buf, buflen, f ) != NULL );20.50 +}20.51 +20.52 +/**20.53 + * Parse a single complete rule20.54 + * @return 0 on success, non-zero on failure20.55 + */20.56 +int parse_rule( char **str, struct rule *rule )20.57 +{20.58 + if( parse_bitstring( str, rule ) != 0 ) {20.59 + return -1;20.60 + }20.61 +20.62 + /* consume whitespace in between */20.63 + while( isspace(**str) ) (*str)++;20.64 + if( **str == '\0' ) {20.65 + fprintf( stderr, "Unexpected end of file in rule on line %d\n", yyline );20.66 + return -1;20.67 + }20.68 +20.69 + int result = parse_rule_format( str, rule );20.70 + if( result == 0 ) {20.71 + /* Reverse operand bit shifts */20.72 + int j;20.73 + for( j=0; j<rule->operand_count; j++ ) {20.74 + rule->operands[j].bit_shift =20.75 + rule->bit_count - rule->operands[j].bit_shift - rule->operands[j].bit_count;20.76 + }20.77 + if( **str == '!' ) {20.78 + (*str)++;20.79 + result = parse_operand_uses( str, rule );20.80 + }20.81 + }20.82 +20.83 + return 0;20.84 +}20.85 +20.86 +int parse_bitstring( char **str, struct rule *rule )20.87 +{20.88 + while( !isspace(**str) ) {20.89 + int ch = **str;20.90 + (*str)++;20.91 + switch( ch ) {20.92 + case '0':20.93 + rule->bits = rule->bits << 1;20.94 + rule->mask = (rule->mask << 1) | 1;20.95 + rule->bit_count++;20.96 + break;20.97 + case '1':20.98 + rule->bits = (rule->bits << 1) | 1;20.99 + rule->mask = (rule->mask << 1) | 1;20.100 + rule->bit_count++;20.101 + break;20.102 + case '(':20.103 + if( parse_bitoperand( str, rule ) != 0 ) {20.104 + return -1 ;20.105 + }20.106 + break;20.107 + default:20.108 + (*str)--;20.109 + fprintf( stderr, "Unexpected character '%c' in bitstring at line %d\n", ch, yyline );20.110 + return -1;20.111 + }20.112 + }20.113 + return 0;20.114 +}20.115 +20.116 +int parse_bitoperand( char **str, struct rule *rule )20.117 +{20.118 + char *p = rule->operands[rule->operand_count].name;20.119 + char tmp[8];20.120 +20.121 + if( rule->operand_count == MAX_OPERANDS ) {20.122 + fprintf( stderr, "Maximum operands/rule exceeded (%d) at line %d\n", MAX_OPERANDS, yyline );20.123 + return -1;20.124 + }20.125 +20.126 + while( isalnum(**str) || **str == '_' ) {20.127 + *p++ = *(*str)++;20.128 + }20.129 + *p = '\0';20.130 + CONSUME_CHAR(':');20.131 +20.132 + int size = parse_integer( str );20.133 + if( size == -1 ) {20.134 + return -1;20.135 + }20.136 + rule->operands[rule->operand_count].bit_count = size;20.137 + if( **str == 's' || **str == 'S' ) {20.138 + (*str)++;20.139 + rule->operands[rule->operand_count].is_signed = 1;20.140 + } else if( **str == 'u' || **str == 'U' ) {20.141 + (*str)++;20.142 + rule->operands[rule->operand_count].is_signed = 0;20.143 + }20.144 + if( **str == '<' ) {20.145 + (*str)++;20.146 + CONSUME_CHAR('<');20.147 + int lsl = parse_integer(str);20.148 + if( lsl == -1 ) {20.149 + return -1;20.150 + }20.151 + rule->operands[rule->operand_count].left_shift = lsl;20.152 + }20.153 + CONSUME_CHAR(')');20.154 +20.155 + rule->operands[rule->operand_count].bit_shift = rule->bit_count;20.156 + rule->bit_count += size;20.157 + rule->bits = rule->bits << size;20.158 + rule->mask = rule->mask << size;20.159 + rule->operand_count++;20.160 + return 0;20.161 +}20.162 +20.163 +int parse_integer( char **str )20.164 +{20.165 + uint32_t val = 0;20.166 + if( !isdigit(**str) ) {20.167 + fprintf(stderr, "Expected digit (0-9) but was '%c' at line %d\n", **str, yyline );20.168 + return -1;20.169 + }20.170 + do {20.171 + val = val * 10 + (**str - '0');20.172 + (*str)++;20.173 + } while( isdigit(**str) );20.174 + return val;20.175 +}20.176 +20.177 +int parse_rule_format( char **str, struct rule *rule )20.178 +{20.179 +20.180 + char tmp[64];20.181 + char *p = tmp;20.182 + while( **str != '\n' && **str != '\0' && **str != '!' ) {20.183 + *p++ = *(*str)++;20.184 + }20.185 + *p = '\0';20.186 + strcpy( rule->format, tmp );20.187 +20.188 + return 0;20.189 +}20.190 +20.191 +int parse_operand_uses( char **str, struct rule *rule )20.192 +{20.193 +20.194 +}20.195 +20.196 +void dump_ruleset( struct ruleset *rules, FILE *f )20.197 +{20.198 + int i, j;20.199 + fprintf( f, "Rulset: %d rules\n", rules->rule_count );20.200 + for( i=0; i<rules->rule_count; i++ ) {20.201 + struct rule *rule = rules->rules[i];20.202 + fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );20.203 + for( j=0; j<rule->operand_count; j++ ) {20.204 + fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,20.205 + rule->operands[j].is_signed ? "signed" : "unsigned",20.206 + rule->operands[j].bit_shift,20.207 + (1<<rule->operands[j].bit_count)-1 );20.208 + }20.209 + fprintf( f, "\n" );20.210 + }20.211 +}20.212 +20.213 +void dump_rulesubset( struct ruleset *rules, int ruleidx[], int rule_count, FILE *f )20.214 +{20.215 + int i,j;20.216 + for( i=0; i<rule_count; i++ ) {20.217 + struct rule *rule = rules->rules[ruleidx[i]];20.218 + fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );20.219 + for( j=0; j<rule->operand_count; j++ ) {20.220 + fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,20.221 + rule->operands[j].is_signed ? "signed" : "unsigned",20.222 + rule->operands[j].bit_shift,20.223 + (1<<rule->operands[j].bit_count)-1 );20.224 + }20.225 + fprintf( f, "\n" );20.226 + }20.227 +}
.