Search
lxdream.org :: lxdream :: r359:c588dce7ebde
lxdream 0.9.1
released Jun 29
Download Now
changeset359:c588dce7ebde
parent358:65043a8f5785
child360:dff4a3bbac0c
authornkeynes
dateThu 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
src/Makefile.am
src/Makefile.in
src/dreamcast.h
src/sh4/sh4.def
src/sh4/sh4core.c
src/sh4/sh4core.h
src/sh4/sh4core.in
src/sh4/sh4dasm.c
src/sh4/sh4dasm.in
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.c
src/sh4/sh4x86.in
src/sh4/x86op.h
src/sh4/xltcache.c
src/sh4/xltcache.h
src/tools/actparse.c
src/tools/gendec.c
src/tools/gendec.h
src/tools/insparse.c
1.1 --- a/src/Makefile.am Thu Aug 23 12:31:31 2007 +0000
1.2 +++ b/src/Makefile.am Thu Aug 23 12:33:27 2007 +0000
1.3 @@ -6,7 +6,11 @@
1.4 -Ish4 \
1.5 @PACKAGE_CFLAGS@
1.6
1.7 -bin_PROGRAMS = lxdream
1.8 +bin_PROGRAMS = gendec lxdream
1.9 +
1.10 +BUILT_SOURCES = sh4/sh4core.c sh4/sh4dasm.c sh4/sh4x86.c
1.11 +
1.12 +gendec_SOURCES = tools/gendec.c tools/gendec.h tools/insparse.c tools/actparse.c
1.13
1.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.27
1.28 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
1.29
1.30 +gendec_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)
1.31 +
1.32 +TESTS = test/testxlt
1.33 +
1.34 +check_PROGRAMS = test/testxlt
1.35 +
1.36 +test_testxlt_SOURCES = test/testxlt.c sh4/xltcache.c sh4/xltcache.h
1.37 +
1.38 AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE
1.39 +
1.40 +sh4/sh4core.c: gendec sh4/sh4.def sh4/sh4core.in
1.41 + ./gendec sh4/sh4.def sh4/sh4core.in -o sh4/sh4core.c
1.42 +sh4/sh4dasm.c: gendec sh4/sh4.def sh4/sh4dasm.in
1.43 + ./gendec sh4/sh4.def sh4/sh4dasm.in -o sh4/sh4dasm.c
1.44 +sh4/sh4x86.c: gendec sh4/sh4.def sh4/sh4x86.in
1.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 +0000
2.2 +++ b/src/Makefile.in Thu Aug 23 12:33:27 2007 +0000
2.3 @@ -140,7 +140,11 @@
2.4 @PACKAGE_CFLAGS@
2.5
2.6
2.7 -bin_PROGRAMS = lxdream
2.8 +bin_PROGRAMS = gendec lxdream
2.9 +
2.10 +BUILT_SOURCES = sh4/sh4core.c sh4/sh4dasm.c sh4/sh4x86.c
2.11 +
2.12 +gendec_SOURCES = tools/gendec.c tools/gendec.h tools/insparse.c tools/actparse.c
2.13
2.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.27
2.28 lxdream_LDADD = @PACKAGE_LIBS@ $(INTLLIBS) -lesd
2.29
2.30 +gendec_LDADD = @PACKAGE_LIBS@ $(INTLLIBS)
2.31 +
2.32 +TESTS = test/testxlt
2.33 +
2.34 +check_PROGRAMS = test/testxlt
2.35 +
2.36 +test_testxlt_SOURCES = test/testxlt.c sh4/xltcache.c sh4/xltcache.h
2.37 +
2.38 AM_CFLAGS = -D_ISOC99_SOURCE -D_BSD_SOURCE
2.39 subdir = src
2.40 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
2.41 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
2.42 CONFIG_HEADER = $(top_builddir)/config.h
2.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.48
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)dirstamp
2.77
2.78 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
2.79 depcomp = $(SHELL) $(top_srcdir)/depcomp
2.80 am__depfiles_maybe = depfiles
2.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.Po
2.136 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/xltcache.Po \
2.137 +@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po
2.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.am
2.146 -SOURCES = $(lxdream_SOURCES)
2.147 +SOURCES = $(gendec_SOURCES) $(lxdream_SOURCES) $(test_testxlt_SOURCES)
2.148
2.149 -all: all-am
2.150 +all: $(BUILT_SOURCES)
2.151 + $(MAKE) $(AM_MAKEFLAGS) all-am
2.152
2.153 .SUFFIXES:
2.154 .SUFFIXES: .c .o .obj
2.155 @@ -280,9 +312,21 @@
2.156
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) test
2.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.174
2.175 mostlyclean-compile:
2.176 -rm -f *.$(OBJEXT) core *.core
2.177 @@ -290,6 +334,7 @@
2.178 distclean-compile:
2.179 -rm -f *.tab.c
2.180
2.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.217
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.222
2.223 +gendec.o: tools/gendec.c
2.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@ fi
2.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.c
2.233 +
2.234 +gendec.obj: tools/gendec.c
2.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@ fi
2.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.c
2.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@ fi
2.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.c
2.255 +
2.256 +insparse.obj: tools/insparse.c
2.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@ fi
2.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.c
2.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@ fi
2.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.c
2.277 +
2.278 +actparse.obj: tools/actparse.c
2.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@ fi
2.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.c
2.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.295
2.296 +xltcache.o: sh4/xltcache.c
2.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@ fi
2.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.c
2.306 +
2.307 +xltcache.obj: sh4/xltcache.c
2.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@ fi
2.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.c
2.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@ fi
2.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.c
2.328 +
2.329 +sh4trans.obj: sh4/sh4trans.c
2.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@ fi
2.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.c
2.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@ fi
2.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.c
2.350 +
2.351 +sh4x86.obj: sh4/sh4x86.c
2.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@ fi
2.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.c
2.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.c
2.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@ fi
2.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.c
2.380 +
2.381 +testxlt.obj: test/testxlt.c
2.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@ fi
2.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.392
2.393 ETAGS = etags
2.394 @@ -1415,6 +1620,79 @@
2.395
2.396 distclean-tags:
2.397 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
2.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 :; fi
2.471 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
2.472
2.473 top_distdir = ..
2.474 @@ -1448,12 +1726,16 @@
2.475 fi; \
2.476 done
2.477 check-am: all-am
2.478 -check: check-am
2.479 + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
2.480 + $(MAKE) $(AM_MAKEFLAGS) check-TESTS
2.481 +check: $(BUILT_SOURCES)
2.482 + $(MAKE) $(AM_MAKEFLAGS) check-am
2.483 all-am: Makefile $(PROGRAMS)
2.484
2.485 installdirs:
2.486 $(mkinstalldirs) $(DESTDIR)$(bindir)
2.487 -install: install-am
2.488 +install: $(BUILT_SOURCES)
2.489 + $(MAKE) $(AM_MAKEFLAGS) install-am
2.490 install-exec: install-exec-am
2.491 install-data: install-data-am
2.492 uninstall: uninstall-am
2.493 @@ -1473,13 +1755,16 @@
2.494
2.495 distclean-generic:
2.496 -rm -f $(CONFIG_CLEAN_FILES)
2.497 + -rm -f test/$(am__dirstamp)
2.498
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-am
2.504
2.505 -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
2.506 +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
2.507 + mostlyclean-am
2.508
2.509 distclean: distclean-am
2.510 -rm -rf ./$(DEPDIR)
2.511 @@ -1524,17 +1809,25 @@
2.512
2.513 uninstall-am: uninstall-binPROGRAMS uninstall-info-am
2.514
2.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-am
2.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-am
2.536
2.537 +
2.538 +sh4/sh4core.c: gendec sh4/sh4.def sh4/sh4core.in
2.539 + ./gendec sh4/sh4.def sh4/sh4core.in -o sh4/sh4core.c
2.540 +sh4/sh4dasm.c: gendec sh4/sh4.def sh4/sh4dasm.in
2.541 + ./gendec sh4/sh4.def sh4/sh4dasm.in -o sh4/sh4dasm.c
2.542 +sh4/sh4x86.c: gendec sh4/sh4.def sh4/sh4x86.in
2.543 + ./gendec sh4/sh4.def sh4/sh4x86.in -o sh4/sh4x86.c
2.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 +0000
3.2 +++ b/src/dreamcast.h Thu Aug 23 12:33:27 2007 +0000
3.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 modules
3.10 @@ -30,6 +30,15 @@
3.11 #endif
3.12
3.13 #define DEFAULT_TIMESLICE_LENGTH 1000000 /* nanoseconds */
3.14 +
3.15 +#ifndef MB
3.16 +#define MB *1024*1024
3.17 +#endif
3.18 +
3.19 +#define XLAT_NEW_CACHE_SIZE 8 MB
3.20 +#define XLAT_TEMP_CACHE_SIZE 2 MB
3.21 +#define XLAT_OLD_CACHE_SIZE 8 MB
3.22 +
3.23 #define CONFIG_TYPE_NONE 0
3.24 #define CONFIG_TYPE_FILE 1
3.25 #define CONFIG_TYPE_PATH 2
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/sh4/sh4.def Thu Aug 23 12:33:27 2007 +0000
4.3 @@ -0,0 +1,236 @@
4.4 +##
4.5 +## Instruction file for the SH4 - from the SH4 manual.
4.6 +## line ::= bitpattern WHITESPACE result NEWLINE
4.7 +## bitpattern ::= { '0' | '1' | '(' operand ')' }
4.8 +## operand ::= IDENTIFIER ':' NUMBER signspec
4.9 +## signspec ::= 'u' | 's' |
4.10 +## result ::= { IDENTIFIER | NON-IDENT-CHAR }
4.11 +
4.12 +registers {
4.13 + uint32 Rm, Rn = r0..r15
4.14 + uint32 Rm_BANK, Rn_BANK = r8_bank..r15_bank
4.15 + float Frm, Frn = fr0..fr15
4.16 + float XFm, XFn = xf0..xf15
4.17 + double Drm, Drn = dr0..dr8 overlaps fr0..fr15 swapped
4.18 + double XDm, XDn = xd0..xd8 overlaps xf0..xf15 swapped
4.19 + float[4] FVm, FVn = fv0..fv3 overlaps fr0..fr15
4.20 + float[16] XMTRX = xmtrx overlaps xf0..xf15
4.21 +
4.22 +## Special registers
4.23 + uint32 GBR, SR, VBR, SSR, SGR SPC, DBR
4.24 + uint32 FPSCR, FPUL, MACH, MACL, PR, PC
4.25 +
4.26 +}
4.27 +
4.28 +0011(Rn:4)(Rm:4)1100 ADD Rm, Rn
4.29 +0111(Rn:4)(imm:8s) ADD #imm, Rn
4.30 +0011(Rn:4)(Rm:4)1110 ADDC Rm, Rn
4.31 +0011(Rn:4)(Rm:4)1111 ADDV Rm, Rn
4.32 +0010(Rn:4)(Rm:4)1001 AND Rm, Rn
4.33 +11001001(imm:8u) AND #imm, R0
4.34 +11001101(imm:8u) AND.B #imm, @(R0, GBR)
4.35 +10001011(disp:8s<<1) BF disp
4.36 +10001111(disp:8s<<1) BF/S disp
4.37 +1010(disp:12s<<1) BRA disp
4.38 +0000(Rn:4)00100011 BRAF Rn
4.39 +1011(disp:12s<<1) BSR disp
4.40 +0000(Rn:4)00000011 BSRF Rn
4.41 +10001001(disp:8s<<1) BT disp
4.42 +10001101(disp:8s<<1) BT/S disp
4.43 +0000000000101000 CLRMAC
4.44 +0000000001001000 CLRS
4.45 +0000000000001000 CLRT
4.46 +0011(Rn:4)(Rm:4)0000 CMP/EQ Rm, Rn
4.47 +10001000(imm:8s) CMP/EQ #imm, R0
4.48 +0011(Rn:4)(Rm:4)0011 CMP/GE Rm, Rn
4.49 +0011(Rn:4)(Rm:4)0111 CMP/GT Rm, Rn
4.50 +0011(Rn:4)(Rm:4)0110 CMP/HI Rm, Rn
4.51 +0011(Rn:4)(Rm:4)0010 CMP/HS Rm, Rn
4.52 +0100(Rn:4)00010101 CMP/PL Rn
4.53 +0100(Rn:4)00010001 CMP/PZ Rn
4.54 +0010(Rn:4)(Rm:4)1100 CMP/STR Rm, Rn
4.55 +0010(Rn:4)(Rm:4)0111 DIV0S Rm, Rn
4.56 +0000000000011001 DIV0U
4.57 +0011(Rn:4)(Rm:4)0100 DIV1 Rm, Rn
4.58 +0011(Rn:4)(Rm:4)1101 DMULS.L Rm, Rn
4.59 +0011(Rn:4)(Rm:4)0101 DMULU.L Rm, Rn
4.60 +0100(Rn:4)00010000 DT Rn
4.61 +0110(Rn:4)(Rm:4)1110 EXTS.B Rm, Rn
4.62 +0110(Rn:4)(Rm:4)1111 EXTS.W Rm, Rn
4.63 +0110(Rn:4)(Rm:4)1100 EXTU.B Rm, Rn
4.64 +0110(Rn:4)(Rm:4)1101 EXTU.W Rm, Rn
4.65 +1111(FRn:4)01011101 FABS FRn
4.66 +1111(FRn:4)(FRm:4)0000 FADD FRm, FRn
4.67 +1111(FRn:4)(FRm:4)0100 FCMP/EQ FRm, FRn
4.68 +1111(FRn:4)(FRm:4)0101 FCMP/GT FRm, FRn
4.69 +1111(FRm:4)10111101 FCNVDS FRm, FPUL
4.70 +1111(FRn:4)10101101 FCNVSD FPUL, FRn
4.71 +1111(FRn:4)(FRm:4)0011 FDIV FRm, FRn
4.72 +1111(FVn:2)(FVm:2)11101101 FIPR FVm, FVn
4.73 +1111(FRm:4)00011101 FLDS FRm, FPUL
4.74 +1111(FRn:4)10001101 FLDI0 FRn
4.75 +1111(FRn:4)10011101 FLDI1 FRn
4.76 +1111(FRn:4)00101101 FLOAT FPUL, FRn
4.77 +1111(FRn:4)(FRm:4)1110 FMAC FR0, FRm, FRn
4.78 +1111(FRn:4)(FRm:4)1100 FMOV FRm, FRn
4.79 +1111(Rn:4)(FRm:4)1010 FMOV FRm, @Rn
4.80 +1111(Rn:4)(FRm:4)1011 FMOV FRm, @-Rn
4.81 +1111(Rn:4)(FRm:4)0111 FMOV FRm, @(R0, Rn)
4.82 +1111(FRn:4)(Rm:4)1000 FMOV @Rm, FRn
4.83 +1111(FRn:4)(Rm:4)1001 FMOV @Rm+, FRn
4.84 +1111(FRn:4)(Rm:4)0110 FMOV @(R0, Rm), FRn
4.85 +1111(FRn:4)(FRm:4)0010 FMUL FRm, FRn
4.86 +1111(FRn:4)01001101 FNEG FRn
4.87 +1111101111111101 FRCHG
4.88 +1111(FRn:3<<1)011111101 FSCA FPUL, FRn
4.89 +1111001111111101 FSCHG
4.90 +1111(FRn:4)01101101 FSQRT FRn
4.91 +1111(FRn:4)01111101 FSRRA FRn
4.92 +1111(FRn:4)00001101 FSTS FPUL, FRn
4.93 +1111(FRn:4)(FRm:4)0001 FSUB FRm, FRn
4.94 +1111(FRm:4)00111101 FTRC FRm, FPUL
4.95 +1111(FVn:2)0111111101 FTRV XMTRX, FVn
4.96 +0100(Rn:4)00101011 JMP @Rn
4.97 +0100(Rn:4)00001011 JSR @Rn
4.98 +0100(Rm:4)00011110 LDC Rm, GBR
4.99 +0100(Rm:4)00001110 LDC Rm, SR
4.100 +0100(Rm:4)00101110 LDC Rm, VBR
4.101 +0100(Rm:4)00111110 LDC Rm, SSR
4.102 +0100(Rm:4)00111010 LDC Rm, SGR
4.103 +0100(Rm:4)01001110 LDC Rm, SPC
4.104 +0100(Rm:4)11111010 LDC Rm, DBR
4.105 +0100(Rm:4)1(Rn_BANK:3)1110 LDC Rm, Rn_BANK
4.106 +0100(Rm:4)00010111 LDC.L @Rm+, GBR
4.107 +0100(Rm:4)00000111 LDC.L @Rm+, SR
4.108 +0100(Rm:4)00100111 LDC.L @Rm+, VBR
4.109 +0100(Rm:4)00110111 LDC.L @Rm+, SSR
4.110 +0100(Rm:4)00110110 LDC.L @Rm+, SGR
4.111 +0100(Rm:4)01000111 LDC.L @Rm+, SPC
4.112 +0100(Rm:4)11110110 LDC.L @Rm+, DBR
4.113 +0100(Rm:4)1(Rn_BANK:3)0111 LDC.L @Rm+, Rn_BANK
4.114 +0100(Rm:4)01101010 LDS Rm, FPSCR
4.115 +0100(Rm:4)01100110 LDS.L @Rm+, FPSCR
4.116 +0100(Rm:4)01011010 LDS Rm, FPUL
4.117 +0100(Rm:4)01010110 LDS.L @Rm+, FPUL
4.118 +0100(Rm:4)00001010 LDS Rm, MACH
4.119 +0100(Rm:4)00000110 LDS.L @Rm+, MACH
4.120 +0100(Rm:4)00011010 LDS Rm, MACL
4.121 +0100(Rm:4)00010110 LDS.L @Rm+, MACL
4.122 +0100(Rm:4)00101010 LDS Rm, PR
4.123 +0100(Rm:4)00100110 LDS.L @Rm+, PR
4.124 +0000000000111000 LDTLB
4.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, Rn
4.128 +1110(Rn:4)(imm:8s) MOV #imm, Rn
4.129 +0010(Rn:4)(Rm:4)0000 MOV.B Rm, @Rn
4.130 +0010(Rn:4)(Rm:4)0100 MOV.B Rm, @-Rn
4.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, Rn
4.135 +0110(Rn:4)(Rm:4)0100 MOV.B @Rm+, Rn
4.136 +0000(Rn:4)(Rm:4)1100 MOV.B @(R0, Rm), Rn
4.137 +11000100(disp:8) MOV.B @(disp, GBR), R0
4.138 +10000100(Rm:4)(disp:4) MOV.B @(disp, Rm), R0
4.139 +0010(Rn:4)(Rm:4)0010 MOV.L Rm, @Rn
4.140 +0010(Rn:4)(Rm:4)0110 MOV.L Rm, @-Rn
4.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, Rn
4.145 +0110(Rn:4)(Rm:4)0110 MOV.L @Rm+, Rn
4.146 +0000(Rn:4)(Rm:4)1110 MOV.L @(R0, Rm), Rn
4.147 +11000110(disp:8<<2) MOV.L @(disp, GBR), R0
4.148 +1101(Rn:4)(disp:8<<2) MOV.L @(disp, PC), Rn
4.149 +0101(Rn:4)(Rm:4)(disp:4<<2) MOV.L @(disp, Rm), Rn
4.150 +0010(Rn:4)(Rm:4)0001 MOV.W Rm, @Rn
4.151 +0010(Rn:4)(Rm:4)0101 MOV.W Rm, @-Rn
4.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, Rn
4.156 +0110(Rn:4)(Rm:4)0101 MOV.W @Rm+, Rn
4.157 +0000(Rn:4)(Rm:4)1101 MOV.W @(R0, Rm), Rn
4.158 +11000101(disp:8<<1) MOV.W @(disp, GBR), R0
4.159 +1001(Rn:4)(disp:8<<1) MOV.W @(disp, PC), Rn
4.160 +10000101(Rm:4)(disp:4<<1) MOV.W @(disp, Rm), R0
4.161 +11000111(disp:8<<2) MOVA @(disp, PC), R0
4.162 +0000(Rn:4)11000011 MOVCA.L R0, @Rn
4.163 +0000(Rn:4)00101001 MOVT Rn
4.164 +0000(Rn:4)(Rm:4)0111 MUL.L Rm, Rn
4.165 +0010(Rn:4)(Rm:4)1111 MULS.W Rm, Rn
4.166 +0010(Rn:4)(Rm:4)1110 MULU.W Rm, Rn
4.167 +0110(Rn:4)(Rm:4)1011 NEG Rm, Rn
4.168 +0110(Rn:4)(Rm:4)1010 NEGC Rm, Rn
4.169 +0000000000001001 NOP
4.170 +0110(Rn:4)(Rm:4)0111 NOT Rm, Rn
4.171 +0000(Rn:4)10010011 OCBI @Rn
4.172 +0000(Rn:4)10100011 OCBP @Rn
4.173 +0000(Rn:4)10110011 OCBWB @Rn
4.174 +0010(Rn:4)(Rm:4)1011 OR Rm, Rn
4.175 +11001011(imm:8) OR #imm, R0
4.176 +11001111(imm:8) OR.B #imm, @(R0, GBR)
4.177 +0000(Rn:4)10000011 PREF @Rn
4.178 +0100(Rn:4)00100100 ROTCL Rn
4.179 +0100(Rn:4)00100101 ROTCR Rn
4.180 +0100(Rn:4)00000100 ROTL Rn
4.181 +0100(Rn:4)00000101 ROTR Rn
4.182 +0000000000101011 RTE
4.183 +0000000000001011 RTS
4.184 +0000000001011000 SETS
4.185 +0000000000011000 SETT
4.186 +0100(Rn:4)(Rm:4)1100 SHAD Rm, Rn
4.187 +0100(Rn:4)00100000 SHAL Rn
4.188 +0100(Rn:4)00100001 SHAR Rn
4.189 +0100(Rn:4)(Rm:4)1101 SHLD Rm, Rn
4.190 +0100(Rn:4)00000000 SHLL Rn
4.191 +0100(Rn:4)00001000 SHLL2 Rn
4.192 +0100(Rn:4)00011000 SHLL8 Rn
4.193 +0100(Rn:4)00101000 SHLL16 Rn
4.194 +0100(Rn:4)00000001 SHLR Rn
4.195 +0100(Rn:4)00001001 SHLR2 Rn
4.196 +0100(Rn:4)00011001 SHLR8 Rn
4.197 +0100(Rn:4)00101001 SHLR16 Rn
4.198 +0000000000011011 SLEEP
4.199 +0000(Rn:4)00000010 STC SR, Rn
4.200 +0000(Rn:4)00010010 STC GBR, Rn
4.201 +0000(Rn:4)00100010 STC VBR, Rn
4.202 +0000(Rn:4)00110010 STC SSR, Rn
4.203 +0000(Rn:4)01000010 STC SPC, Rn
4.204 +0000(Rn:4)00111010 STC SGR, Rn
4.205 +0000(Rn:4)11111010 STC DBR, Rn
4.206 +0000(Rn:4)1(Rm_BANK:3)0010 STC Rm_BANK, Rn
4.207 +0100(Rn:4)00000011 STC.L SR, @-Rn
4.208 +0100(Rn:4)00100011 STC.L VBR, @-Rn
4.209 +0100(Rn:4)00110011 STC.L SSR, @-Rn
4.210 +0100(Rn:4)01000011 STC.L SPC, @-Rn
4.211 +0100(Rn:4)00110010 STC.L SGR, @-Rn
4.212 +0100(Rn:4)11110010 STC.L DBR, @-Rn
4.213 +0100(Rn:4)1(Rm_BANK:3)0011 STC.L Rm_BANK, @-Rn
4.214 +0100(Rn:4)00010011 STC.L GBR, @-Rn
4.215 +0000(Rn:4)01101010 STS FPSCR, Rn
4.216 +0100(Rn:4)01100010 STS.L FPSCR, @-Rn
4.217 +0000(Rn:4)01011010 STS FPUL, Rn
4.218 +0100(Rn:4)01010010 STS.L FPUL, @-Rn
4.219 +0000(Rn:4)00001010 STS MACH, Rn
4.220 +0100(Rn:4)00000010 STS.L MACH, @-Rn
4.221 +0000(Rn:4)00011010 STS MACL, Rn
4.222 +0100(Rn:4)00010010 STS.L MACL, @-Rn
4.223 +0000(Rn:4)00101010 STS PR, Rn
4.224 +0100(Rn:4)00100010 STS.L PR, @-Rn
4.225 +0011(Rn:4)(Rm:4)1000 SUB Rm, Rn
4.226 +0011(Rn:4)(Rm:4)1010 SUBC Rm, Rn
4.227 +0011(Rn:4)(Rm:4)1011 SUBV Rm, Rn
4.228 +0110(Rn:4)(Rm:4)1000 SWAP.B Rm, Rn
4.229 +0110(Rn:4)(Rm:4)1001 SWAP.W Rm, Rn
4.230 +0100(Rn:4)00011011 TAS.B @Rn
4.231 +11000011(imm:8) TRAPA #imm
4.232 +0010(Rn:4)(Rm:4)1000 TST Rm, Rn
4.233 +11001000(imm:8) TST #imm, R0
4.234 +11001100(imm:8) TST.B #imm, @(R0, GBR)
4.235 +0010(Rn:4)(Rm:4)1010 XOR Rm, Rn
4.236 +11001010(imm:8) XOR #imm, R0
4.237 +11001110(imm:8) XOR.B #imm, @(R0, GBR)
4.238 +0010(Rn:4)(Rm:4)1101 XTRCT Rm, Rn
4.239 +1111111111111101 UNDEF
5.1 --- a/src/sh4/sh4core.c Thu Aug 23 12:31:31 2007 +0000
5.2 +++ b/src/sh4/sh4core.c Thu Aug 23 12:33:27 2007 +0000
5.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 peripheral
5.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.16
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.22
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.27
5.28 @@ -415,7 +415,7 @@
5.29 RAISE( code, EXV_TLBMISS );
5.30 }
5.31
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.44
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 some
5.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 + else
5.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 some
5.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 things
5.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 + else
5.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 + else
5.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 + else
5.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 + else
5.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.2259
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 - else
5.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 - else
5.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 - else
5.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 - else
5.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 - else
5.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 accurate
5.3072 - * as the SH4 instruction is less precise. Also
5.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 +0000
6.2 +++ b/src/sh4/sh4core.h Thu Aug 23 12:33:27 2007 +0000
6.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.h
6.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.23
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.27
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.39
6.40 #define EX_ILLEGAL_INSTRUCTION 0x180, 0x100
6.41 @@ -198,3 +202,4 @@
6.42 }
6.43 #endif
6.44 #endif
6.45 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/sh4/sh4core.in Thu Aug 23 12:33:27 2007 +0000
7.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 peripheral
7.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 modify
7.13 + * it under the terms of the GNU General Public License as published by
7.14 + * the Free Software Foundation; either version 2 of the License, or
7.15 + * (at your option) any later version.
7.16 + *
7.17 + * This program is distributed in the hope that it will be useful,
7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.20 + * GNU General Public License for more details.
7.21 + */
7.22 +
7.23 +#define MODULE sh4_module
7.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 1
7.34 +
7.35 +#define MAX_INT 0x7FFFFFFF
7.36 +#define MIN_INT 0x80000000
7.37 +#define MAX_INTF 2147483647.0
7.38 +#define MIN_INTF -2147483648.0
7.39 +
7.40 +/* CPU-generated exception code/vector pairs */
7.41 +#define EXC_POWER_RESET 0x000 /* vector special */
7.42 +#define EXC_MANUAL_RESET 0x020
7.43 +#define EXC_READ_ADDR_ERR 0x0E0
7.44 +#define EXC_WRITE_ADDR_ERR 0x100
7.45 +#define EXC_SLOT_ILLEGAL 0x1A0
7.46 +#define EXC_ILLEGAL 0x180
7.47 +#define EXC_TRAP 0x160
7.48 +#define EXC_FPDISABLE 0x800
7.49 +#define EXC_SLOT_FPDISABLE 0x820
7.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_MODE
7.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 +#endif
7.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 we
7.203 + * actually executed
7.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 32
7.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 +#else
7.292 +#define TRACE_CALL( dest, rts )
7.293 +#define TRACE_RETURN( source, dest )
7.294 +#endif
7.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 IO
7.461 + * region, fallback on the full-blown memory read
7.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 + else
7.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 some
7.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 + else
7.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 + else
7.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 + else
7.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 + else
7.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 +0000
8.2 +++ b/src/sh4/sh4dasm.c Thu Aug 23 12:33:27 2007 +0000
8.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 functions
8.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.21
8.22 sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );
8.23
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 }
8.1815
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/sh4/sh4dasm.in Thu Aug 23 12:33:27 2007 +0000
9.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 functions
9.8 + *
9.9 + * Copyright (c) 2005 Nathan Keynes.
9.10 + *
9.11 + * This program is free software; you can redistribute it and/or modify
9.12 + * it under the terms of the GNU General Public License as published by
9.13 + * the Free Software Foundation; either version 2 of the License, or
9.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 of
9.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.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 +0000
10.2 +++ b/src/sh4/sh4trans.c Thu Aug 23 12:33:27 2007 +0000
10.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-specific
10.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 modify
10.13 + * it under the terms of the GNU General Public License as published by
10.14 + * the Free Software Foundation; either version 2 of the License, or
10.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 of
10.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.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 breakpoints
10.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 we
10.64 + * actually executed
10.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 address
10.80 + * (inclusive) until the next branch/jump instruction or the end of the page
10.81 + * is reached.
10.82 + * @return the address of the translated block
10.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 +0000
11.2 +++ b/src/sh4/sh4trans.h Thu Aug 23 12:33:27 2007 +0000
11.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 module
11.8 + *
11.9 + * Copyright (c) 2005 Nathan Keynes.
11.10 + *
11.11 + * This program is free software; you can redistribute it and/or modify
11.12 + * it under the terms of the GNU General Public License as published by
11.13 + * the Free Software Foundation; either version 2 of the License, or
11.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 of
11.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.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 potentially
11.26 + * writing the entire epilogue
11.27 + */
11.28 +#define MAX_INSTRUCTION_SIZE 32
11.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 start
11.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 +0000
12.2 +++ b/src/sh4/sh4x86.c Thu Aug 23 12:33:27 2007 +0000
12.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 just
12.8 + * outputs straight-line x86 code - it mainly exists to provide a baseline
12.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 modify
12.14 + * it under the terms of the GNU General Public License as published by
12.15 + * the Free Software Foundation; either version 2 of the License, or
12.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 of
12.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.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 register
12.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 register
12.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 save
12.83 + * SI/DI as required
12.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, etc
12.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 specially
12.108 + * by translating both branch and delayed instruction as a single unit (as
12.109 + *
12.110 + *
12.111 + * @return true if the instruction marks the end of a basic block
12.112 + * (eg a branch or
12.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. So
12.1524 + // need to use the imm32 version
12.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 +0000
13.2 +++ b/src/sh4/sh4x86.in Thu Aug 23 12:33:27 2007 +0000
13.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 just
13.8 + * outputs straight-line x86 code - it mainly exists to provide a baseline
13.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 modify
13.14 + * it under the terms of the GNU General Public License as published by
13.15 + * the Free Software Foundation; either version 2 of the License, or
13.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 of
13.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.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 register
13.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 register
13.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 save
13.83 + * SI/DI as required
13.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, etc
13.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 specially
13.108 + * by translating both branch and delayed instruction as a single unit (as
13.109 + *
13.110 + *
13.111 + * @return true if the instruction marks the end of a basic block
13.112 + * (eg a branch or
13.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. So
13.154 + // need to use the imm32 version
13.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 +0000
14.2 +++ b/src/sh4/x86op.h Thu Aug 23 12:33:27 2007 +0000
14.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 modify
14.12 + * it under the terms of the GNU General Public License as published by
14.13 + * the Free Software Foundation; either version 2 of the License, or
14.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 of
14.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.19 + * GNU General Public License for more details.
14.20 + */
14.21 +
14.22 +#ifndef __lxdream_x86op_H
14.23 +#define __lxdream_x86op_H
14.24 +
14.25 +#define R_NONE -1
14.26 +#define R_EAX 0
14.27 +#define R_ECX 1
14.28 +#define R_EDX 2
14.29 +#define R_EBX 3
14.30 +#define R_ESP 4
14.31 +#define R_EBP 5
14.32 +#define R_ESI 6
14.33 +#define R_EDI 7
14.34 +
14.35 +#define R_AL 0
14.36 +#define R_CL 1
14.37 +#define R_DL 2
14.38 +#define R_BL 3
14.39 +#define R_AH 4
14.40 +#define R_CH 5
14.41 +#define R_DH 6
14.42 +#define R_BH 7
14.43 +
14.44 +
14.45 +#define OP(x) *xlat_output++ = x
14.46 +#define OP32(x) *((uint32_t *)xlat_output) = x; xlat_output+=2
14.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)+4
14.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 x86
14.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 +0000
15.2 +++ b/src/sh4/xltcache.c Thu Aug 23 12:33:27 2007 +0000
15.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 modify
15.12 + * it under the terms of the GNU General Public License as published by
15.13 + * the Free Software Foundation; either version 2 of the License, or
15.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 of
15.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15.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 12
15.28 +#define XLAT_LUT_TOTAL_BITS 28
15.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 *)0
15.37 +#define XLAT_LUT_ENTRY_USED (void *)1
15.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 32
15.45 +#define MIN_TOTAL_SIZE (sizeof(struct xlat_cache_block)+MIN_BLOCK_SIZE)
15.46 +
15.47 +#define BLOCK_INACTIVE 0
15.48 +#define BLOCK_ACTIVE 1
15.49 +#define BLOCK_USED 2
15.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 state
15.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 data
15.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 the
15.173 + * top of the cache
15.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 identical
15.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 the
15.213 + * top of the cache
15.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 the
15.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 +0000
16.2 +++ b/src/sh4/xltcache.h Thu Aug 23 12:33:27 2007 +0000
16.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 modify
16.12 + * it under the terms of the GNU General Public License as published by
16.13 + * the Free Software Foundation; either version 2 of the License, or
16.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 of
16.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16.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 the
16.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 block
16.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 bytes
16.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 responsible
16.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 given
16.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 address
16.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 like
16.72 + */
16.73 +void xlat_flush_cache();
16.74 +
16.75 +/**
16.76 + * Check the internal integrity of the cache
16.77 + */
16.78 +void xlat_check_integrity();
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/tools/actparse.c Thu Aug 23 12:33:27 2007 +0000
17.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 comments
17.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 +0000
18.2 +++ b/src/tools/gendec.c Thu Aug 23 12:33:27 2007 +0000
18.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 appropriate
18.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 modify
18.13 + * it under the terms of the GNU General Public License as published by
18.14 + * the Free Software Foundation; either version 2 of the License, or
18.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 of
18.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18.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 1
18.40 +#define GEN_TEMPLATE 2
18.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 rules
18.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 complex
18.283 + * data structures. For now though, this keeps it simple
18.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 +0000
19.2 +++ b/src/tools/gendec.h Thu Aug 23 12:33:27 2007 +0000
19.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 memory
19.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 modify
19.13 + * it under the terms of the GNU General Public License as published by
19.14 + * the Free Software Foundation; either version 2 of the License, or
19.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 of
19.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19.20 + * GNU General Public License for more details.
19.21 + */
19.22 +
19.23 +#ifndef gendec_H
19.24 +#define gendec_H
19.25 +
19.26 +#include <stdint.h>
19.27 +
19.28 +#ifdef __cplusplus
19.29 +extern "C" {
19.30 +#endif
19.31 +
19.32 +#define MAX_OPERAND_NAME 8
19.33 +#define MAX_OPERANDS 4
19.34 +#define MAX_OPERATION_FORMAT 64
19.35 +#define MAX_RULES 512
19.36 +
19.37 +#define USE_NONE 0
19.38 +#define USE_READ 1
19.39 +#define USE_WRITE 2
19.40 +#define USE_READWRITE 3
19.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 __cplusplus
19.85 +}
19.86 +#endif
19.87 +#endif
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/src/tools/insparse.c Thu Aug 23 12:33:27 2007 +0000
20.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 rule
20.54 + * @return 0 on success, non-zero on failure
20.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 +}
.