* Initial Device Support
authorIan Carmichael <iancarm@cygnus>
Fri, 16 Jan 1998 19:27:02 +0000 (19:27 +0000)
committerIan Carmichael <iancarm@cygnus>
Fri, 16 Jan 1998 19:27:02 +0000 (19:27 +0000)
*
*Modified Files:
*    .Sanitize ChangeLog
*Added Files:
*    Makefile.in README.Cygnus config.in configure configure.in
*    device.c device.h dma.c dma.h engine-sky.c gencode.c gpuif.c
*    gpuif.h hardware.c hardware.h interp.c m16.igen mdmx.igen
*    mips.dc mips.igen pke0.c pke0.h pke1.c pke1.h r5900.igen
*    sim-main.h tconfig.in vr5400.igen vu0.c vu0.h vu1.c vu1.h

34 files changed:
sim/txvu/.Sanitize
sim/txvu/ChangeLog
sim/txvu/Makefile.in [new file with mode: 0644]
sim/txvu/README.Cygnus [new file with mode: 0644]
sim/txvu/config.in [new file with mode: 0644]
sim/txvu/configure [new file with mode: 0755]
sim/txvu/configure.in [new file with mode: 0644]
sim/txvu/device.c [new file with mode: 0644]
sim/txvu/device.h [new file with mode: 0644]
sim/txvu/dma.c [new file with mode: 0644]
sim/txvu/dma.h [new file with mode: 0644]
sim/txvu/engine-sky.c [new file with mode: 0644]
sim/txvu/gencode.c [new file with mode: 0644]
sim/txvu/gpuif.c [new file with mode: 0644]
sim/txvu/gpuif.h [new file with mode: 0644]
sim/txvu/hardware.c [new file with mode: 0644]
sim/txvu/hardware.h [new file with mode: 0644]
sim/txvu/interp.c [new file with mode: 0644]
sim/txvu/m16.igen [new file with mode: 0644]
sim/txvu/mdmx.igen [new file with mode: 0644]
sim/txvu/mips.dc [new file with mode: 0644]
sim/txvu/mips.igen [new file with mode: 0644]
sim/txvu/pke0.c [new file with mode: 0644]
sim/txvu/pke0.h [new file with mode: 0644]
sim/txvu/pke1.c [new file with mode: 0644]
sim/txvu/pke1.h [new file with mode: 0644]
sim/txvu/r5900.igen [new file with mode: 0644]
sim/txvu/sim-main.h [new file with mode: 0644]
sim/txvu/tconfig.in [new file with mode: 0644]
sim/txvu/vr5400.igen [new file with mode: 0644]
sim/txvu/vu0.c [new file with mode: 0644]
sim/txvu/vu0.h [new file with mode: 0644]
sim/txvu/vu1.c [new file with mode: 0644]
sim/txvu/vu1.h [new file with mode: 0644]

index eecd57e..362eae0 100644 (file)
@@ -25,6 +25,38 @@ Do-first:
 Things-to-keep:
 
 ChangeLog
+interp.c
+configure.in
+Makefile.in
+config.in
+tconfig.in
+README.Cygnus
+configure
+gencode.c
+m16.igen
+mdmx.igen
+mips.dc
+mips.igen
+r5900.igen
+sim-main.h
+vr5400.igen
+engine-sky.c
+gpuif.h
+dma.h
+device.c
+gpuif.c
+device.h
+dma.c
+vu0.h
+pke0.h
+vu1.h
+pke1.h
+vu1.c
+vu0.c
+pke0.c
+pke1.c
+hardware.c
+hardware.h
 
 Things-to-lose:
 
index 1aea3ea..f6c8673 100644 (file)
@@ -1,3 +1,7 @@
+Fri Jan 16 14:25:54 1998  Ian Carmichael  <iancarm@cygnus.com>
+
+       * Initial Device Support
+
 Thu Jan 15 10:25:54 1998  Ian Carmichael  <iancarm@cygnus.com>
 
        * ChangeLog created
diff --git a/sim/txvu/Makefile.in b/sim/txvu/Makefile.in
new file mode 100644 (file)
index 0000000..006e440
--- /dev/null
@@ -0,0 +1,260 @@
+# template for Configure for the MIPS simulator.
+#    Written by Cygnus Support.
+
+## COMMON_PRE_CONFIG_FRAG
+
+srcdir=@srcdir@
+srcroot=$(srcdir)/../../
+
+SIM_NO_OBJ =
+
+SIM_IGEN_OBJ = \
+       support.o \
+       itable.o \
+       semantics.o \
+       idecode.o \
+       icache.o \
+       irun.o
+
+SIM_M16_OBJ = \
+       $(SIM_IGEN_OBJ) = \
+       m16_support.o \
+       m16_itable.o \
+       m16_semantics.o \
+       m16_idecode.o \
+       m16_icache.o \
+       m16_engine.o \
+       m16_irun.o
+
+SIM_OBJS = \
+       $(SIM_@sim_gen@_OBJ) \
+       $(SIM_NEW_COMMON_OBJS) \
+       engine-sky.o \
+       interp.o \
+       hardware.o \
+       device.o \
+       gpuif.o \
+       dma.o \
+       vu0.o \
+       vu1.o \
+       pke0.o \
+       pke1.o \
+       sim-hload.o \
+       sim-engine.o \
+       sim-stop.o \
+       sim-resume.o \
+       sim-reason.o
+
+
+# List of flags to always pass to $(CC).
+SIM_SUBTARGET=@SIM_SUBTARGET@
+
+SIM_NO_CFLAGS = -DWITH_IGEN=0
+SIM_IGEN_CFLAGS = -DWITH_IGEN=1
+SIM_M16_CFLAGS = -DWITH_IGEN=1
+
+# FIXME: Hack to find syscall.h?  Better support for syscall.h
+# is in progress.
+SIM_EXTRA_CFLAGS = \
+       $(SIM_SUBTARGET) \
+       -I$(srcdir)/../../newlib/libc/sys/idt \
+       $(SIM_@sim_gen@_CFLAGS)
+
+SIM_EXTRA_CLEAN = clean-igen clean-m16 clean-extra
+
+SIM_EXTRA_ALL = $(SIM_@sim_gen@_ALL)
+
+# List of main object files for `run'.
+SIM_RUN_OBJS = nrun.o
+
+
+
+## COMMON_POST_CONFIG_FRAG
+
+interp.o: $(srcdir)/interp.c config.h sim-main.h oengine.c
+
+oengine.c: gencode
+       ./gencode @SIMCONF@ > tmp-oengine
+       mv tmp-oengine oengine.c
+
+gencode: gencode.o getopt.o getopt1.o
+       $(CC_FOR_BUILD) -o $@ gencode.o getopt.o getopt1.o
+
+gencode.o: $(srcdir)/gencode.c
+       $(CC_FOR_BUILD) -c -g -I${srcroot}/include $(srcdir)/gencode.c
+
+getopt.o: $(srcdir)/../../libiberty/getopt.c
+       $(CC_FOR_BUILD) -c -g -I${srcroot}/include $(srcdir)/../../libiberty/getopt.c
+getopt1.o: $(srcdir)/../../libiberty/getopt1.c
+       $(CC_FOR_BUILD) -c -g -I${srcroot}/include $(srcdir)/../../libiberty/getopt1.c
+
+
+../igen/igen:
+       cd ../igen && $(MAKE)
+
+IGEN_TRACE= # -G omit-line-numbers # -G trace-rule-selection -G trace-rule-rejection -G trace-entries
+IGEN_INSN=$(srcdir)/mips.igen
+IGEN_DC=$(srcdir)/mips.dc
+IGEN_INCLUDE=\
+       $(start-sanitize-r5900) \
+       $(srcdir)/r5900.igen \
+       $(end-sanitize-r5900) \
+       $(start-sanitize-vr5400) \
+       $(srcdir)/vr5400.igen \
+       $(srcdir)/mdmx.igen \
+       $(end-sanitize-vr5400) \
+       $(srcdir)/m16.igen
+
+SIM_IGEN_ALL = tmp-igen
+
+BUILT_SRC_FROM_IGEN = \
+       icache.h \
+       icache.c \
+       idecode.h \
+       idecode.c \
+       semantics.h \
+       semantics.c \
+       model.h \
+       model.c \
+       support.h \
+       support.c \
+       itable.h \
+       itable.c \
+       engine.h \
+       engine.c \
+       irun.c
+
+$(BUILT_SRC_FROM_IGEN): tmp-igen
+
+.PHONY: clean-igen
+clean-igen:
+       rm -f $(BUILT_SRC_FROM_IGEN)
+       rm -f tmp-igen
+
+tmp-igen: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+       cd ../igen && $(MAKE)
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               @sim_igen_flags@ \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -i $(IGEN_INSN) \
+               -o $(IGEN_DC) \
+               -x \
+               -n icache.h    -hc tmp-icache.h \
+               -n icache.c    -c  tmp-icache.c \
+               -n semantics.h -hs tmp-semantics.h \
+               -n semantics.c -s  tmp-semantics.c \
+               -n idecode.h   -hd tmp-idecode.h \
+               -n idecode.c   -d  tmp-idecode.c \
+               -n model.h     -hm tmp-model.h \
+               -n model.c     -m  tmp-model.c \
+               -n support.h   -hf tmp-support.h \
+               -n support.c   -f  tmp-support.c \
+               -n itable.h    -ht tmp-itable.h \
+               -n itable.c    -t  tmp-itable.c \
+               -n engine.h    -he tmp-engine.h \
+               -n engine.c    -e  tmp-engine.c \
+               -n irun.c      -r  tmp-irun.c
+       $(srcdir)/../../move-if-change tmp-icache.h icache.h
+       $(srcdir)/../../move-if-change tmp-icache.c icache.c
+       $(srcdir)/../../move-if-change tmp-idecode.h idecode.h
+       $(srcdir)/../../move-if-change tmp-idecode.c idecode.c
+       $(srcdir)/../../move-if-change tmp-semantics.h semantics.h
+       $(srcdir)/../../move-if-change tmp-semantics.c semantics.c
+       $(srcdir)/../../move-if-change tmp-model.h model.h
+       $(srcdir)/../../move-if-change tmp-model.c model.c
+       $(srcdir)/../../move-if-change tmp-support.h support.h
+       $(srcdir)/../../move-if-change tmp-support.c support.c
+       $(srcdir)/../../move-if-change tmp-itable.h itable.h
+       $(srcdir)/../../move-if-change tmp-itable.c itable.c
+       $(srcdir)/../../move-if-change tmp-engine.h engine.h
+       $(srcdir)/../../move-if-change tmp-engine.c engine.c
+       $(srcdir)/../../move-if-change tmp-irun.c irun.c
+       touch tmp-igen
+
+semantics.o: sim-main.h $(SIM_EXTRA_DEPS)
+engine.o: sim-main.h $(SIM_EXTRA_DEPS)
+support.o: sim-main.h $(SIM_EXTRA_DEPS)
+idecode.o: sim-main.h $(SIM_EXTRA_DEPS)
+itable.o: sim-main.h $(SIM_EXTRA_DEPS)
+
+
+
+SIM_M16_ALL = tmp-igen $(SIM_M16_ALL) 
+
+BUILT_SRC_FROM_M16 = \
+       m16_icache.h \
+       m16_icache.c \
+       m16_idecode.h \
+       m16_idecode.c \
+       m16_semantics.h \
+       m16_semantics.c \
+       m16_model.h \
+       m16_model.c \
+       m16_support.h \
+       m16_support.c \
+       m16_itable.h \
+       m16_itable.c \
+       m16_engine.h \
+       m16_engine.c \
+       m16_irun.c
+
+$(BUILT_SRC_FROM_M16): tmp-m16
+
+.PHONY: clean-m16
+clean-m16:
+       rm -f $(BUILT_SRC_FROM_M16)
+       rm -f tmp-m16
+
+tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+       cd ../igen && $(MAKE)
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               -F 16 \
+               -M mips16 \
+               -G gen-direct-access \
+               -i $(IGEN_INSN) \
+               -o $(IGEN_DC) \
+               -x \
+               -n m16_icache.h    -hc tmp-icache.h \
+               -n m16_icache.c    -c  tmp-icache.c \
+               -n m16_semantics.h -hs tmp-semantics.h \
+               -n m16_semantics.c -s  tmp-semantics.c \
+               -n m16_idecode.h   -hd tmp-idecode.h \
+               -n m16_idecode.c   -d  tmp-idecode.c \
+               -n m16_model.h     -hm tmp-model.h \
+               -n m16_model.c     -m  tmp-model.c \
+               -n m16_support.h   -hf tmp-support.h \
+               -n m16_support.c   -f  tmp-support.c \
+               -n m16_itable.h    -ht tmp-itable.h \
+               -n m16_itable.c    -t  tmp-itable.c \
+               -n m16_engine.h    -he tmp-engine.h \
+               -n m16_engine.c    -e  tmp-engine.c \
+               -n m16_irun.c      -r  tmp-irun.c
+       $(srcdir)/../../move-if-change tmp-icache.h m16_icache.h
+       $(srcdir)/../../move-if-change tmp-icache.c m16_icache.c
+       $(srcdir)/../../move-if-change tmp-idecode.h m16_idecode.h
+       $(srcdir)/../../move-if-change tmp-idecode.c m16_idecode.c
+       $(srcdir)/../../move-if-change tmp-semantics.h m16_semantics.h
+       $(srcdir)/../../move-if-change tmp-semantics.c m16_semantics.c
+       $(srcdir)/../../move-if-change tmp-model.h m16_model.h
+       $(srcdir)/../../move-if-change tmp-model.c m16_model.c
+       $(srcdir)/../../move-if-change tmp-support.h m16_support.h
+       $(srcdir)/../../move-if-change tmp-support.c m16_support.c
+       $(srcdir)/../../move-if-change tmp-itable.h m16_itable.h
+       $(srcdir)/../../move-if-change tmp-itable.c m16_itable.c
+       $(srcdir)/../../move-if-change tmp-engine.h m16_engine.h
+       $(srcdir)/../../move-if-change tmp-engine.c m16_engine.c
+       $(srcdir)/../../move-if-change tmp-irun.c m16_irun.c
+       touch tmp-m16
+
+
+clean-extra:
+       rm -f gencode oengine.c tmp.igen
diff --git a/sim/txvu/README.Cygnus b/sim/txvu/README.Cygnus
new file mode 100644 (file)
index 0000000..06c5e43
--- /dev/null
@@ -0,0 +1,38 @@
+> README.Cygnus
+-------------------------------------------------------------------------------
+
+The following are the main reasons for constructing the simulator as a
+generator:
+
+1) Avoid large fixed decode source file, with lots of #ifs controlling
+   the compilation. i.e. keep the source cleaner, smaller and easier
+   to parse.
+
+2) Allow optimum code to be created, without run-time checks on
+   instruction types. Ensure that the simulator engine only includes
+   code for the architecture being targetted. e.g. This avoids
+   run-time checks on ISA conformance, aswell as increasing
+   throughput.
+
+3) Allow updates to the instruction sets to be added quickly. Having a
+   table means that the information is together, and is easier to
+   manipulate. Having the table generate the engine, rather than the
+   run-time parse the table gives higher performance at simulation
+   time.
+
+4) Keep all the similar simulation code together. i.e. have a single
+   place where, for example, the addition code is held. This ensures that
+   updates to the simulation are not spread over a large flat source
+   file maintained by the developer.
+
+-------------------------------------------------------------------------------
+
+To keep the simulator simple (and to avoid the slight chance of
+mis-matched files) the manifests describing an engine, and the
+simulator engine itself, are held in the same source file.
+
+This means that the engine must be included twice, with the first pass
+controlled by the SIM_MANIFESTS definition.
+
+-------------------------------------------------------------------------------
+> EOF README.Cygnus
diff --git a/sim/txvu/config.in b/sim/txvu/config.in
new file mode 100644 (file)
index 0000000..f28acc6
--- /dev/null
@@ -0,0 +1,50 @@
+/* config.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define as the return type of signal handlers (int or void).  */
+#undef RETSIGTYPE
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if you have the aint function.  */
+#undef HAVE_AINT
+
+/* Define if you have the anint function.  */
+#undef HAVE_ANINT
+
+/* Define if you have the getrusage function.  */
+#undef HAVE_GETRUSAGE
+
+/* Define if you have the sigaction function.  */
+#undef HAVE_SIGACTION
+
+/* Define if you have the sqrt function.  */
+#undef HAVE_SQRT
+
+/* Define if you have the time function.  */
+#undef HAVE_TIME
+
+/* Define if you have the <stdlib.h> header file.  */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file.  */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file.  */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/resource.h> header file.  */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <time.h> header file.  */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the m library (-lm).  */
+#undef HAVE_LIBM
diff --git a/sim/txvu/configure b/sim/txvu/configure
new file mode 100755 (executable)
index 0000000..53d86a6
--- /dev/null
@@ -0,0 +1,2476 @@
+#! /bin/sh
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12.1 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-sim-bswap                   Use Host specific BSWAP instruction."
+ac_help="$ac_help
+  --enable-sim-cflags=opts             Extra CFLAGS for use in building simulator"
+ac_help="$ac_help
+  --enable-sim-debug=opts              Enable debugging flags"
+ac_help="$ac_help
+  --enable-sim-stdio                   Specify whether to use stdio for console input/output."
+ac_help="$ac_help
+  --enable-sim-trace=opts              Enable tracing flags"
+ac_help="$ac_help
+  --enable-sim-profile=opts            Enable profiling flags"
+ac_help="$ac_help
+  --enable-sim-inline=inlines          Specify which functions should be inlined."
+ac_help="$ac_help
+  --enable-sim-alignment=align         Specify strict,  nonstrict or forced alignment of memory accesses."
+ac_help="$ac_help
+  --enable-sim-hostendian=end          Specify host byte endian orientation."
+ac_help="$ac_help
+  --enable-sim-warnings=opts           Extra CFLAGS for turning on compiler warnings"
+ac_help="$ac_help
+  --enable-sim-endian=endian           Specify target byte endian orientation."
+ac_help="$ac_help
+  --enable-sim-bitsize=n               Specify target bitsize (32 or 64)."
+ac_help="$ac_help
+  --enable-sim-float                   Specify that the target processor has floating point hardware."
+ac_help="$ac_help
+  --enable-sim-igen=opts               Enable IGEN simulator"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.12.1"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=Makefile.in
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:628: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 643 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 660 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:666: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+# autoconf.info says this should be called right after AC_INIT.
+
+
+ac_aux_dir=
+for ac_dir in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in `cd $srcdir;pwd`/../.. $srcdir/`cd $srcdir;pwd`/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:739: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:760: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:778: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:822: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:851: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:899: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 909 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:933: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:938: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+  ac_test_CFLAGS="${CFLAGS+set}"
+  ac_save_CFLAGS="$CFLAGS"
+  CFLAGS=
+  echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:962: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+  if test "$ac_test_CFLAGS" = set; then
+    CFLAGS="$ac_save_CFLAGS"
+  elif test $ac_cv_prog_cc_g = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-O2"
+  fi
+else
+  GCC=
+  test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1001: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Put a plausible default for CC_FOR_BUILD in Makefile.
+if test "x$cross_compiling" = "xno"; then
+  CC_FOR_BUILD='$(CC)'
+else
+  CC_FOR_BUILD=gcc
+fi
+
+
+
+
+AR=${AR-ar}
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1067: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# Check for common headers.
+# FIXME: Seems to me this can cause problems for i386-windows hosts.
+# At one point there were hardcoded AC_DEFINE's if ${host} = i386-*-windows*.
+for ac_hdr in stdlib.h string.h strings.h unistd.h time.h sys/time.h sys/resource.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1101: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1106 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1111: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getrusage time sigaction
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1140: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1145 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+. ${srcdir}/../../bfd/configure.host
+
+
+
+# Check whether --enable-sim-bswap or --disable-sim-bswap was given.
+if test "${enable_sim_bswap+set}" = set; then
+  enableval="$enable_sim_bswap"
+  case "${enableval}" in
+  yes) sim_bswap="-DWITH_BSWAP=1 -DUSE_BSWAP=1";;
+  no)  sim_bswap="-DWITH_BSWAP=0";;
+  *)   { echo "configure: error: "--enable-sim-bswap does not take a value"" 1>&2; exit 1; }; sim_bswap="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_bswap" != x""; then
+  echo "Setting bswap flags = $sim_bswap" 6>&1
+fi
+else
+  sim_bswap=""
+fi
+
+
+
+# Check whether --enable-sim-cflags or --disable-sim-cflags was given.
+if test "${enable_sim_cflags+set}" = set; then
+  enableval="$enable_sim_cflags"
+  case "${enableval}" in
+  yes)  sim_cflags="-O2";;
+  trace) { echo "configure: error: "Please use --enable-sim-debug instead."" 1>&2; exit 1; }; sim_cflags="";;
+  no)   sim_cflags="";;
+  *)    sim_cflags=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_cflags" != x""; then
+  echo "Setting sim cflags = $sim_cflags" 6>&1
+fi
+else
+  sim_cflags=""
+fi
+
+
+
+# Check whether --enable-sim-debug or --disable-sim-debug was given.
+if test "${enable_sim_debug+set}" = set; then
+  enableval="$enable_sim_debug"
+  case "${enableval}" in
+  yes) sim_debug="-DDEBUG=7 -DWITH_DEBUG=7";;
+  no)  sim_debug="-DDEBUG=0 -DWITH_DEBUG=0";;
+  *)   sim_debug="-DDEBUG='(${enableval})' -DWITH_DEBUG='(${enableval})'";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_debug" != x""; then
+  echo "Setting sim debug = $sim_debug" 6>&1
+fi
+else
+  sim_debug=""
+fi
+
+
+
+# Check whether --enable-sim-stdio or --disable-sim-stdio was given.
+if test "${enable_sim_stdio+set}" = set; then
+  enableval="$enable_sim_stdio"
+  case "${enableval}" in
+  yes) sim_stdio="-DWITH_STDIO=DO_USE_STDIO";;
+  no)  sim_stdio="-DWITH_STDIO=DONT_USE_STDIO";;
+  *)   { echo "configure: error: "Unknown value $enableval passed to --enable-sim-stdio"" 1>&2; exit 1; }; sim_stdio="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_stdio" != x""; then
+  echo "Setting stdio flags = $sim_stdio" 6>&1
+fi
+else
+  sim_stdio=""
+fi
+
+
+
+# Check whether --enable-sim-trace or --disable-sim-trace was given.
+if test "${enable_sim_trace+set}" = set; then
+  enableval="$enable_sim_trace"
+  case "${enableval}" in
+  yes) sim_trace="-DTRACE=1 -DWITH_TRACE=-1";;
+  no)  sim_trace="-DTRACE=0 -DWITH_TRACE=0";;
+  [-0-9]*)
+       sim_trace="-DTRACE='(${enableval})' -DWITH_TRACE='(${enableval})'";;
+  [a-z]*)
+       sim_trace=""
+       for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+         if test x"$sim_trace" = x; then
+           sim_trace="-DWITH_TRACE='(TRACE_$x"
+         else
+           sim_trace="${sim_trace}|TRACE_$x"
+         fi
+       done
+       sim_trace="$sim_trace)'" ;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_trace" != x""; then
+  echo "Setting sim trace = $sim_trace" 6>&1
+fi
+else
+  sim_trace=""
+fi
+
+
+
+# Check whether --enable-sim-profile or --disable-sim-profile was given.
+if test "${enable_sim_profile+set}" = set; then
+  enableval="$enable_sim_profile"
+  case "${enableval}" in
+  yes) sim_profile="-DPROFILE=1 -DWITH_PROFILE=-1";;
+  no)  sim_profile="-DPROFILE=0 -DWITH_PROFILE=0";;
+  [-0-9]*)
+       sim_profile="-DPROFILE='(${enableval})' -DWITH_PROFILE='(${enableval})'";;
+  [a-z]*)
+       sim_profile=""
+       for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+         if test x"$sim_profile" = x; then
+           sim_profile="-DWITH_PROFILE='(PROFILE_$x"
+         else
+           sim_profile="${sim_profile}|PROFILE_$x"
+         fi
+       done
+       sim_profile="$sim_profile)'" ;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_profile" != x""; then
+  echo "Setting sim profile = $sim_profile" 6>&1
+fi
+else
+  sim_profile=""
+fi
+
+
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1323: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1328 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1345: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_type_signal=void
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+
+
+sim_link_files=
+sim_link_links=
+
+sim_link_links=tconfig.h
+if test -f ${srcdir}/tconfig.in
+then
+  sim_link_files=tconfig.in
+else
+  sim_link_files=../common/tconfig.in
+fi
+
+# targ-vals.def points to the libc macro description file.
+case "${target}" in
+*-*-*) TARG_VALS_DEF=../common/nltvals.def ;;
+esac
+sim_link_files="${sim_link_files} ${TARG_VALS_DEF}"
+sim_link_links="${sim_link_links} targ-vals.def"
+
+
+
+
+default_sim_inline="-DDEFAULT_INLINE=0"
+# Check whether --enable-sim-inline or --disable-sim-inline was given.
+if test "${enable_sim_inline+set}" = set; then
+  enableval="$enable_sim_inline"
+  sim_inline=""
+case "$enableval" in
+  no)          sim_inline="-DDEFAULT_INLINE=0";;
+  0)           sim_inline="-DDEFAULT_INLINE=0";;
+  yes | 2)     sim_inline="-DDEFAULT_INLINE=ALL_INLINE";;
+  1)           sim_inline="-DDEFAULT_INLINE=INLINE_LOCALS";;
+  *) for x in `echo "$enableval" | sed -e "s/,/ /g"`; do
+       new_flag=""
+       case "$x" in
+        *_INLINE=*)    new_flag="-D$x";;
+        *=*)           new_flag=`echo "$x" | sed -e "s/=/_INLINE=/" -e "s/^/-D/"`;;
+        *_INLINE)      new_flag="-D$x=ALL_INLINE";;
+        *)             new_flag="-D$x""_INLINE=ALL_INLINE";;
+       esac
+       if test x"$sim_inline" = x""; then
+        sim_inline="$new_flag"
+       else
+        sim_inline="$sim_inline $new_flag"
+       fi
+     done;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_inline" != x""; then
+  echo "Setting inline flags = $sim_inline" 6>&1
+fi
+else
+  if test x"$GCC" != "x" -a x"${default_sim_inline}" != "x" ; then
+  sim_inline="${default_sim_inline}"
+  if test x"$silent" != x"yes"; then
+    echo "Setting inline flags = $sim_inline" 6>&1
+  fi
+else
+  sim_inline=""
+fi
+fi
+
+wire_alignment="NONSTRICT_ALIGNMENT"
+default_alignment=""
+
+# Check whether --enable-sim-alignment or --disable-sim-alignment was given.
+if test "${enable_sim_alignment+set}" = set; then
+  enableval="$enable_sim_alignment"
+  case "${enableval}" in
+  strict | STRICT)       sim_alignment="-DWITH_ALIGNMENT=STRICT_ALIGNMENT";;
+  nonstrict | NONSTRICT) sim_alignment="-DWITH_ALIGNMENT=NONSTRICT_ALIGNMENT";;
+  forced | FORCED)       sim_alignment="-DWITH_ALIGNMENT=FORCED_ALIGNMENT";;
+  yes) if test x"$wire_alignment" != x; then
+        sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+       else
+         if test x"$default_alignment" != x; then
+           sim_alignment="-DWITH_ALIGNMENT=${default_alignment}"
+         else
+          echo "No hard-wired alignment for target $target" 1>&6
+          sim_alignment="-DWITH_ALIGNMENT=0"
+         fi
+       fi;;
+  no)  if test x"$default_alignment" != x; then
+        sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+       else
+         if test x"$wire_alignment" != x; then
+          sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${wire_alignment}"
+         else
+           echo "No default alignment for target $target" 1>&6
+           sim_alignment="-DWITH_DEFAULT_ALIGNMENT=0"
+         fi
+       fi;;
+  *)   { echo "configure: error: "Unknown value $enableval passed to --enable-sim-alignment"" 1>&2; exit 1; }; sim_alignment="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_alignment" != x""; then
+  echo "Setting alignment flags = $sim_alignment" 6>&1
+fi
+else
+  if test x"$default_alignment" != x; then
+  sim_alignment="-DWITH_DEFAULT_ALIGNMENT=${default_alignment}"
+else
+  if test x"$wire_alignment" != x; then
+    sim_alignment="-DWITH_ALIGNMENT=${wire_alignment}"
+  else
+    sim_alignment=
+  fi
+fi
+fi
+
+
+# Check whether --enable-sim-hostendian or --disable-sim-hostendian was given.
+if test "${enable_sim_hostendian+set}" = set; then
+  enableval="$enable_sim_hostendian"
+  case "${enableval}" in
+  no)   sim_hostendian="-DWITH_HOST_BYTE_ORDER=0";;
+  b*|B*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN";;
+  l*|L*) sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN";;
+  *)    { echo "configure: error: "Unknown value $enableval for --enable-sim-hostendian"" 1>&2; exit 1; }; sim_hostendian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_hostendian" != x""; then
+  echo "Setting hostendian flags = $sim_hostendian" 6>&1
+fi
+else
+  
+if test "x$cross_compiling" = "xno"; then
+  echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1489: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 1496 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1507: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 1511 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1522: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1542 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:1555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+  if test $ac_cv_c_bigendian = yes; then
+    sim_hostendian="-DWITH_HOST_BYTE_ORDER=BIG_ENDIAN"
+  else
+    sim_hostendian="-DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN"
+  fi
+else
+  sim_hostendian="-DWITH_HOST_BYTE_ORDER=0"
+fi
+fi
+
+
+# Check whether --enable-sim-warnings or --disable-sim-warnings was given.
+if test "${enable_sim_warnings+set}" = set; then
+  enableval="$enable_sim_warnings"
+  case "${enableval}" in
+  yes) sim_warnings="-Werror -Wall -Wpointer-arith -Wmissing-prototypes -Wmissing-declarations ";;
+  no)  sim_warnings="-w";;
+  *)   sim_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$sim_warnings" != x""; then
+  echo "Setting warning flags = $sim_warnings" 6>&1
+fi
+else
+  sim_warnings=""
+fi
+
+
+
+# Ensure a reasonable default simulator is constructed:
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        SIMCONF="-mips1 -mcpu=r1900 -mno-fp --warnings";;
+# end-sanitize-tx19
+# start-sanitize-tx49
+  mips64tx49*-*-*)      SIMCONF="-mips3 --warnings -mcpu=r4900";;
+# end-sanitize-tx49
+# start-sanitize-r5900
+  mips64r59*-*-*)      SIMCONF="-mips3 --warnings -mcpu=r5900";;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)      SIMCONF="-mips3 --warnings -mcpu=r5900";;
+# end-sanitize-sky
+  mips64*-*-*)          SIMCONF="-mips0 --warnings";;
+  mips16*-*-*)          SIMCONF="-mips0 --warnings";;
+  mips*-*-*)            SIMCONF="-mips2 --warnings";;
+  *)                    SIMCONF="-mips0 --warnings";;
+esac
+
+
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
+# end-sanitize-tx19
+  *)                    SIM_SUBTARGET="";;
+esac
+
+
+
+#
+# Select the byte order of the target
+#
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_endian=0 ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      mips_endian=LITTLE_ENDIAN ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_endian=LITTLE_ENDIAN ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_endian=0 ;;
+  mips16*-*-*)          mips_endian=0 ;;
+  mips*-*-*)            mips_endian=0 ;;
+  *)                    mips_endian=0 ;;
+esac
+
+wire_endian="$mips_endian"
+default_endian=""
+# Check whether --enable-sim-endian or --disable-sim-endian was given.
+if test "${enable_sim_endian+set}" = set; then
+  enableval="$enable_sim_endian"
+  case "${enableval}" in
+  b*|B*) sim_endian="-DWITH_TARGET_BYTE_ORDER=BIG_ENDIAN";;
+  l*|L*) sim_endian="-DWITH_TARGET_BYTE_ORDER=LITTLE_ENDIAN";;
+  yes)  if test x"$wire_endian" != x; then
+          sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+        else
+           if test x"$default_endian" != x; then
+            sim_endian="-DWITH_TARGET_BYTE_ORDER=${default_endian}"
+          else
+            echo "No hard-wired endian for target $target" 1>&6
+            sim_endian="-DWITH_TARGET_BYTE_ORDER=0"
+          fi
+        fi;;
+  no)   if test x"$default_endian" != x; then
+          sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+        else
+          if test x"$wire_endian" != x; then
+            sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${wire_endian}"
+          else
+            echo "No default endian for target $target" 1>&6
+            sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=0"
+          fi
+        fi;;
+  *)    { echo "configure: error: "Unknown value $enableval for --enable-sim-endian"" 1>&2; exit 1; }; sim_endian="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_endian" != x""; then
+  echo "Setting endian flags = $sim_endian" 6>&1
+fi
+else
+  if test x"$default_endian" != x; then
+  sim_endian="-DWITH_DEFAULT_TARGET_BYTE_ORDER=${default_endian}"
+else
+  if test x"$wire_endian" != x; then
+    sim_endian="-DWITH_TARGET_BYTE_ORDER=${wire_endian}"
+  else
+    sim_endian=
+  fi
+fi
+fi
+
+
+
+#
+# Select the bitsize of the target
+#
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_bitsize=32 ; mips_msb=31 ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      mips_bitsize=64 ; mips_msb=63 ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_bitsize=64 ; mips_msb=63 ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_bitsize=64 ; mips_msb=63 ;;
+  mips16*-*-*)          mips_bitsize=64 ; mips_msb=63 ;;
+  mips*-*-*)            mips_bitsize=32 ; mips_msb=31 ;;
+  *)                    mips_bitsize=64 ; mips_msb=63 ;;
+esac
+wire_bitsize="$mips_bitsize"
+wire_msb="$mips_msb"
+# Check whether --enable-sim-bitsize or --disable-sim-bitsize was given.
+if test "${enable_sim_bitsize+set}" = set; then
+  enableval="$enable_sim_bitsize"
+  case "${enableval}" in
+  64,63) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=63";;
+  32,31) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=31";;
+  64,0) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0";;
+  32,0) sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0";;
+  32) if test x"$wire_msb" != x -a x"$wire_msb" != x0; then
+        sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=31"
+      else
+        sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=32 -DWITH_TARGET_WORD_MSB=0"
+      fi ;;
+  64) if test x"$wire_msb" != x -a x"$wire_msb" != x0; then
+        sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=63"
+      else
+        sim_bitsize="-DWITH_TARGET_WORD_BITSIZE=64 -DWITH_TARGET_WORD_MSB=0"
+      fi ;;
+  *)  { echo "configure: error: "--enable-sim-bitsize was given $enableval.  Expected 32 or 64"" 1>&2; exit 1; }; sim_bitsize="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_bitsize" != x""; then
+  echo "Setting bitsize flags = $sim_bitsize" 6>&1
+fi
+else
+  sim_bitsize=""
+if test x"$wire_bitsize" != x; then
+  sim_bitsize="$sim_bitsize -DWITH_TARGET_WORD_BITSIZE=$wire_bitsize"
+fi
+if test x"$wire_msb" != x; then
+  sim_bitsize="$sim_bitsize -DWITH_TARGET_WORD_MSB=$wire_msb"
+fi
+fi
+
+
+
+#
+# Select the floating hardware support of the target
+#
+mips_fpu=HARDWARE_FLOATING_POINT
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_fpu=SOFT_FLOATING_POINT ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)       mips_fpu=HARD_FLOATING_POINT ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_fpu=HARD_FLOATING_POINT ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_fpu=HARD_FLOATING_POINT ;;
+  mips16*-*-*)          mips_fpu=HARD_FLOATING_POINT ;;
+  mips*-*-*)            mips_fpu=HARD_FLOATING_POINT ;;
+  *)                    mips_fpu=HARD_FLOATING_POINT ;;
+esac
+
+default_sim_floating_point="$mips_fpu"
+# Check whether --enable-sim-float or --disable-sim-float was given.
+if test "${enable_sim_float+set}" = set; then
+  enableval="$enable_sim_float"
+  case "${enableval}" in
+  yes | hard)  sim_float="-DWITH_FLOATING_POINT=HARD_FLOATING_POINT";;
+  no | soft)   sim_float="-DWITH_FLOATING_POINT=SOFT_FLOATING_POINT";;
+  *)           { echo "configure: error: "Unknown value $enableval passed to --enable-sim-float"" 1>&2; exit 1; }; sim_float="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_float" != x""; then
+  echo "Setting float flags = $sim_float" 6>&1
+fi
+else
+  sim_float="-DWITH_FLOATING_POINT=${default_sim_floating_point}"
+fi
+
+
+
+#
+# Select the IGEN architecture
+#
+sim_use_gen=NO
+sim_igen_machine="-M mipsIV"
+sim_m16_machine="-M mips16"
+sim_igen_filter="32,64,f"
+sim_m16_filter="16"
+
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)       sim_default_gen=M16
+                       sim_igen_machine="-M tx19"
+                       sim_m16_machine="-M tx19"
+                       sim_igen_filter="32"
+                       sim_m16_filter="16"
+                       ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      sim_default_gen=IGEN
+                       sim_igen_machine="-M r5900"
+                       ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            sim_default_gen=IGEN
+                       sim_igen_machine="-M r5900"
+                       ;;
+# end-sanitize-sky
+# start-sanitize-vr5400
+  mips64vr54*-*-*)     sim_default_gen=IGEN
+                       sim_use_gen=IGEN
+                       sim_igen_machine="-M vr5000,vr5400 -G gen-multi-sim=vr5400"
+                       ;;
+# end-sanitize-vr5400
+  mips64vr5*-*-*)      sim_default_gen=IGEN
+                       sim_use_gen=IGEN
+                       sim_igen_machine="-M vr5000"
+# start-sanitize-vr5400
+                       sim_igen_machine="-M vr5000,vr5400 -G gen-multi-sim=vr5000"
+# end-sanitize-vr5400
+                       ;;
+  mips16*-*-*)         sim_default_gen=M16
+                       ;;
+  mips32*-*-*)         sim_default_gen=IGEN
+                       sim_igen_filter="32,f"
+                       ;;
+  *)                    sim_default_gen=IGEN
+                       ;;
+esac
+sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine}"
+sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}"
+
+
+
+#
+# Enable igen
+#
+# Check whether --enable-sim-igen or --disable-sim-igen was given.
+if test "${enable_sim_igen+set}" = set; then
+  enableval="$enable_sim_igen"
+  case "${enableval}" in
+  yes) sim_gen="${sim_default_gen}";;
+  no)  sim_gen=NO;;
+  16)  sim_gen=M16;;
+  *)   { echo "configure: error: "Unknown value $enableval passed to --enable-sim-stdio"" 1>&2; exit 1; }; sim_gen="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_gen" != x""; then
+  echo "Setting sim_igen = $sim_gen" 6>&1
+fi
+else
+  sim_gen="${sim_use_gen}"
+fi
+
+
+
+
+for ac_hdr in string.h strings.h stdlib.h stdlib.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1875: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1880 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1885: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for fabs in -lm""... $ac_c" 1>&6
+echo "configure:1912: checking for fabs in -lm" >&5
+ac_lib_var=`echo m'_'fabs | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lm  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1920 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char fabs();
+
+int main() {
+fabs()
+; return 0; }
+EOF
+if { (eval echo configure:1931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lm $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+for ac_func in aint anint sqrt
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1961: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1966 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set) 2>&1 | grep ac_space` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.12.1"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@sim_environment@%$sim_environment%g
+s%@sim_alignment@%$sim_alignment%g
+s%@sim_assert@%$sim_assert%g
+s%@sim_bitsize@%$sim_bitsize%g
+s%@sim_endian@%$sim_endian%g
+s%@sim_hostendian@%$sim_hostendian%g
+s%@sim_float@%$sim_float%g
+s%@sim_scache@%$sim_scache%g
+s%@sim_default_model@%$sim_default_model%g
+s%@sim_hardware@%$sim_hardware%g
+s%@sim_inline@%$sim_inline%g
+s%@sim_packages@%$sim_packages%g
+s%@sim_regparm@%$sim_regparm%g
+s%@sim_reserved_bits@%$sim_reserved_bits%g
+s%@sim_smp@%$sim_smp%g
+s%@sim_stdcall@%$sim_stdcall%g
+s%@sim_xor_endian@%$sim_xor_endian%g
+s%@sim_warnings@%$sim_warnings%g
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CC_FOR_BUILD@%$CC_FOR_BUILD%g
+s%@HDEFINES@%$HDEFINES%g
+s%@AR@%$AR%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@sim_bswap@%$sim_bswap%g
+s%@sim_cflags@%$sim_cflags%g
+s%@sim_debug@%$sim_debug%g
+s%@sim_stdio@%$sim_stdio%g
+s%@sim_trace@%$sim_trace%g
+s%@sim_profile@%$sim_profile%g
+s%@SIMCONF@%$SIMCONF%g
+s%@SIM_SUBTARGET@%$SIM_SUBTARGET%g
+s%@sim_igen_flags@%$sim_igen_flags%g
+s%@sim_m16_flags@%$sim_m16_flags%g
+s%@sim_gen@%$sim_gen%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+ac_sources="$sim_link_files"
+ac_dests="$sim_link_links"
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+srcdir=$ac_given_srcdir
+while test -n "$ac_sources"; do
+  set $ac_dests; ac_dest=$1; shift; ac_dests=$*
+  set $ac_sources; ac_source=$1; shift; ac_sources=$*
+
+  echo "linking $srcdir/$ac_source to $ac_dest"
+
+  if test ! -r $srcdir/$ac_source; then
+    { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; }
+  fi
+  rm -f $ac_dest
+
+  # Make relative symlinks.
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then
+    # The dest file is in a subdirectory.
+    test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir"
+    ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dest_dir_suffix.
+    ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dest_dir_suffix= ac_dots=
+  fi
+
+  case "$srcdir" in
+  [/$]*) ac_rel_source="$srcdir/$ac_source" ;;
+  *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;;
+  esac
+
+  # Make a symlink if possible; otherwise try a hard link.
+  if ln -s $ac_rel_source $ac_dest 2>/dev/null ||
+    ln $srcdir/$ac_source $ac_dest; then :
+  else
+    { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; }
+  fi
+done
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+case "x$CONFIG_FILES" in
+ xMakefile*)
+   echo "Merging Makefile.sim+Make-common.sim into Makefile ..."
+   rm -f Makesim1.tmp Makesim2.tmp Makefile
+   sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' <Make-common.sim >Makesim1.tmp
+   sed -n -e '/^## COMMON_POST_/,/^## End COMMON_POST_/ p' <Make-common.sim >Makesim2.tmp
+   sed -e '/^## COMMON_PRE_/ r Makesim1.tmp' \
+       -e '/^## COMMON_POST_/ r Makesim2.tmp' \
+       <Makefile.sim >Makefile
+   rm -f Makefile.sim Make-common.sim Makesim1.tmp Makesim2.tmp
+   ;;
+ esac
+ case "x$CONFIG_HEADERS" in xconfig.h:config.in) echo > stamp-h ;; esac
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
diff --git a/sim/txvu/configure.in b/sim/txvu/configure.in
new file mode 100644 (file)
index 0000000..6c01e7f
--- /dev/null
@@ -0,0 +1,185 @@
+dnl Process this file with autoconf to produce a configure script.
+sinclude(../common/aclocal.m4)
+AC_PREREQ(2.5)dnl
+AC_INIT(Makefile.in)
+
+SIM_AC_COMMON
+
+dnl Options available in this module
+SIM_AC_OPTION_INLINE(0)
+SIM_AC_OPTION_ALIGNMENT(NONSTRICT_ALIGNMENT)
+SIM_AC_OPTION_HOSTENDIAN
+SIM_AC_OPTION_WARNINGS
+
+
+# Ensure a reasonable default simulator is constructed:
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        SIMCONF="-mips1 -mcpu=r1900 -mno-fp --warnings";;
+# end-sanitize-tx19
+# start-sanitize-tx49
+  mips64tx49*-*-*)      SIMCONF="-mips3 --warnings -mcpu=r4900";;
+# end-sanitize-tx49
+# start-sanitize-r5900
+  mips64r59*-*-*)      SIMCONF="-mips3 --warnings -mcpu=r5900";;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)      SIMCONF="-mips3 --warnings -mcpu=r5900";;
+# end-sanitize-sky
+  mips64*-*-*)          SIMCONF="-mips0 --warnings";;
+  mips16*-*-*)          SIMCONF="-mips0 --warnings";;
+  mips*-*-*)            SIMCONF="-mips2 --warnings";;
+  *)                    SIMCONF="-mips0 --warnings";;
+esac
+AC_SUBST(SIMCONF)
+
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
+# end-sanitize-tx19
+  *)                    SIM_SUBTARGET="";;
+esac
+AC_SUBST(SIM_SUBTARGET)
+
+
+#
+# Select the byte order of the target
+#
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_endian=0 ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      mips_endian=LITTLE_ENDIAN ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_endian=LITTLE_ENDIAN ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_endian=0 ;;
+  mips16*-*-*)          mips_endian=0 ;;
+  mips*-*-*)            mips_endian=0 ;;
+  *)                    mips_endian=0 ;;
+esac
+SIM_AC_OPTION_ENDIAN($mips_endian)
+
+
+#
+# Select the bitsize of the target
+#
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_bitsize=32 ; mips_msb=31 ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      mips_bitsize=64 ; mips_msb=63 ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_bitsize=64 ; mips_msb=63 ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_bitsize=64 ; mips_msb=63 ;;
+  mips16*-*-*)          mips_bitsize=64 ; mips_msb=63 ;;
+  mips*-*-*)            mips_bitsize=32 ; mips_msb=31 ;;
+  *)                    mips_bitsize=64 ; mips_msb=63 ;;
+esac
+SIM_AC_OPTION_BITSIZE($mips_bitsize,$mips_msb)
+
+
+#
+# Select the floating hardware support of the target
+#
+mips_fpu=HARDWARE_FLOATING_POINT
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)        mips_fpu=SOFT_FLOATING_POINT ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)       mips_fpu=HARD_FLOATING_POINT ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            mips_fpu=HARD_FLOATING_POINT ;;
+# end-sanitize-sky
+  mips64*-*-*)          mips_fpu=HARD_FLOATING_POINT ;;
+  mips16*-*-*)          mips_fpu=HARD_FLOATING_POINT ;;
+  mips*-*-*)            mips_fpu=HARD_FLOATING_POINT ;;
+  *)                    mips_fpu=HARD_FLOATING_POINT ;;
+esac
+SIM_AC_OPTION_FLOAT($mips_fpu)
+
+
+#
+# Select the IGEN architecture
+#
+sim_use_gen=NO
+sim_igen_machine="-M mipsIV"
+sim_m16_machine="-M mips16"
+sim_igen_filter="32,64,f"
+sim_m16_filter="16"
+
+case "${target}" in
+# start-sanitize-tx19
+  mipstx19*-*-*)       sim_default_gen=M16
+                       sim_igen_machine="-M tx19"
+                       sim_m16_machine="-M tx19"
+                       sim_igen_filter="32"
+                       sim_m16_filter="16"
+                       ;;
+# end-sanitize-tx19
+# start-sanitize-r5900
+  mips64r59*-*-*)      sim_default_gen=IGEN
+                       sim_igen_machine="-M r5900"
+                       ;;
+# end-sanitize-r5900
+# start-sanitize-sky
+  txvu-*-*)            sim_default_gen=IGEN
+                       sim_igen_machine="-M r5900"
+                       ;;
+# end-sanitize-sky
+# start-sanitize-vr5400
+  mips64vr54*-*-*)     sim_default_gen=IGEN
+                       sim_use_gen=IGEN
+                       sim_igen_machine="-M vr5000,vr5400 -G gen-multi-sim=vr5400"
+                       ;;
+# end-sanitize-vr5400
+  mips64vr5*-*-*)      sim_default_gen=IGEN
+                       sim_use_gen=IGEN
+                       sim_igen_machine="-M vr5000"
+# start-sanitize-vr5400
+                       sim_igen_machine="-M vr5000,vr5400 -G gen-multi-sim=vr5000"
+# end-sanitize-vr5400
+                       ;;
+  mips16*-*-*)         sim_default_gen=M16
+                       ;;
+  mips32*-*-*)         sim_default_gen=IGEN
+                       sim_igen_filter="32,f"
+                       ;;
+  *)                    sim_default_gen=IGEN
+                       ;;
+esac
+sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine}"
+sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}"
+AC_SUBST(sim_igen_flags)
+AC_SUBST(sim_m16_flags)
+
+#
+# Enable igen
+#
+AC_ARG_ENABLE(sim-igen,
+[  --enable-sim-igen=opts              Enable IGEN simulator],
+[case "${enableval}" in
+  yes) sim_gen="${sim_default_gen}";;
+  no)  sim_gen=NO;;
+  16)  sim_gen=M16;;
+  *)   AC_MSG_ERROR("Unknown value $enableval passed to --enable-sim-stdio"); sim_gen="";;
+esac
+if test x"$silent" != x"yes" && test x"$sim_gen" != x""; then
+  echo "Setting sim_igen = $sim_gen" 6>&1
+fi],[sim_gen="${sim_use_gen}"])dnl
+AC_SUBST(sim_gen)
+
+
+
+AC_CHECK_HEADERS(string.h strings.h stdlib.h stdlib.h)
+AC_CHECK_LIB(m, fabs)
+AC_CHECK_FUNCS(aint anint sqrt)
+
+SIM_AC_OUTPUT
diff --git a/sim/txvu/device.c b/sim/txvu/device.c
new file mode 100644 (file)
index 0000000..5dda361
--- /dev/null
@@ -0,0 +1,59 @@
+/*  Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1998, Cygnus Solutions
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+    */
+
+#include "sim-main.h"
+#include "device.h"
+
+void 
+device_error (device *me, char* message) 
+{
+    fprintf(stderr, "device_error: %s: %s", me->name, message);
+}
+
+int
+device_io_read_buffer(device *me,
+                      void *dest,
+                      int space,
+                      address_word addr,
+                      unsigned nr_bytes,
+                      sim_cpu *processor,
+                      sim_cia cia)
+{
+  if (me->io_read_buffer_callback == NULL)
+    device_error(me, "no io_read_buffer_callback method");
+  return me->io_read_buffer_callback(me, dest, space,
+                                      addr, nr_bytes,
+                                      processor, cia);
+}
+
+int
+device_io_write_buffer(device *me,
+                       const void *source,
+                       int space,
+                       address_word addr,
+                       unsigned nr_bytes,
+                       sim_cpu *processor,
+                       sim_cia cia)
+{
+  if (me->io_write_buffer_callback == NULL)
+    device_error(me, "no io_write_buffer_callback method");
+  return me->io_write_buffer_callback(me, source, space,
+                                       addr, nr_bytes,
+                                       processor, cia);
+}
diff --git a/sim/txvu/device.h b/sim/txvu/device.h
new file mode 100644 (file)
index 0000000..641cd29
--- /dev/null
@@ -0,0 +1,24 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef DEVICE_H_
+#define DEVICE_H_
+
+#include "sim-main.h"
+
+typedef int io_read_buffer_callback_type (device *, void *, int,
+                        address_word, unsigned ,
+                        sim_cpu *, sim_cia);
+
+typedef int io_write_buffer_callback_type (device *, const void *, int,
+                        address_word, unsigned ,
+                        sim_cpu *, sim_cia);
+
+struct _device {
+    char *name;
+    io_read_buffer_callback_type *io_read_buffer_callback;
+    io_write_buffer_callback_type *io_write_buffer_callback;
+};
+
+#endif
diff --git a/sim/txvu/dma.c b/sim/txvu/dma.c
new file mode 100644 (file)
index 0000000..7f178aa
--- /dev/null
@@ -0,0 +1,70 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "dma.h"
+
+int
+dma_io_read_buffer(device *me,
+                   void *dest,
+                   int space,
+                   address_word addr,
+                   unsigned nr_bytes,
+                   sim_cpu *processor,
+                   sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+       return nr_bytes;
+}
+
+static sim_event_handler do_the_dma_thing_handler;
+
+int
+dma_io_write_buffer(device *me,
+                    const void *source,
+                    int space,
+                    address_word addr,
+                    unsigned nr_bytes,
+                    sim_cpu *processor,
+                    sim_cia cia)
+{
+       printf("%s: Write!\n", me->name);
+
+       /* Do an event before the next instruction! */
+       sim_events_schedule (CPU_STATE(processor), 
+                            0 /*time*/, 
+                            do_the_dma_thing_handler,
+                            CPU_STATE(processor) /*data*/);
+       return nr_bytes;
+}
+
+device dma_device = 
+  { 
+    "Dma Controller", 
+    &dma_io_read_buffer,
+    &dma_io_write_buffer 
+  };
+
+void 
+dma_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   DMA_REGISTER_WINDOW_START,
+                   DMA_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &dma_device,
+                   NULL /*buffer*/);
+}
+
+static void
+do_the_dma_thing_handler(SIM_DESC sd, void *data)
+{
+  printf("Dma Event!!!\n");
+}
diff --git a/sim/txvu/dma.h b/sim/txvu/dma.h
new file mode 100644 (file)
index 0000000..dc2fcb7
--- /dev/null
@@ -0,0 +1,46 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef DMA_H_
+#define DMA_H_
+
+#include "sim-main.h"
+
+void dma_attach(SIM_DESC sd);
+
+#define DMA_REGISTER_WINDOW_START 0x10001000
+
+#define DMA_D0_CHCR_ADDR       0x10001000
+#define DMA_D0_MADR_ADDR       0x10001010
+#define DMA_D0_QWC_ADDR                0x10001020
+#define DMA_D0_TADR_ADDR       0x10001030
+#define DMA_D0_ASR0_ADDR       0x10001040
+#define DMA_D0_ASR1_ADDR       0x10001050
+
+#define DMA_D1_CHCR_ADDR       0x10001100
+#define DMA_D1_MADR_ADDR       0x10001110
+#define DMA_D1_QWC_ADDR                0x10001120
+#define DMA_D1_TADR_ADDR       0x10001130
+#define DMA_D1_ASR0_ADDR       0x10001140
+#define DMA_D1_ASR1_ADDR       0x10001150
+
+#define DMA_D2_CHCR_ADDR       0x10001200
+#define DMA_D2_MADR_ADDR       0x10001210
+#define DMA_D2_QWC_ADDR                0x10001220
+#define DMA_D2_TADR_ADDR       0x10001230
+#define DMA_D2_ASR0_ADDR       0x10001240
+#define DMA_D2_ASR1_ADDR       0x10001250
+
+#define DMA_D_CTRL             0x10001c00
+#define DMA_D_STAT             0x10001c10
+#define DMA_D_PCR              0x10001c20
+#define DMA_D_SQWC             0x10001c30
+#define DMA_D_RBSR             0x10001c40
+#define DMA_D_RBOR             0x10001c50
+#define DMA_D_STADR            0x10001c60
+
+#define DMA_REGISTER_WINDOW_END 0x10001c70
+#define DMA_REGISTER_WINDOW_SIZE (DMA_REGISTER_WINDOW_END - DMA_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/txvu/engine-sky.c b/sim/txvu/engine-sky.c
new file mode 100644 (file)
index 0000000..78143b2
--- /dev/null
@@ -0,0 +1,94 @@
+/*  Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+    Copyright (C) 1998, Cygnus Solutions
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+    */
+
+#ifndef _ENGINE_C_
+#define _ENGINE_C_
+
+#include "sim-inline.c"
+
+#include "sim-main.h"
+#include "itable.h"
+#include "idecode.h"
+#include "semantics.h"
+#include "icache.h"
+#include "engine.h"
+#include "support.h"
+
+#include "sim-assert.h"
+
+enum {
+  /* greater or equal to zero => table */
+  function_entry = -1,
+  boolean_entry = -2,
+};
+
+typedef struct _idecode_table_entry {
+  int shift;
+  unsigned32 mask;
+  unsigned32 value;
+  void *function_or_table;
+} idecode_table_entry;
+
+
+INLINE_ENGINE\
+(void) engine_run
+(SIM_DESC sd,
+ int next_cpu_nr,
+ int siggnal)
+{
+  sim_cpu *processor = NULL;
+  instruction_address cia;
+  int current_cpu = next_cpu_nr;
+
+  /* Hard coded main loop.  Not pretty, but should work. */
+
+  SIM_ASSERT (current_cpu == 0);
+  processor = STATE_CPU (sd, current_cpu);
+  cia = CPU_CIA (processor);
+
+  while (1)
+    {
+      instruction_address nia;
+
+      instruction_word instruction_0 = IMEM (cia);
+
+#if defined (ENGINE_ISSUE_PREFIX_HOOK)
+      ENGINE_ISSUE_PREFIX_HOOK();
+#endif
+
+      nia = idecode_issue(sd, instruction_0, cia);
+
+#if defined (ENGINE_ISSUE_POSTFIX_HOOK)
+      ENGINE_ISSUE_POSTFIX_HOOK();
+#endif
+
+
+      /* Update the instruction address */
+      cia = nia;
+
+      /* process any events */
+      if (sim_events_tick (sd))
+        {
+          CPU_CIA (processor) = cia;
+          sim_events_process (sd);
+        }
+    }
+}
+
+#endif /* _ENGINE_C_*/
diff --git a/sim/txvu/gencode.c b/sim/txvu/gencode.c
new file mode 100644 (file)
index 0000000..44fac70
--- /dev/null
@@ -0,0 +1,4846 @@
+/*> gencode.c <*/
+/* Instruction handling support for the MIPS architecture simulator.
+
+   This file is part of the MIPS sim
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   Cygnus offers the following for use in the public domain.  Cygnus
+   makes no warranty with regard to the software or it's performance
+   and the user accepts the software "AS IS" with all faults.
+
+   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
+   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+   $Revision$
+     $Author$
+       $Date$
+*/
+
+#if 0
+#define DEBUG (1) /* Just for testing */
+#endif
+
+/* All output sent to stdout is for the simulator engine. All program
+   related warnings and errors should be sent to stderr. */
+
+/* The simulator decode table is constructed this way to allow the
+   minimal code required for a particular instruction type to be
+   coded.  This avoids a large simulator source file, with lots of
+   build-time conditionals controlling what code is included.  However
+   this two-stage process does mean that care must be taken to ensure
+   that the correct decoding source is generated for a particular MIPS
+   simulator. */
+
+/* Notes:
+
+   We could provide pipeline modelling by splitting the simulation of
+   instructions into seperate bytecodes for each pipeline
+   stage. e.g. for the VR4300 each instruction would generate 5
+   bytecodes, one for each pipeline stage. The simulator control would
+   then insert these into the relevant pipeline slots, and execute a
+   complete slots worth of bytecodes. However, the shape of the
+   pipeline, and what parts of each instruction are executed in each
+   pipeline stage, are different between MIPS implementations. If we
+   were to construct a simulator for a particular MIPS architecture
+   this would be a good solution.
+
+   To avoid having to provide multiple different pipeline models, a
+   simple approach for dealing with the delay slots, and register
+   dependencies has been used. The "MIPS IV Instruction Set" document
+   (Revision 3.1 - January 1995) details the standard MIPS instruction
+   set, and it defines operations in instruction (not pipe-line)
+   cycles. This means we only need to worry about a few cases where
+   the result is not available until after the next instruction, or
+   where registers in the previous two instruction cycles may be
+   corrupted. The case for corruption only occurs with HI or LO
+   register access, so we can just keep a count within the engine for
+   upto two cycles before marking the register as safe. We then only
+   need to check the safety flag when performing an update that
+   involves the HI or LO register. The only other case is the
+   BC1F/BC1T instructions in the FP unit. For ISAs I, II and III there
+   must be an instruction between the FP CMP and the BC1[FT]. We can
+   perform the same instruction cycle count scheme, so we can raise a
+   warning if an attempt is made to access the condition code early
+   (NOTE: The hardware does not interlock on this operation, so the
+   simulator should just raise a warning).
+
+   For the situations where a result is not available until later, we
+   implent a slot to hold pending values. After the PC is incremented,
+   and before the instruction is decoded we can execute the required
+   register update (or remainder of instruction processing). */
+
+/* The FP instruction decoding is also provided by this code.  The
+   instructions are marked as "FP" ones so that we can construct a
+   simulator without an FPU if required.  Similarly we mark
+   instructions as Single or Double precision, since some MIPS
+   processors only have single precision FP hardware. */
+
+/* NOTE: Ideally all state should be passed as parameters. This allows
+   a single simulator engine to be used for multiple concurrent
+   simulations. More importantly, if a suitably powerful control is in
+   place it will allow speculative simulation, since the context can
+   be saved easily, and then restored after performing some
+   simulation. The down-side is that for certain host architectures it
+   can slow the simulator down (e.g. if globals can be accessed faster
+   than local structures). However, this is not actually the case at
+   the moment. The constructed engine uses direct names (that can be
+   macro definitions). This keeps the engine source smalled (using
+   short-hands), and it also allows the user to control whether they
+   want to use global, or indirected memory locations. i.e. whether
+   they want a single- or multi-threaded simulator engine. */
+
+/* The constructed simulator engine contains manifests for each of the
+   features supported. The code that includes the engine can then
+   discover the available features during its build. This information
+   can be used to control run-time features provided by the final
+   simulator. */
+
+/*---------------------------------------------------------------------------*/
+
+/* Program defaults */
+#define DEF_ISA      (3)
+#define DEF_PROC64   (1 == 1)
+#define DEF_FP       (1 == 1)
+#define DEF_FPSINGLE (1 == 0)
+
+#define FEATURE_PROC32      (1 << 0)    /* 0 = 64bit; 1 = 32bit */
+#define FEATURE_HASFPU      (1 << 1)    /* 0 = no FPU; 1 = include FPU */
+#define FEATURE_FPSINGLE    (1 << 1)    /* 0 = double; 1 = single (only used if FEATURE_HASFPU defined) */
+#define FEATURE_GP64        (1 << 2)    /* 0 = GPRLEN 32; 1 = GPRLEN 64 */
+#define FEATURE_FAST        (1 << 17)   /* 0 = normal;  1 = disable features that slow performance */
+#define FEATURE_WARN_STALL  (1 << 24)   /* 0 = nothing; 1 = generate warnings when pipeline would stall */
+#define FEATURE_WARN_LOHI   (1 << 25)   /* 0 = nothing; 1 = generate warnings when LO/HI corrupted */
+#define FEATURE_WARN_ZERO   (1 << 26)   /* 0 = nothing; 1 = generate warnings if attempt to write register zero */ 
+#define FEATURE_WARN_MEM    (1 << 27)   /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
+#define FEATURE_WARN_R31    (1 << 28)   /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
+#define FEATURE_WARN_RESULT (1 << 29)   /* 0 = nothing; 1 = generate warnings when undefined results may occur */
+#define FEATURE_IGEN        (1 << 20)   /* 0 = nothing; 1 = generate igen formatted output file */
+
+/* We used to enable FEATURE_WARN_ZERO, but it is perfectly legitimate to
+   have the zero register as a destination -- the zero register just doesn't
+   actually change.  */
+/* start-sanitize-r5900 */
+/* The 5900 madd instructions for example use this feature.  */
+/* end-sanitize-r5900 */
+#if 1
+#define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_R31)
+#else
+#define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_R31 | FEATURE_WARN_RESULT)
+#endif
+
+/* FEATURE_WARN_STALL */
+/* If MIPS I we want to raise a warning if an attempt is made to
+   access Rn in an instruction immediately following an Rn update
+   "WARNING : Invalid value read". The simulator engine is designed
+   that the previous value is read in such cases, to allow programs
+   that make use of this feature to execute. */
+/* If MIPS II or later, attempting to read a register before the
+   update has completed will generate a "WARNING : Processor stall"
+   message (since the processor will lock the pipeline until the value
+   becomes available). */
+
+/* FEATURE_WARN_LOHI */
+/* Warn if an attempt is made to read the HI/LO registers before the
+   update has completed, or if an attempt is made to update the
+   registers whilst an update is occurring. */
+
+/* FEATURE_WARN_ZERO */
+/* Notify the user if an attempt is made to use GPR 0 as a destination. */
+
+/* FEATURE_WARN_R31 */
+/* Notify the user if register r31 (the default procedure call return
+   address) is used unwisely. e.g. If r31 is used as the source in a
+   branch-and-link instruction, it would mean that an exception in the
+   delay slot instruction would not allow the branch to be re-started
+   (since r31 will have been overwritten by the link operation during
+   the first execution of the branch). */
+
+/* FEATURE_WARN_RESULT */
+/* Certain instructions do not raise exceptions when invalid operands
+   are given, they will just result in undefined values being
+   generated. This option controls whether the simulator flags such
+   events. */
+
+/*---------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <getopt.h>
+#include <limits.h>
+#include <errno.h>
+#include <ctype.h>
+#include "ansidecl.h"
+#include "opcode/mips.h"
+
+/* FIXME: ansidecl.h defines AND.  */
+#undef AND
+
+#ifndef ULONG_MAX
+#define        ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
+#endif
+
+static unsigned long my_strtoul ();
+
+#if 0
+#ifndef TRUE
+#define TRUE  (1 == 1)
+#define FALSE (1 == 0)
+#endif
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+/* Holding the instruction table this way makes it easier to check the
+   instruction values defined, and to add instructions to the
+   system. However, it makes the process of constructing the simulator
+   a bit more complicated: */
+
+/* The "bitmap" is encoded as follows (NOTE: Only lower-case
+   alphabetic characters should be used, since the letter ordinal is
+   used as a bit position): */
+
+typedef struct operand_encoding {
+ char id; /* character identifier */
+ int fpos; /* first bit position */
+ int flen; /* field length in bits */
+ char * const type;
+ char * const name;
+ unsigned int flags;
+} operand_encoding;
+
+/* Values for the "flags" field: */
+#define OP_NONE   (0 << 0)      /* To keep the source tidy */
+#define OP_GPR    (1 << 0)      /* Get operand from integer register bank */
+#define OP_SIGNX  (1 << 1)      /* Sign-extend the operand */
+#define OP_SHIFT2 (1 << 2)      /* Shift field left by 2 */
+#define OP_BITS5  (1 << 3)      /* Only take the lo 5-bits of the operand */
+#define OP_GPR1   (1 << 4)      /* fetch from the GPR1 registers */
+
+struct operand_encoding opfields[] = {
+ {'0',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit zero */
+ {'1',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit one */
+ {'?',-1,-1,"",      "",              (OP_NONE)},  /* undefined (do not care at this level) */
+ /* The rest are the explicit operand fields: */
+ {'a', 6, 5,"int",   "op1",           (OP_NONE)},  /* shift amount (or hint) */
+ {'b',21, 5,"int",   "fr",            (OP_NONE)},   /* fr register */
+ {'c',16, 1,"int",   "boolean",       (OP_NONE)},  /* TRUE or FALSE boolean */
+ {'d',11, 5,"int",   "destreg",       (OP_NONE)},  /* integer destination/rd register */
+ {'e', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-3bits must be zero) */
+ {'f',17, 1,"int",   "likely",        (OP_NONE)},  /* set if branch LIKELY */
+ {'g',16, 5,"t_reg", "op2",           (OP_GPR)},   /* integer source rt register */
+ {'h', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-1bit must be zero) */
+ {'i', 0,16,"t_reg", "op2",           (OP_SIGNX)}, /* signed immediate (op2) */
+ {'j', 0,26,"ut_reg","op1",           (OP_SHIFT2)},/* shifted left 2 bits and combined with hi-order bits of address in the delay slot */
+ {'k',16, 5,"int",   "ft",            (OP_NONE)},
+ {'l', 0,16,"t_reg", "offset",        (OP_SIGNX | OP_SHIFT2)}, /* signed offset shifted left 2 to make 18bit signed offset */
+ {'m',21, 3,"int",   "format",        (OP_NONE)},  /* FP format field */
+ {'n',16, 5,"int",   "hint",          (OP_NONE)},  /* hint */
+ {'o',21, 5,"t_reg", "op1",           (OP_GPR | OP_BITS5)},  /* integer source/rs register (but never treated as 32bit word) */
+ {'p', 8, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
+ {'q',18, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
+ {'r', 6, 5,"int",   "destreg",       (OP_NONE)},  /* FP fd register */
+ {'s',21, 5,"t_reg", "op1",           (OP_GPR)},   /* integer source/rs register */
+ {'t',16, 5,"int",   "destreg",       (OP_NONE)},  /* integer target rt (destination) register */
+ {'u', 0, 4,"int",   "cmpflags",      (OP_NONE)},  /* FP comparison control flags */
+ {'v',11, 5,"int",   "fs",            (OP_NONE)},  /* FP fs register (or PREFX hint) */
+ {'w', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-2bits must be zero) */
+ {'x',23, 1,"int",   "to",            (OP_NONE)},  /* TRUE if move To; FALSE if move From */
+ {'y', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset */
+ {'z', 0,16,"ut_reg","op2",           (OP_NONE)},  /* unsigned immediate (zero extended) */
+ {'S',21, 5,"t_reg", "rs_reg",  (OP_GPR|OP_GPR1)}, /* rs field, GPR[rs] and GPR1[rs] as source */
+ {'T',16, 5,"t_reg", "rt_reg",  (OP_GPR|OP_GPR1)}, /* rt field, GPR[rt] and GPR1[rt] as source */
+};
+
+
+/* Main instruction encoding types: */
+typedef enum {
+ NORMAL,
+ SPECIAL,
+ REGIMM,
+ COP1,
+ COP1X,
+ COP1S, /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
+
+ MMINORM,
+ MMI0,
+ MMI1,
+ MMI2,
+ MMI3,
+
+ /* mips16 encoding types.  */
+ I, RI, RR, RRI, RRR, RRI_A, ISHIFT, I8, I8_MOVR32, I8_MOV32R, I64, RI64
+} inst_type;
+
+/* Main instruction families: */
+typedef enum {
+ ADD,                  /* res = operand1 + operand2 */
+ SUB,                   /* res = operand1 - operand2 */
+ MUL,                   /* res = operand1 * operand2 */
+ DIV,                   /* res = operand1 / operand2 */
+ AND,                  /* res = operand1 & operand2 */
+ OR,                   /* res = operand1 | operand2 */
+ XOR,                  /* res = operand1 ^ operand2 */
+ MOVE,                  /* res = operand1 */
+ BRANCH,               /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
+ JUMP,                  /* execute delay slot instruction before jump */
+ LOAD,                  /* load from memory */
+ STORE,                 /* store to memory */
+ PREFETCH,              /* prefetch data into cache */
+ SET,                   /* set register on result of condition code */
+ SHIFT,                 /* perform a logical or arithmetic shift */
+ TRAP,                  /* system exception generation */
+ BREAK,                 /* system breakpoint exception generation */
+ SDBBP,                 /* software debug breakpoint exception generation */
+ SYSCALL,               /* system exception generation */
+ SYNC,                  /* system cache control */
+ DECODE,                /* co-processor instruction */
+ CACHE,                 /* co-processor 0 CACHE instruction */
+ MADD16,                /* VR4100 specific multiply-add extensions */
+ FPMOVE,
+ FPMOVEC,
+ FPFLOOR,               
+ FPCEIL,
+ FPTRUNC,
+ FPROUND,
+ FPNEG,
+ FPABS,
+ FPDIV,
+ FPMUL,
+ FPSUB,
+ FPADD,
+ FPPREFX,
+ FPRECIP,
+ FPSQRT,
+ FPCONVERT,
+ FPCOMPARE,
+ MADD,
+ /* start-sanitize-r5900 */
+ PABS,
+ PADD,
+ PADSBH,
+ POP,
+ PCMP,
+ PCPYH,
+ PCPYLD,
+ PCPYUD,
+ PEXCH,
+ PEXCW,
+ PEXOH,
+ PEXOW,
+ PEXTLB,
+ PEXTLH,
+ PEXTLW,
+ PEXTUB,
+ PEXTUH,
+ PEXTUW,
+ PPACB,
+ PPACH,
+ PPACW,
+ PREVH,
+ PROT3W,
+ PINTH,
+ PINTOH,
+ PMXX,
+ PMFHL,
+ PMTHL,
+ PMAXMIN,
+ QFSRV,
+ MxSA,
+ MTSAB,
+ MTSAH,
+ PSHIFT,
+ PSLLVW,
+ PSRLVW,
+ PSRAVW,
+ PLZCW,
+ PHMADDH,
+ PMULTH,
+ PMULTW,
+ PDIVBW,
+ PDIVW,
+ PEXT5,
+ PPAC5,
+ /* end-sanitize-r5900 */
+ NYI,                   /* Not Yet Implemented, placeholder, errors if used */
+ RSVD                   /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "Reserved Instruction" */
+} opcode_type;
+
+/* Flags field: */
+#define NONE           (0 << 0)        /* Zero value (used to keep source tidy) */
+#define SIM_SH_SIZE     (0)
+#define SIM_MASK_SIZE   (0x7)
+#define BYTE            (0)     /*  8bit */
+#define HALFWORD        (1)     /* 16bit */
+#define WORD            (2)     /* 32bit */
+#define DOUBLEWORD      (3)     /* 64bit */
+#define SINGLE          (4)     /* single precision FP */
+#define DOUBLE          (5)     /* double precision FP */
+/* start-sanitize-r5900 */
+#define QUADWORD        (6)     /* 128bit */
+/* end-sanitize-r5900 */
+
+/* Shorthand to get the size field from the flags value: */
+#define GETDATASIZEINSN(i) (((i)->flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
+
+/* The rest are single bit flags: */
+#define MULTIPLY        (1 << 3)        /* actually FP multiply ADD/SUB modifier */
+#define EQ             (1 << 4)
+#define GT             (1 << 5)
+#define LT              (1 << 6)
+#define NOT            (1 << 7)
+#define LIKELY         (1 << 8)
+#define SIGNEXTEND     (1 << 9)
+#define OVERFLOW       (1 << 10)
+#define LINK           (1 << 11)
+#define ATOMIC         (1 << 12)
+#define SHIFT16                (1 << 13)
+#define REG             (1 << 14)
+#define LEFT            (1 << 15)       /* Deliberate explicit encodings to allow check for neither, or both */
+#define RIGHT           (1 << 16)       /* Mutually exclusive with "LEFT" */
+#define LOGICAL         (1 << 17)
+#define ARITHMETIC      (1 << 18)
+#define UNSIGNED        (1 << 19)
+#define HI32            (1 << 20)
+#define HI              (1 << 21)       /* accesses or updates the HI register */
+#define LO              (1 << 22)       /* accesses or updates the LO register */
+#define WORD32         (1 << 23)
+#define FP              (1 << 24)       /* Floating Point operation */
+#define FIXED           (1 << 25)       /* fixed point arithmetic */
+#define COPROC          (1 << 26)
+#define INTEGER         (1 << 27)
+#define CONDITIONAL     (1 << 28)
+#define RECIP           (1 << 29)
+#define CONTROL         (1 << 30)
+#define NOARG           (1 << 31)       /* Instruction has no (defined) operands */
+/* NOTE: We can overload the use of certain of these flags, since not
+   all options are applicable to all instruction types. This will free
+   up more space for new flags. */
+
+/* Overloadings of above bits */
+#define PIPE1        LIKELY      /* Using pipeline 1 (DIV,MUL) */
+#define OP3          EQ          /* 3 operand version of operation  (MUL)     */
+
+#define SATURATE     OVERFLOW    /* for PADD, saturate for overflow           */
+
+#define SUBTRACT     LEFT        /* for PMULT, PMULT becomes PMSUB            */
+#define ADDITION     RIGHT       /* for PMULT, PMULT becomes PMADD            */
+
+#define FROM         LEFT        /* move from special register                */
+#define TO           RIGHT       /* move to special register                  */
+
+/* For bitwise parallel operations */ 
+#define POP_AND      0            /* for POP, op = &                           */
+#define POP_OR       LEFT         /* for POP, op = |                           */
+#define POP_NOR      LIKELY       /* for POP, op = ~(x | y)                    */
+#define POP_XOR      LEFT|LIKELY  /* for POP, op = ^                           */
+
+#define GET_OP_FROM_INSN(insn) (((insn)->flags)&(LEFT|LIKELY))
+
+
+   
+typedef struct instruction {
+ char         *name;   /* ASCII mnemonic name */
+ unsigned int  isa;    /* MIPS ISA number where instruction introduced */
+ char         *bitmap; /* 32character string describing instruction operands */
+ inst_type     mark;   /* type of MIPS instruction encoding */
+ opcode_type   type;   /* main instruction family */
+ unsigned int  flags;  /* flags describing instruction features */
+} instruction;
+/* The number of pipeline cycles taken by an instruction varies
+   between MIPS processors. This means that the information must be
+   encoded elsewhere, in a CPU specific structure. */
+
+/* NOTE: Undefined instructions cause "Reserved Instruction"
+   exceptions. i.e. if there is no bit-mapping defined then the
+   instruction is deemed to be undefined. */
+
+/* NOTE: The "isa" field is also used to encode flags for particular
+   chip architecture extensions. e.g. the NEC VR4100 specific
+   instructions. Normally chip extensions are added via the COP0
+   space. However, the VR4100 (and possibly other devices) also use
+   the normal instruction space. */
+#define MASK_ISA (0x000000FF) /* Start by leaving 8bits for the ISA ID */
+/* The other bits are allocated downwards, to avoid renumbering if we
+   have to extend the bits allocated to the pure ISA number.
+
+   These architecture bits come in two flavors: 
+     ISA dependent - marking insns that should be included in the opcode 
+     set if that architecture is requested on the gencode command line 
+     AND the ISA of the insn is <= requested ISA; 
+   
+     ISA independent - marking insn that should be included in the opcode
+     set if that architecture is requested 
+     OR the ISA of the insn is <= requested ISA. 
+
+   Independent bits are listed in MASK_ISA_INDEP, the rest are dependent.
+ */
+#define ARCH_VR4100       ((unsigned)1 << 31) /* NEC VR4100 extension instructions */
+/* start-sanitize-r5900 */
+#define ARCH_R5900        ((unsigned)1 << 30) /* Toshiba r5900 extension instructions */
+/* end-sanitize-r5900 */
+#define ARCH_R3900        ((unsigned)1 << 29) /* Toshiba r3900 (tx39) */
+/* start-sanitize-tx49 */
+#define ARCH_R4900        ((unsigned)1 << 28) /* Toshiba r4900 (tx49) */
+/* end-sanitize-tx49 */   
+
+/* start-sanitize-tx19 */
+/* The r1900 (tx19) is a tx39 with a mips16 decoder.  For the purposes
+   of implementing the simulator we treat them as the same. */
+/* end-sanitize-tx19 */
+
+/* A list (or'ed) of extension insn sets that can be requested independant of the ISA# */
+#define MASK_ISA_INDEP  (0                                             \
+                         | ARCH_R3900                                  \
+                         /* start-sanitize-tx49 */                     \
+                         | ARCH_R4900                                  \
+                         /* end-sanitize-tx49 */                       \
+                         /* start-sanitize-r5900 */                    \
+                         | ARCH_R5900                                  \
+                         /* end-sanitize-r5900 */                      \
+                         | 0)
+
+#define MASK_ISA_DEP ~(MASK_ISA_INDEP | MASK_ISA)
+
+/* Very short names for use in the table below to keep it neet. */
+#define G1 (3 | ARCH_VR4100)
+
+#define G2 (4                                        \
+            /* start-sanitize-r5900 */               \
+            | ARCH_R5900                             \
+            /* end-sanitize-r5900 */                 \
+            | 0)
+
+#define G3 (4                                                           \
+            /* start-sanitize-r5900 */                                  \
+            /* insn that are not really 5900 insn but were left in */   \
+            /* until we can rewrite the code-gen and libs          */   \
+            | ARCH_R5900                                                \
+            /* end-sanitize-r5900 */                                    \
+            | 0)
+
+#define G4 (2 | ARCH_R3900)
+
+#define G5 (0                                         \
+            | ARCH_R3900                              \
+            /* start-sanitize-tx49 */                 \
+            | ARCH_R4900                              \
+            /* end-sanitize-tx49 */                   \
+            /* start-sanitize-r5900 */                \
+            | ARCH_R5900                              \
+            /* end-sanitize-r5900 */                  \
+            )
+
+#define G6 (3 | ARCH_R3900)
+
+#define G7 (ARCH_R3900                                \
+            /* start-sanitize-tx49 */                 \
+            | ARCH_R4900                              \
+            /* end-sanitize-tx49 */                   \
+            )
+
+#define G8 (4                                         \
+            /* start-sanitize-tx49 */                 \
+            | ARCH_R4900                              \
+            /* end-sanitize-tx49 */                   \
+            /* start-sanitize-r5900 */                \
+            | ARCH_R5900                              \
+            /* end-sanitize-r5900 */                  \
+            )
+
+#define G9 (3                                         \
+            /* start-sanitize-tx49 */                 \
+            | ARCH_R4900                              \
+            /* end-sanitize-tx49 */                   \
+            )
+
+/* start-sanitize-r5900 */
+#define T5 ARCH_R5900       
+/* end-sanitize-r5900 */
+
+
+/* The HIBERNATE, STANDBY and SUSPEND instructions are encoded in the
+   COP0 space. This means that an external decoder should be added
+   when constructing a full VR4100 simulator. However some arithmetic
+   instructions are encoded in the normal instruction space. */
+
+struct instruction MIPS_DECODE[] = {
+ /* The instructions are alphabetical, and not in instruction bit-order: */
+ {"ABS",     1,"01000110mmm00000vvvvvrrrrr000101",COP1,   FPABS,    (FP)},
+ {"ADD",     1,"000000sssssgggggddddd00000100000",SPECIAL,ADD,      (WORD | WORD32 | OVERFLOW)}, /* rd = rs + rt */
+ {"ADD",     1,"01000110mmmkkkkkvvvvvrrrrr000000",COP1,   FPADD,    (FP)},
+ {"ADDI",    1,"001000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32 | OVERFLOW)},
+ {"ADDU",    1,"000000sssssgggggddddd00000100001",SPECIAL,ADD,      (WORD | WORD32)}, /* rd = rs + rt */
+ {"ADDIU",   1,"001001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32)},
+ {"AND",     1,"000000sssssgggggddddd00000100100",SPECIAL,AND,      (NONE)}, /* rd = rs AND rt */
+ {"ANDI",    1,"001100ssssstttttzzzzzzzzzzzzzzzz",NORMAL, AND,      (NONE)},
+ {"BC1",     1,"01000101000qqqfcllllllllllllllll",COP1S,  BRANCH,   (FP)},
+ {"BEQ",     1,"000100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ)},
+ {"BEQL",   G4,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ | LIKELY)},
+ {"BGEZ",    1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ)},
+ {"BGEZAL",  1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
+ {"BGEZALL",G4,"000001sssss10011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
+ {"BGEZL",  G4,"000001sssss00011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LIKELY)},
+ {"BGTZ",    1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT)},
+ {"BGTZL",  G4,"010111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT | LIKELY)},
+ {"BLEZ",    1,"000110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ)},
+ {"BLEZL",  G4,"010110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ | LIKELY)},
+ {"BLTZ",    1,"000001sssss00000llllllllllllllll",REGIMM, BRANCH,   (LT)},
+ {"BLTZAL",  1,"000001sssss10000llllllllllllllll",REGIMM, BRANCH,   (LT | LINK)},
+ {"BLTZALL",G4,"000001sssss10010llllllllllllllll",REGIMM, BRANCH,   (LT | LINK | LIKELY)},
+ {"BLTZL",  G4,"000001sssss00010llllllllllllllll",REGIMM, BRANCH,   (LT | LIKELY)},
+ {"BNE",     1,"000101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ)},
+ {"BNEL",   G4,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ | LIKELY)},
+ {"BREAK",   1,"000000????????????????????001101",SPECIAL,BREAK,    (NOARG)},
+ {"CEIL.L",  3,"01000110mmm00000vvvvvrrrrr001010",COP1,   FPCEIL,   (FP | FIXED | DOUBLEWORD)},
+ {"CEIL.W",  2,"01000110mmm00000vvvvvrrrrr001110",COP1,   FPCEIL,   (FP | FIXED | WORD)},
+ {"COP0",    1,"010000??????????????????????????",NORMAL, DECODE,   (NOARG)},
+ {"COP2",    1,"010010??????????????????????????",NORMAL, DECODE,   (NOARG)},
+ {"CVT.D",   1,"01000110mmm00000vvvvvrrrrr100001",COP1,   FPCONVERT,(FP | DOUBLE)},
+ {"CVT.L",   3,"01000110mmm00000vvvvvrrrrr100101",COP1,   FPCONVERT,(FP | FIXED | DOUBLEWORD)},
+ {"CVT.S",   1,"01000110mmm00000vvvvvrrrrr100000",COP1,   FPCONVERT,(FP | SINGLE)},
+ {"CVT.W",   1,"01000110mmm00000vvvvvrrrrr100100",COP1,   FPCONVERT,(FP | FIXED | WORD)},
+ {"C.%s",    1,"01000110mmmkkkkkvvvvvppp0011uuuu",COP1,   FPCOMPARE,(FP)},
+ {"CxC1",    1,"01000100x10kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD | CONTROL)},
+ {"DADD",    3,"000000sssssgggggddddd00000101100",SPECIAL,ADD,      (DOUBLEWORD | OVERFLOW)},
+ {"DADDI",   3,"011000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | OVERFLOW)},
+ {"DADDU",   3,"000000sssssgggggddddd00000101101",SPECIAL,ADD,      (DOUBLEWORD | UNSIGNED)},
+ {"DADDIU",  3,"011001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | UNSIGNED)},
+ {"DDIV",    3,"000000sssssggggg0000000000011110",SPECIAL,DIV,      (DOUBLEWORD | HI | LO)},
+ {"DDIVU",   3,"000000sssssggggg0000000000011111",SPECIAL,DIV,      (DOUBLEWORD | UNSIGNED | HI | LO)},
+ {"DIV",     1,"000000sssssggggg0000000000011010",SPECIAL,DIV,      (WORD | WORD32 | SIGNEXTEND | HI | LO)},
+ {"DIV",     1,"01000110mmmkkkkkvvvvvrrrrr000011",COP1,   FPDIV,    (FP | WORD | HI | LO)},
+ /* start-sanitize-r5900 */
+ {"DIV1",   T5,"011100sssssggggg0000000000011010",MMINORM,DIV,      (WORD | WORD32 | SIGNEXTEND | HI | LO | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"DIVU",    1,"000000sssssggggg0000000000011011",SPECIAL,DIV,      (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO)},
+ /* start-sanitize-r5900 */
+ {"DIVU1",  T5,"011100sssssggggg0000000000011011",MMINORM,DIV,      (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"DMADD16",G1,"000000sssssggggg0000000000101001",SPECIAL,MADD16,   (DOUBLEWORD | HI | LO)},
+ /* See note near MULT for explanation of 3op-ness. */
+ {"DMULT",  G9,"000000sssssgggggddddd00000011100",SPECIAL,MUL,      (OP3 | DOUBLEWORD | HI | LO)},
+ {"DMULTU", G9,"000000sssssgggggddddd00000011101",SPECIAL,MUL,      (OP3 | DOUBLEWORD | UNSIGNED | HI | LO)},
+ {"DMxC1",   3,"01000100x01kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | DOUBLEWORD)},
+ {"DSLL",    3,"00000000000gggggdddddaaaaa111000",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL)},
+ {"DSLLV",   3,"000000sssssgggggddddd00000010100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL | REG)},
+ {"DSLL32",  3,"00000000000gggggdddddaaaaa111100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL | HI32)}, /* rd = rt << (sa + 32) */
+ {"DSRA",    3,"00000000000gggggdddddaaaaa111011",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC)},
+ {"DSRAV",   3,"000000sssssgggggddddd00000010111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC | REG)},
+ {"DSRA32",  3,"00000000000gggggdddddaaaaa111111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC | HI32)}, /* rd = rt >> (sa + 32) */
+ {"DSRL",    3,"00000000000gggggdddddaaaaa111010",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL)},
+ {"DSRLV",   3,"000000sssssgggggddddd00000010110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL | REG)},
+ {"DSRL32",  3,"00000000000gggggdddddaaaaa111110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL | HI32)},
+ {"DSUB",    3,"000000sssssgggggddddd00000101110",SPECIAL,SUB,      (DOUBLEWORD)},
+ {"DSUBU",   3,"000000sssssgggggddddd00000101111",SPECIAL,SUB,      (DOUBLEWORD | UNSIGNED)},
+ {"FLOOR.L", 3,"01000110mmm00000vvvvvrrrrr001011",COP1,   FPFLOOR,  (FP | FIXED | DOUBLEWORD)},
+ {"FLOOR.W", 2,"01000110mmm00000vvvvvrrrrr001111",COP1,   FPFLOOR,  (FP | FIXED | WORD)},
+ {"J",       1,"000010jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (NONE)},                   /* NOTE: boundary case due to delay slot address being used */
+ {"JAL",     1,"000011jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (LINK)},                   /* NOTE: boundary case due to delay slot address being used */
+ {"JALR",    1,"000000sssss00000ddddd00000001001",SPECIAL,JUMP,     (LINK | REG)},
+ {"JALX",    1,"011101jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (LINK | NOT)},
+ {"JR",      1,"000000sssss000000000000000001000",SPECIAL,JUMP,     (NONE)}, /* need to check PC as part of instruction fetch */
+ {"LB",      1,"100000ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE | SIGNEXTEND)},      /* NOTE: "i" rather than "o" because BYTE addressing is allowed */
+ {"LBU",     1,"100100ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE)},                   /* NOTE: See "LB" comment */
+ {"LD",      3,"110111sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD)},
+ {"LDC1",    2,"110101sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
+ {"LDC2",    2,"110110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
+ {"LDL",     3,"011010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | LEFT)},      /* NOTE: See "LB" comment */
+ {"LDR",     3,"011011ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | RIGHT)},     /* NOTE: See "LB" comment */
+ {"LDXC1",  G3,"010011sssssggggg00000rrrrr000001",COP1X,  LOAD,     (FP | DOUBLEWORD | COPROC | REG)},
+ {"LH",      1,"100001sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD | SIGNEXTEND)},
+ {"LHU",     1,"100101sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD)},
+ {"LL",      2,"110000ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | ATOMIC | SIGNEXTEND)},
+ {"LLD",     3,"110100sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | ATOMIC)},
+ {"LUI",     1,"00111100000tttttiiiiiiiiiiiiiiii",NORMAL, MOVE,     (SHIFT16)}, /* Cheat and specify sign-extension of immediate field */
+ /* start-sanitize-r5900 */
+ {"LQ",     T5,"011110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (QUADWORD)},
+ /* end-sanitize-r5900 */
+ {"LW",      1,"100011ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | SIGNEXTEND)},
+ {"LWC1",    1,"110001ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
+ {"LWC2",    1,"110010ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
+ {"LWL",     1,"100010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | LEFT)},
+ {"LWR",     1,"100110ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | RIGHT)},
+ {"LWU",     3,"100111ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD)},
+ {"LWXC1",  G3,"010011sssssggggg00000rrrrr000000",COP1X,  LOAD,     (FP | WORD | COPROC | REG)},
+ {"MADD",   G5,"011100sssssgggggddddd00000000000",MMINORM,MADD,     (NONE)},
+ {"MADDU",  G5,"011100sssssgggggddddd00000000001",MMINORM,MADD,     (UNSIGNED)},
+ /* start-sanitize-r5900 */
+ {"MADD1",  T5,"011100sssssgggggddddd00000100000",MMINORM,MADD,     (PIPE1)},
+ {"MADDU1", T5,"011100sssssgggggddddd00000100001",MMINORM,MADD,     (UNSIGNED | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"MADD16", G1,"000000sssssggggg0000000000101000",SPECIAL,MADD16,   (WORD | HI | LO)},
+ {"MADD.D", G3,"010011bbbbbkkkkkvvvvvrrrrr100001",COP1X,  FPADD,    (FP | MULTIPLY | DOUBLE)},
+ {"MADD.S", G3,"010011bbbbbkkkkkvvvvvrrrrr100000",COP1X,  FPADD,    (FP | MULTIPLY | SINGLE)},
+ {"MFHI",    1,"0000000000000000ddddd00000010000",SPECIAL,MOVE,     (HI | LEFT)},    /* with following, from and to denoted by usage of LEFT or RIGHT */
+ /* start-sanitize-r5900 */
+ {"MFHI1",  T5,"0111000000000000ddddd00000010000",MMINORM,MOVE,     (HI | LEFT | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"MFLO",    1,"0000000000000000ddddd00000010010",SPECIAL,MOVE,     (LO | LEFT)},
+ /* start-sanitize-r5900 */
+ {"MFLO1",  T5,"0111000000000000ddddd00000010010",MMINORM,MOVE,     (LO | LEFT | PIPE1)},
+ {"MFSA",   T5,"0000000000000000ddddd00000101000",SPECIAL,MxSA,     (FROM)},
+ /* end-sanitize-r5900 */
+ {"MTHI",    1,"000000sssss000000000000000010001",SPECIAL,MOVE,     (HI | RIGHT)},
+ /* start-sanitize-r5900 */
+ {"MTHI1",  T5,"011100sssss000000000000000010001",MMINORM,MOVE,     (HI | RIGHT | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"MTLO",    1,"000000sssss000000000000000010011",SPECIAL,MOVE,     (LO | RIGHT)},
+ /* start-sanitize-r5900 */
+ {"MTLO1",  T5,"011100sssss000000000000000010011",MMINORM,MOVE,     (LO | RIGHT | PIPE1)},
+ {"MTSA",   T5,"000000sssss000000000000000101001",SPECIAL,MxSA,     (TO)},
+ {"MTSAB",  T5,"000001sssss11000iiiiiiiiiiiiiiii",REGIMM, MTSAB,    (NONE)},
+ {"MTSAH",  T5,"000001sssss11001iiiiiiiiiiiiiiii",REGIMM, MTSAH,    (NONE)},
+ /* end-sanitize-r5900 */
+ {"MOV",     1,"01000110mmm00000vvvvvrrrrr000110",COP1,   FPMOVE,   (FP)},
+ {"MOVN",   G2,"000000sssssgggggddddd00000001011",SPECIAL,MOVE,     (NOT | EQ)},
+ {"MOVN",   G2,"01000110mmmgggggvvvvvrrrrr010011",COP1,   FPMOVE,   (FP | NOT | EQ)},
+ {"MOV%c",  G3,"000000sssssqqq0cddddd00000000001",SPECIAL,FPMOVE,   (FP | CONDITIONAL | INTEGER)},
+ {"MOV%c",  G3,"01000110mmmqqq0cvvvvvrrrrr010001",COP1,   FPMOVE,   (FP | CONDITIONAL)},
+ {"MOVZ",   G2,"000000sssssgggggddddd00000001010",SPECIAL,MOVE,     (EQ)},
+ {"MOVZ",   G2,"01000110mmmgggggvvvvvrrrrr010010",COP1,   FPMOVE,   (FP | EQ)},
+ {"MSUB.D", G3,"010011bbbbbkkkkkvvvvvrrrrr101001",COP1X,  FPSUB,    (FP | MULTIPLY | DOUBLE)},
+ {"MSUB.S", G3,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X,  FPSUB,    (FP | MULTIPLY | SINGLE)},
+ {"MUL",     1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1,   FPMUL,    (FP | HI | LO)},
+ /* The 3op version of MULT and MULTU are TX39 (and related chips) specific.
+    They should be removed from other chips sets, so that using the 3op opcode
+    causes a reserved instruction exception, but gencode can't deal with
+    that currently. */
+ {"MULT",    1,"000000sssssgggggddddd00000011000",SPECIAL,MUL,      (OP3 | WORD | WORD32 | HI | LO)},
+ /* start-sanitize-r5900 */
+ {"MULT1",  T5,"011100sssssgggggddddd00000011000",MMINORM,MUL,      (OP3 | WORD | WORD32 | HI | LO | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"MULTU",   1,"000000sssssgggggddddd00000011001",SPECIAL,MUL,      (OP3 | WORD | WORD32 | UNSIGNED | HI | LO)},
+ /* start-sanitize-r5900 */
+ {"MULTU1", T5,"011100sssssgggggddddd00000011001",MMINORM,MUL,      (OP3 | WORD | WORD32 | UNSIGNED | HI | LO | PIPE1)},
+ /* end-sanitize-r5900 */
+ {"MxC1",    1,"01000100x00kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD)},
+ {"NEG",     1,"01000110mmm00000vvvvvrrrrr000111",COP1,   FPNEG,    (FP)},
+ {"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X,  FPADD,    (FP | NOT | MULTIPLY | DOUBLE)},
+ {"NMADD.S", 4,"010011bbbbbkkkkkvvvvvrrrrr110000",COP1X,  FPADD,    (FP | NOT | MULTIPLY | SINGLE)},
+ {"NMSUB.D", 4,"010011bbbbbkkkkkvvvvvrrrrr111001",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | DOUBLE)},
+ {"NMSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr111000",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | SINGLE)},
+ {"NOR",     1,"000000sssssgggggddddd00000100111",SPECIAL,OR,       (NOT)},
+ {"OR",      1,"000000sssssgggggddddd00000100101",SPECIAL,OR,       (NONE)},
+ {"ORI",     1,"001101ssssstttttzzzzzzzzzzzzzzzz",NORMAL, OR,       (NONE)},
+
+ /* start-sanitize-r5900 */
+ {"PABSH",  T5,"01110000000TTTTTddddd00101101000",MMI1,   PABS,     (HALFWORD)},
+ {"PABSW",  T5,"01110000000TTTTTddddd00001101000",MMI1,   PABS,     (WORD)},
+
+ {"PADDB",  T5,"011100SSSSSTTTTTddddd01000001000",MMI0,   PADD,     (BYTE)},
+ {"PADDH",  T5,"011100SSSSSTTTTTddddd00100001000",MMI0,   PADD,     (HALFWORD)},
+ {"PADDW",  T5,"011100SSSSSTTTTTddddd00000001000",MMI0,   PADD,     (WORD)},
+
+ {"PADDSB", T5,"011100SSSSSTTTTTddddd11000001000",MMI0,   PADD,     (BYTE | SATURATE)},
+ {"PADDSH", T5,"011100SSSSSTTTTTddddd10100001000",MMI0,   PADD,     (HALFWORD | SATURATE)},
+ {"PADDSW", T5,"011100SSSSSTTTTTddddd10000001000",MMI0,   PADD,     (WORD | SATURATE)},
+
+ {"PADDUB", T5,"011100SSSSSTTTTTddddd11000101000",MMI1,   PADD,     (BYTE | UNSIGNED)},
+ {"PADDUH", T5,"011100SSSSSTTTTTddddd10100101000",MMI1,   PADD,     (HALFWORD | UNSIGNED)},
+ {"PADDUW", T5,"011100SSSSSTTTTTddddd10000101000",MMI1,   PADD,     (WORD | UNSIGNED)},
+
+ {"PADSBH", T5,"011100SSSSSTTTTTddddd00100101000",MMI1,   PADSBH,   (NONE)},
+
+ {"PAND",   T5,"011100SSSSSTTTTTddddd10010001001",MMI2,   POP,      (POP_AND)},
+
+ {"PCEQB",  T5,"011100SSSSSTTTTTddddd01010101000",MMI1,   PCMP,     (EQ | BYTE)},
+ {"PCEQH",  T5,"011100SSSSSTTTTTddddd00110101000",MMI1,   PCMP,     (EQ | HALFWORD)},
+ {"PCEQW",  T5,"011100SSSSSTTTTTddddd00010101000",MMI1,   PCMP,     (EQ | WORD)},
+
+ {"PCGTB",  T5,"011100SSSSSTTTTTddddd01010001000",MMI0,   PCMP,     (GT | BYTE)},
+ {"PCGTH",  T5,"011100SSSSSTTTTTddddd00110001000",MMI0,   PCMP,     (GT | HALFWORD)},
+ {"PCGTW",  T5,"011100SSSSSTTTTTddddd00010001000",MMI0,   PCMP,     (GT | WORD)},
+
+ {"PCPYH",  T5,"01110000000TTTTTddddd11011101001",MMI3,   PCPYH,    (NONE)},
+ {"PCPYLD", T5,"011100SSSSSTTTTTddddd01110001001",MMI2,   PCPYLD,   (NONE)},
+ {"PCPYUD", T5,"011100SSSSSTTTTTddddd01110101001",MMI3,   PCPYUD,   (NONE)},
+
+ {"PDIVBW", T5,"011100SSSSSTTTTT0000011101001001",MMI2,   PDIVBW,   (NONE)},
+ {"PDIVUW", T5,"011100SSSSSTTTTT0000001101101001",MMI3,   PDIVW,    (UNSIGNED)},
+ {"PDIVW",  T5,"011100SSSSSTTTTT0000001101001001",MMI2,   PDIVW,    (NONE)},
+ {"PEXCH",  T5,"01110000000TTTTTddddd11010101001",MMI3,   PEXCH,    (NONE)},
+ {"PEXCW",  T5,"01110000000TTTTTddddd11110101001",MMI3,   PEXCW,    (NONE)},
+ {"PEXOH",  T5,"01110000000TTTTTddddd11010001001",MMI2,   PEXOH,    (NONE)},
+ {"PEXOW",  T5,"01110000000TTTTTddddd11110001001",MMI2,   PEXOW,    (NONE)},
+
+ {"PEXT5",  T5,"01110000000TTTTTddddd11110001000",MMI0,   PEXT5,    (NONE)},
+
+ {"PEXTLB", T5,"011100SSSSSTTTTTddddd11010001000",MMI0,   PEXTLB,   (NONE)},
+ {"PEXTLH", T5,"011100SSSSSTTTTTddddd10110001000",MMI0,   PEXTLH,   (NONE)},
+ {"PEXTLW", T5,"011100SSSSSTTTTTddddd10010001000",MMI0,   PEXTLW,   (NONE)},
+ {"PEXTUB", T5,"011100SSSSSTTTTTddddd11010101000",MMI1,   PEXTUB,   (NONE)},
+ {"PEXTUH", T5,"011100SSSSSTTTTTddddd10110101000",MMI1,   PEXTUH,   (NONE)},
+ {"PEXTUW", T5,"011100SSSSSTTTTTddddd10010101000",MMI1,   PEXTUW,   (NONE)},
+
+ {"PHMADDH",T5,"011100SSSSSTTTTTddddd10001001001",MMI2,   PHMADDH,  (NONE)},
+ {"PHMSUBH",T5,"011100SSSSSTTTTTddddd10101001001",MMI2,   PHMADDH,  (SUBTRACT)},
+
+ {"PINTH",  T5,"011100SSSSSTTTTTddddd01010001001",MMI2,   PINTH,    (NONE)},
+ {"PINTOH", T5,"011100SSSSSTTTTTddddd01010101001",MMI3,   PINTOH,   (NONE)},
+
+ {"PLZCW",  T5,"011100SSSSS00000ddddd00000000100",MMINORM,PLZCW,    (NONE)},
+
+ {"PMADDH", T5,"011100SSSSSTTTTTddddd10000001001",MMI2,   PMULTH,   (ADDITION)},
+ {"PMADDUW",T5,"011100SSSSSTTTTTddddd00000101001",MMI3,   PMULTW,   (ADDITION | UNSIGNED)},
+ {"PMADDW", T5,"011100SSSSSTTTTTddddd00000001001",MMI2,   PMULTW,   (ADDITION)},
+
+ {"PMAXH",  T5,"011100SSSSSTTTTTddddd00111001000",MMI0,   PMAXMIN,  (GT | HALFWORD)},
+ {"PMAXW",  T5,"011100SSSSSTTTTTddddd00011001000",MMI0,   PMAXMIN,  (GT | WORD)},
+
+ {"PMFHI",  T5,"0111000000000000ddddd01000001001",MMI2,   PMXX,     (HI|FROM)},
+ {"PMFLO",  T5,"0111000000000000ddddd01001001001",MMI2,   PMXX,     (LO|FROM)},
+
+ {"PMFHL",  T5,"0111000000000000dddddaaaaa110000",MMINORM,PMFHL,    (NONE)},
+
+ {"PMINH",  T5,"011100SSSSSTTTTTddddd00111101000",MMI1,   PMAXMIN,  (LT | HALFWORD)},
+ {"PMINW",  T5,"011100SSSSSTTTTTddddd00011101000",MMI1,   PMAXMIN,  (LT | WORD)},
+
+ {"PMSUBH", T5,"011100SSSSSTTTTTddddd10100001001",MMI2,   PMULTH,   (SUBTRACT)},
+ {"PMSUBW", T5,"011100SSSSSTTTTTddddd00100001001",MMI2,   PMULTW,   (SUBTRACT)},
+
+ {"PMTHI",  T5,"011100SSSSS000000000001000101001",MMI3,   PMXX,     (HI|TO)},
+ {"PMTLO",  T5,"011100SSSSS000000000001001101001",MMI3,   PMXX,     (LO|TO)},
+
+{"PMTHL.LW",T5,"011100SSSSS000000000000000110001",MMINORM,PMTHL,    (NONE)},
+
+ {"PMULTH", T5,"011100SSSSSTTTTTddddd11100001001",MMI2,   PMULTH,   (NONE)},
+ {"PMULTUW",T5,"011100SSSSSTTTTTddddd01100101001",MMI3,   PMULTW,   (UNSIGNED)},
+ {"PMULTW", T5,"011100SSSSSTTTTTddddd01100001001",MMI2,   PMULTW,   (NONE)},
+
+ {"PNOR",   T5,"011100SSSSSTTTTTddddd10011101001",MMI3,   POP,      (POP_NOR)},
+ {"POR",    T5,"011100SSSSSTTTTTddddd10010101001",MMI3,   POP,      (POP_OR)},
+
+ {"PPAC5",  T5,"01110000000TTTTTddddd11111001000",MMI0,   PPAC5,    (NONE)},
+
+ {"PPACB",  T5,"011100SSSSSTTTTTddddd11011001000",MMI0,   PPACB,    (NONE)},
+ {"PPACH",  T5,"011100SSSSSTTTTTddddd10111001000",MMI0,   PPACH,    (NONE)},
+ {"PPACW",  T5,"011100SSSSSTTTTTddddd10011001000",MMI0,   PPACW,    (NONE)},
+
+ {"PREVH",  T5,"01110000000TTTTTddddd11011001001",MMI2,   PREVH,    (NONE)},
+ {"PROT3W", T5,"01110000000TTTTTddddd11111001001",MMI2,   PROT3W,   (NONE)},
+
+ {"PSLLH",  T5,"01110000000TTTTTdddddaaaaa110100",MMINORM,PSHIFT,   (LEFT | LOGICAL | HALFWORD)},
+ {"PSLLVW", T5,"011100SSSSSTTTTTddddd00010001001",MMI2,   PSLLVW,   (NONE)},
+ {"PSLLW",  T5,"01110000000TTTTTdddddaaaaa111100",MMINORM,PSHIFT,   (LEFT | LOGICAL | WORD)},
+
+ {"PSRAH",  T5,"01110000000TTTTTdddddaaaaa110111",MMINORM,PSHIFT,   (RIGHT | ARITHMETIC | HALFWORD)},
+ {"PSRAVW", T5,"011100SSSSSTTTTTddddd00011101001",MMI3,   PSRAVW,   (NONE)},
+ {"PSRAW",  T5,"01110000000TTTTTdddddaaaaa111111",MMINORM,PSHIFT,   (RIGHT | ARITHMETIC | WORD)},
+
+ {"PSRLH",  T5,"01110000000TTTTTdddddaaaaa110110",MMINORM,PSHIFT,   (RIGHT | LOGICAL | HALFWORD)},
+ {"PSRLVW", T5,"011100SSSSSTTTTTddddd00011001001",MMI2,   PSRLVW,   (NONE)},
+ {"PSRLW",  T5,"01110000000TTTTTdddddaaaaa111110",MMINORM,PSHIFT,   (RIGHT | LOGICAL | WORD)},
+
+ {"PSUBB",  T5,"011100SSSSSTTTTTddddd01001001000",MMI0,   PADD,     (SUBTRACT | BYTE)},
+ {"PSUBH",  T5,"011100SSSSSTTTTTddddd00101001000",MMI0,   PADD,     (SUBTRACT | HALFWORD)},
+ {"PSUBSB", T5,"011100SSSSSTTTTTddddd11001001000",MMI0,   PADD,     (SUBTRACT | SATURATE | BYTE )},
+ {"PSUBSH", T5,"011100SSSSSTTTTTddddd10101001000",MMI0,   PADD,     (SUBTRACT | SATURATE | HALFWORD)},
+ {"PSUBSW", T5,"011100SSSSSTTTTTddddd10001001000",MMI0,   PADD,     (SUBTRACT | SATURATE | WORD)},
+ {"PSUBUB", T5,"011100SSSSSTTTTTddddd11001101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | BYTE)},
+ {"PSUBUH", T5,"011100SSSSSTTTTTddddd10101101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | HALFWORD)},
+ {"PSUBUW", T5,"011100SSSSSTTTTTddddd10001101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | WORD)},
+ {"PSUBW",  T5,"011100SSSSSTTTTTddddd00001001000",MMI0,   PADD,     (SUBTRACT | WORD)},
+
+ {"PXOR",   T5,"011100SSSSSTTTTTddddd10011001001",MMI2,   POP,      (POP_XOR)},
+ /* end-sanitize-r5900 */
+
+ {"PREF",   G8,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
+ {"PREFX",   4,"010011sssssgggggvvvvv00000001111",COP1X,  FPPREFX,  (FP)},
+
+ /* start-sanitize-r5900 */
+ {"QFSRV",  T5,"011100SSSSSTTTTTddddd11011101000",MMI1,   QFSRV,    (NONE)},
+ /* end-sanitize-r5900 */
+
+ {"RECIP",   4,"01000110mmm00000vvvvvrrrrr010101",COP1,   FPRECIP,  (FP)},
+ {"ROUND.L", 3,"01000110mmm00000vvvvvrrrrr001000",COP1,   FPROUND,  (FP | FIXED | DOUBLEWORD)},
+ {"ROUND.W", 2,"01000110mmm00000vvvvvrrrrr001100",COP1,   FPROUND,  (FP | FIXED | WORD)},
+ {"RSQRT",   4,"01000110mmm00000vvvvvrrrrr010110",COP1,   FPSQRT,   (FP | RECIP)},
+ {"SB",      1,"101000sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (BYTE)},
+ {"SC",      2,"111000sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | ATOMIC)},
+ {"SCD",     3,"111100sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | ATOMIC)},
+ {"SD",      3,"111111sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD)},
+ {"SDC1",    2,"111101sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
+ {"SDBBP",  G7,"000000????????????????????001110",SPECIAL,SDBBP,    (NOARG)},
+ {"SDC2",    2,"111110sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
+ {"SDL",     3,"101100sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | LEFT)},
+ {"SDR",     3,"101101sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | RIGHT)},
+ {"SDXC1",  G3,"010011sssssgggggvvvvv00000001001",COP1X,  STORE,    (FP | DOUBLEWORD | COPROC | REG)},
+ {"SH",      1,"101001sssssggggghhhhhhhhhhhhhhhh",NORMAL, STORE,    (HALFWORD)},
+ {"SLL",     1,"00000000000gggggdddddaaaaa000000",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << sa */
+ {"SLLV",    1,"000000ooooogggggddddd00000000100",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << rs - with "SLL" depends on "s" and "a" field values */
+ {"SLT",     1,"000000sssssgggggddddd00000101010",SPECIAL,SET,      (LT)},
+ {"SLTI",    1,"001010ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT)},
+ {"SLTU",    1,"000000sssssgggggddddd00000101011",SPECIAL,SET,      (LT | UNSIGNED)},
+ {"SLTIU",   1,"001011ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT | UNSIGNED)},
+ /* start-sanitize-r5900 */
+ {"SQ",     T5,"011111sssssTTTTTeeeeeeeeeeeeeeee",NORMAL, STORE,    (QUADWORD)},
+ /* end-sanitize-r5900 */
+ {"SQRT",    2,"01000110mmm00000vvvvvrrrrr000100",COP1,   FPSQRT,   (FP)},
+ {"SRA",     1,"00000000000gggggdddddaaaaa000011",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
+ {"SRAV",    1,"000000ooooogggggddddd00000000111",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
+ {"SRL",     1,"00000000000gggggdddddaaaaa000010",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
+ {"SRLV",    1,"000000ooooogggggddddd00000000110",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
+ {"SUB",     1,"000000sssssgggggddddd00000100010",SPECIAL,SUB,      (WORD | WORD32 | OVERFLOW)},
+ {"SUB",     1,"01000110mmmkkkkkvvvvvrrrrr000001",COP1,   FPSUB,    (FP)},
+ {"SUBU",    1,"000000sssssgggggddddd00000100011",SPECIAL,SUB,      (WORD | WORD32)},
+ {"SW",      1,"101011sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD)},
+ {"SWC1",    1,"111001ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
+ {"SWC2",    1,"111010ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
+ {"SWL",     1,"101010sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | LEFT)},
+ {"SWR",     1,"101110sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | RIGHT)},
+ {"SWXC1",  G3,"010011sssssgggggvvvvv00000001000",COP1X,  STORE,    (FP | WORD | COPROC | REG)},
+ {"SYNC",   G4,"000000000000000000000aaaaa001111",SPECIAL,SYNC,     (NONE)}, /* z = 5bit stype field */
+ {"SYSCALL", 1,"000000????????????????????001100",SPECIAL,SYSCALL,  (NOARG)},
+ {"TEQ",     2,"000000sssssggggg??????????110100",SPECIAL,TRAP,     (EQ)},
+ {"TEQI",    2,"000001sssss01100iiiiiiiiiiiiiiii",REGIMM, TRAP,     (EQ)},
+ {"TGE",     2,"000000sssssggggg??????????110000",SPECIAL,TRAP,     (GT | EQ)},
+ {"TGEI",    2,"000001sssss01000iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ)},
+ {"TGEIU",   2,"000001sssss01001iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ | UNSIGNED)},
+ {"TGEU",    2,"000000sssssggggg??????????110001",SPECIAL,TRAP,     (GT | EQ | UNSIGNED)},
+ {"TLT",     2,"000000sssssggggg??????????110010",SPECIAL,TRAP,     (LT)},
+ {"TLTI",    2,"000001sssss01010iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT)},
+ {"TLTIU",   2,"000001sssss01011iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT | UNSIGNED)},
+ {"TLTU",    2,"000000sssssggggg??????????110011",SPECIAL,TRAP,     (LT | UNSIGNED)},
+ {"TNE",     2,"000000sssssggggg??????????110110",SPECIAL,TRAP,     (NOT | EQ)},
+ {"TNEI",    2,"000001sssss01110iiiiiiiiiiiiiiii",REGIMM, TRAP,     (NOT | EQ)},
+ {"TRUNC.L", 3,"01000110mmm00000vvvvvrrrrr001001",COP1,   FPTRUNC,  (FP | FIXED | DOUBLEWORD)},
+ {"TRUNC.W", 2,"01000110mmm00000vvvvvrrrrr001101",COP1,   FPTRUNC,  (FP | FIXED | WORD)},
+ {"XOR",     1,"000000sssssgggggddddd00000100110",SPECIAL,XOR,      (NONE)},
+ {"XORI",    1,"001110ssssstttttzzzzzzzzzzzzzzzz",NORMAL, XOR,      (NONE)},
+ {"CACHE",  G6,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE,    (NONE)},
+ {"<INT>",   1,"111011sssssgggggyyyyyyyyyyyyyyyy",NORMAL, RSVD,     (NONE)},
+};
+
+static const struct instruction MIPS16_DECODE[] = {
+{"ADDIU",   1, "01000xxxddd04444",  RRI_A,   ADD,     WORD | WORD32 },
+{"ADDIU8",  1, "01001wwwkkkkkkkk",  RI,      ADD,     WORD | WORD32 },
+{"ADJSP",   1, "01100011KKKKKKKKS", I8,      ADD,     WORD | WORD32 },
+{"ADDIUPC", 1, "00001dddAAAAAAAAP", RI,      ADD,     WORD | WORD32 },
+{"ADDIUSP", 1, "00000dddAAAAAAAAs", RI,      ADD,     WORD | WORD32 },
+{"ADDU",    1, "11100xxxyyyddd01",  RRR,     ADD,     WORD | WORD32 },
+{"AND",            1, "11101wwwyyy01100",  RR,      AND,     NONE },
+{"B",      1, "00010qqqqqqqqqqqzZ", I,      BRANCH,  EQ },
+{"BEQZ",    1, "00100xxxppppppppz", RI,      BRANCH,  EQ },
+{"BNEZ",    1, "00101xxxppppppppz", RI,      BRANCH,  NOT | EQ },
+{"BREAK",   1, "01100??????00101",  RR,      BREAK,   NOARG },
+{"BTEQZ",   1, "01100000pppppppptz", I8,     BRANCH,  EQ },
+{"BTNEZ",   1, "01100001pppppppptz", I8,     BRANCH,  NOT | EQ },
+{"CMP",     1, "11101xxxyyy01010T", RR,      XOR,     NONE },
+{"CMPI",    1, "01110xxxUUUUUUUUT", RI,      XOR,     NONE },
+{"DADDIU",  3, "01000xxxddd14444",  RRI_A,   ADD,     DOUBLEWORD },
+{"DADDIU5", 3, "11111101wwwjjjjj",  RI64,    ADD,     DOUBLEWORD },
+{"DADJSP",  3, "11111011KKKKKKKKS", I64,     ADD,     DOUBLEWORD },
+{"DADIUPC", 3, "11111110dddEEEEEP", RI64,    ADD,     DOUBLEWORD },
+{"DADIUSP", 3, "11111111dddEEEEEs", RI64,    ADD,     DOUBLEWORD },
+{"DADDU",   3, "11100xxxyyyddd00",  RRR,     ADD,     DOUBLEWORD },
+{"DDIV",    3, "11101xxxyyy11110",  RR,      DIV,     DOUBLEWORD | HI | LO },
+{"DDIVU",   3, "11101xxxyyy11111",  RR,      DIV,     DOUBLEWORD | UNSIGNED | HI | LO },
+{"DIV",            1, "11101xxxyyy11010",  RR,      DIV,     WORD | WORD32 | SIGNEXTEND | HI | LO },
+{"DIVU",    1, "11101xxxyyy11011",  RR,      DIV,     WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO },
+{"DMULT",   3, "11101xxxyyy11100",  RR,      MUL,     DOUBLEWORD | HI | LO },
+{"DMULTU",  3, "11101xxxyyy11101",  RR,      MUL,     DOUBLEWORD | UNSIGNED | HI | LO },
+{"DSLL",    3, "00110dddyyy[[[01",  ISHIFT,  SHIFT,   DOUBLEWORD | LEFT | LOGICAL },
+{"DSLLV",   3, "11101xxxvvv10100",  RR,      SHIFT,   DOUBLEWORD | LEFT | LOGICAL | REG },
+{"DSRA",    3, "11101]]]vvv10011",  RR,      SHIFT,   DOUBLEWORD | RIGHT | ARITHMETIC },
+{"DSRAV",   3, "11101xxxvvv10111",  RR,      SHIFT,   DOUBLEWORD | RIGHT | ARITHMETIC | REG},
+{"DSRL",    3, "11101]]]vvv01000",  RR,      SHIFT,   DOUBLEWORD | RIGHT | LOGICAL },
+{"DSRLV",   3, "11101xxxvvv10110",  RR,      SHIFT,   DOUBLEWORD | RIGHT | LOGICAL | REG},
+{"DSUBU",   3, "11100xxxyyyddd10",  RRR,     SUB,     DOUBLEWORD | UNSIGNED},
+#if 0
+  /* FIXME: Should we handle these ourselves, or should we require an
+     emulation routine?  */
+{"EXIT",    1, "1110111100001000",  RR,      BREAK,   EXIT },
+{"ENTRY",   1, "11101??????01000",  RR,      BREAK,   ENTRY },
+#endif
+{"EXTEND",  1, "11110eeeeeeeeeee",  I,       RSVD,    NOARG },
+{"JALR",    1, "11101xxx01000000R", RR,      JUMP,    LINK | REG },
+{"JAL",     1, "00011aaaaaaaaaaa",  I,       JUMP,    LINK },
+{"JR",      1, "11101xxx00000000",  RR,      JUMP,    NONE },
+{"JRRA",    1, "1110100000100000r", RR,      JUMP,    NONE },
+{"LB",      1, "10000xxxddd55555",  RRI,     LOAD,    BYTE | SIGNEXTEND },
+{"LBU",     1, "10100xxxddd55555",  RRI,     LOAD,    BYTE },
+{"LD",      3, "00111xxxdddDDDDD",  RRI,     LOAD,    DOUBLEWORD },
+{"LDPC",    3, "11111100dddDDDDDP", RI64,    LOAD,    DOUBLEWORD },
+{"LDSP",    3, "11111000dddDDDDDs", RI64,    LOAD,    DOUBLEWORD },
+{"LH",      1, "10001xxxdddHHHHH",  RRI,     LOAD,    HALFWORD | SIGNEXTEND },
+{"LHU",     1, "10101xxxdddHHHHH",  RRI,     LOAD,    HALFWORD },
+{"LI",      1, "01101dddUUUUUUUUZ", RI,      OR,      NONE },
+{"LW",      1, "10011xxxdddWWWWW",  RRI,     LOAD,    WORD | SIGNEXTEND },
+{"LWPC",    1, "10110dddVVVVVVVVP", RI,      LOAD,    WORD | SIGNEXTEND },
+{"LWSP",    1, "10010dddVVVVVVVVs", RI,      LOAD,    WORD | SIGNEXTEND },
+{"LWU",     1, "10111xxxdddWWWWW",  RRI,     LOAD,    WORD },
+{"MFHI",    1, "11101ddd00010000",  RR,      MOVE,    HI | LEFT },
+{"MFLO",    1, "11101ddd00010010",  RR,      MOVE,    LO | LEFT },
+{"MOVR32",  1, "01100111dddXXXXXz", I8_MOVR32, OR,    NONE },
+{"MOV32R",  1, "01100101YYYYYxxxz", I8_MOV32R, OR,    NONE },
+{"MULT",    1, "11101xxxyyy11000",  RR,      MUL,     WORD | WORD32 | HI | LO},
+{"MULTU",   1, "11101xxxyyy11001",  RR,      MUL,     WORD | WORD32 | UNSIGNED | HI | LO },
+{"NEG",     1, "11101dddyyy01011Z", RR,      SUB,     WORD },
+{"NOT",     1, "11101dddyyy01111Z", RR,      OR,      NOT },
+{"OR",      1, "11101wwwyyy01101",  RR,      OR,      NONE },
+{"SB",      1, "11000xxxyyy55555",  RRI,     STORE,   BYTE },
+{"SDBBP",  G7, "11100??????00001",  RR,      SDBBP,   NOARG },
+{"SD",      3, "01111xxxyyyDDDDD",  RRI,     STORE,   DOUBLEWORD },
+{"SDSP",    3, "11111001yyyDDDDDs", RI64,    STORE,   DOUBLEWORD },
+{"SDRASP",  3, "11111010CCCCCCCCsQ", I64,    STORE,   DOUBLEWORD },
+{"SH",      1, "11001xxxyyyHHHHH",  RRI,     STORE,   HALFWORD },
+{"SLL",     1, "00110dddyyy<<<00",  ISHIFT,  SHIFT,   WORD | LEFT | LOGICAL },
+{"SLLV",    1, "11101xxxvvv00100",  RR,      SHIFT,   WORD | LEFT | LOGICAL | REG},
+{"SLT",     1, "11101xxxyyy00010T", RR,      SET,     LT },
+{"SLTI",    1, "01010xxx88888888T", RI,      SET,     LT },
+{"SLTU",    1, "11101xxxyyy00011T", RR,      SET,     LT | UNSIGNED },
+{"SLTIU",   1, "01011xxx88888888T", RI,      SET,     LT | UNSIGNED },
+{"SRA",     1, "00110dddyyy<<<11",  ISHIFT,  SHIFT,   WORD | WORD32 | RIGHT | ARITHMETIC },
+{"SRAV",    1, "11101xxxvvv00111",  RR,      SHIFT,   WORD | WORD32 | RIGHT | ARITHMETIC | REG },
+{"SRL",     1, "00110dddyyy<<<10",  ISHIFT,  SHIFT,   WORD | WORD32 | RIGHT | LOGICAL },
+{"SRLV",    1, "11101xxxvvv00110",  RR,      SHIFT,   WORD | WORD32 | RIGHT | LOGICAL | REG },
+{"SUBU",    1, "11100xxxyyyddd11",  RRR,     SUB,     WORD | WORD32 },
+{"SW",      1, "11011xxxyyyWWWWW",  RRI,     STORE,   WORD },
+{"SWSP",    1, "11010yyyVVVVVVVVs", RI,      STORE,   WORD },
+{"SWRASP",  1, "01100010VVVVVVVVQs", I8,     STORE,   WORD },
+{"XOR",     1, "11101wwwyyy01110",  RR,      XOR,     NONE }
+};
+
+/*---------------------------------------------------------------------------*/
+
+static void print_igen_insn_format PARAMS ((const char *bitmap,
+                                           inst_type mark,
+                                           int data_size,
+                                           const char *options,
+                                           const char *name));
+
+static void
+print_igen_insn_format (bitmap, mark, data_size, options, name)
+     const char *bitmap;
+     inst_type mark;
+     int data_size;
+     const char *options;
+     const char *name;
+{
+  const char *chp;
+  char lch = *bitmap;
+  for (chp = bitmap; *chp != '\0'; chp++)
+    {
+      if ((isdigit (lch) && !isdigit (*chp))
+         || (!isdigit (lch) && isdigit (*chp))
+         || (!isdigit (lch) && !isdigit (*chp) && lch != *chp))
+       {
+         lch = *chp;
+         printf (",");
+       }
+      switch (*chp)
+       {
+       case '?':
+         printf ("*");
+         break;
+       case '<':
+         printf ("s"); /* good guess */
+         break;
+       default:
+         printf ("%c", *chp);
+         break;
+       }
+    }
+  printf (":");
+  switch (mark)
+    {
+    case NORMAL:
+      printf ("NORMAL");
+      break;
+    case SPECIAL:
+      printf ("SPECIAL");
+      break;
+    case REGIMM:
+      printf ("REGIMM");
+      break;
+    case COP1:
+      printf ("COP1");
+      break;
+    case COP1X:
+      printf ("COP1X");
+      break;
+    case COP1S: /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
+      printf ("COP1S");
+      break;
+
+    case MMINORM:
+      printf ("MMINORM");
+      break;
+    case MMI0:
+      printf ("MMI0");
+      break;
+    case MMI1:
+      printf ("MMI1");
+      break;
+    case MMI2:
+      printf ("MMI2");
+      break;
+    case MMI3:
+      printf ("MMI3");
+      break;
+
+      /* mips16 encoding types.  */
+    case I:
+      printf ("I");
+      break;
+    case RI:
+      printf ("RI");
+      break;
+    case RR:
+      printf ("RR");
+      break;
+    case RRI:
+      printf ("RRI");
+      break;
+    case RRR:
+      printf ("RRR");
+      break;
+    case RRI_A:
+      printf ("RRI_A");
+      break;
+    case ISHIFT:
+      printf ("ISHIFT");
+      break;
+    case I8:
+      printf ("I8");
+      break;
+    case I8_MOVR32:
+      printf ("I8_MOVR32");
+      break;
+    case I8_MOV32R:
+      printf ("I8_MOV32R");
+      break;
+    case I64:
+      printf ("I64");
+      break;
+    case RI64:
+      printf ("RI64");
+      break;
+    }
+  printf (":");
+  switch (data_size)
+    {
+    case DOUBLEWORD:
+      printf ("64");
+      break;
+      /* start-sanitize-r5900 */
+    case QUADWORD:
+      printf ("128");
+      break;
+      /* end-sanitize-r5900 */
+    case -1:
+      printf ("16");
+      break;
+    default:
+      printf ("32");
+    }
+  printf (":%s:%s\n", options, name);
+}
+
+static void print_igen_insn_models PARAMS ((unsigned int isa));
+
+static void
+print_igen_insn_models (isa)
+     unsigned int isa;
+{
+  /* common mips ISAs */
+  switch ((isa & MASK_ISA))
+    {
+    case 1:
+      printf ("*mipsI:\n");
+    case 2:
+      printf ("*mipsII:\n");
+    case 3:
+      printf ("*mipsIII:\n");
+      /* start-sanitize-cygnus-never */
+      printf ("// %s-%s-%s\n", "start", "sanitize", "r5900");
+      /* end-sanitize-cygnus-never */
+      /* start-sanitize-r5900 */
+      printf ("*r5900:\n");
+      /* end-sanitize-r5900 */
+      /* start-sanitize-cygnus-never */
+      printf ("// %s-%s-%s\n", "end", "sanitize", "r5900");
+      /* end-sanitize-cygnus-never */
+      printf ("*r3900:\n");
+      /* start-sanitize-cygnus-never */
+      printf ("// %s-%s-%s\n", "start", "sanitize", "tx19");
+      /* end-sanitize-cygnus-never */
+      /* start-sanitize-tx19 */
+      printf ("*tx19:\n");
+      /* end-sanitize-tx19 */
+      /* start-sanitize-cygnus-never */
+      printf ("// %s-%s-%s\n", "end", "sanitize", "tx19");
+      /* end-sanitize-cygnus-never */
+      break;
+    default:
+      /* processor specific ISAs */
+      if ((isa & ARCH_VR4100))
+       printf ("*vr4100:\n");
+      /* start-sanitize-r5900 */
+      if ((isa & ARCH_R5900))
+       printf ("*r5900:\n");
+      /* end-sanitize-r5900 */
+      if ((isa & ARCH_R3900))
+       printf ("*r3900:\n");
+    }
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int bitmap_val PARAMS ((const char *, int, int));
+static void build_mips16_operands PARAMS ((const char *));
+static void build_instruction
+  PARAMS ((int, unsigned int, int, const struct instruction *));
+
+/*---------------------------------------------------------------------------*/
+
+static char* 
+name_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "BYTE";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "HALFWORD";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "WORD";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return "DOUBLEWORD";
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return "QUADWORD";
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+letter_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "B";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "H";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "W";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return "D";
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return "Q";
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+type_for_data_len( insn , is_signed )
+     struct instruction* insn;
+     int is_signed;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return is_signed ? "int" : "unsigned int";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return is_signed ? "int" : "unsigned int";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return is_signed ? "signed64" : "unsigned64";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return 0;
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return 0;
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+max_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "127";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "32767";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "(int)0x7FFFFFFF";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return 0;
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return 0;
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+min_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "-128";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "-32768";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "(int)0x80000000";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return 0;
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return 0;
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+umax_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "0xFF";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "0xFFFF";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "0xFFFFFFFF";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return 0;
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return 0;
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+static char* 
+bits_for_data_len( insn )
+     struct instruction* insn;
+  {
+    if (GETDATASIZEINSN(insn) == BYTE)
+      return "8";
+
+    else if (GETDATASIZEINSN(insn) == HALFWORD)
+      return "16";
+
+    else if (GETDATASIZEINSN(insn) == WORD)
+      return "32";
+
+    else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
+      return "64";
+
+    /* start-sanitize-r5900 */
+    else if (GETDATASIZEINSN(insn) == QUADWORD)
+      return "128";
+
+    /* end-sanitize-r5900 */
+    else
+      return 0;
+  }
+
+/*---------------------------------------------------------------------------*/
+
+
+void
+convert_bitmap(bitmap,onemask,zeromask,dontmask)
+     char *bitmap;
+     unsigned int *onemask, *zeromask, *dontmask;
+{
+  int loop; /* current bitmap position */
+  int lastsp = -1; /* last bitmap field starting position */
+  int lastoe = -1; /* last bitmap field encoding */
+
+  *onemask = 0x00000000;
+  *zeromask = 0x00000000;
+  *dontmask = 0x00000000;
+
+  if (strlen(bitmap) != 32) {
+    fprintf(stderr,"Invalid bitmap string - not 32 characters long \"%s\"\n",bitmap);
+    exit(3);
+  }
+
+  for (loop = 0; (loop < 32); loop++) {
+    int oefield ;
+    for (oefield = 0; (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))); oefield++)
+     if (bitmap[31 - loop] == opfields[oefield].id)
+      break;
+    if (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))) {
+      if ((lastoe != -1) && (lastoe != oefield))
+       if ((loop - lastsp) != (opfields[lastoe].flen)) {
+         fprintf(stderr,"Invalid field length %d for bitmap field '%c' (0x%02X) (should be %d) : bitmap = \"%s\"\n",(loop - lastsp),(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],opfields[lastoe].flen,bitmap);
+         exit(4);
+       }
+         
+      switch (bitmap[31 - loop]) {
+        case '0' : /* fixed value */
+         *zeromask |= (1 << loop);
+         lastsp = loop;
+         lastoe = -1;
+         break;
+
+        case '1' : /* fixed value */
+         *onemask |= (1 << loop);
+         lastsp = loop;
+         lastoe = -1;
+         break;
+
+        case '?' : /* fixed value */
+         *dontmask |= (1 << loop);
+         lastsp = loop;
+         lastoe = -1;
+         break;
+
+        default : /* check character encoding */
+         {
+           if (opfields[oefield].fpos != -1) {
+             /* If flag not set, then check starting position: */
+             if (lastoe != oefield) {
+               if (loop != opfields[oefield].fpos) {
+                 fprintf(stderr,"Bitmap field '%c' (0x%02X) at wrong offset %d in bitmap \"%s\"\n",(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],loop,bitmap);
+                 exit(4);
+               }
+               lastsp = loop;
+               lastoe = oefield;
+             }
+           }
+           *dontmask |= (1 << loop);
+         }
+         break;
+       }
+    } else {
+      fprintf(stderr,"Unrecognised bitmap character '%c' (0x%02X) at offset %d in bitmap \"%s\"\n",(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],loop,bitmap);
+      exit(4);
+    }
+  }
+
+ /* NOTE: Since we check for the position and size of fields when
+    parsing the "bitmap" above, we do *NOT* need to check that invalid
+    field combinations have been used. */
+}
+
+/* Get the value of a 16 bit bitstring for a given shift count and
+   number of bits.  */
+
+static int
+bitmap_val (bitmap, shift, bits)
+     const char *bitmap;
+     int shift;
+     int bits;
+{
+  const char *s;
+  int ret;
+
+  ret = 0;
+  s = bitmap + 16 - shift - bits;
+  for (; bits > 0; --bits)
+    {
+      ret <<= 1;
+      if (*s == '0')
+       ;
+      else if (*s == '1')
+       ret |= 1;
+      else
+       abort ();
+      ++s;
+    }
+
+  return ret;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void
+build_operands(doisa,features,insn)
+     int doisa;
+     unsigned int features;
+     instruction* insn;
+{
+  int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
+  int finish_jump_flag = 0;
+  int check_mult = 0;
+  int check_condition_code = 0;
+  int sfield_used = 0;
+  int gfield_used = 0;
+  int any_operand = 0;
+
+  int current_field_id = -1;
+  int bitpos;
+
+  for (bitpos=0; bitpos<32; bitpos++) {
+    if (insn->bitmap[31-bitpos] != current_field_id)
+      {
+        int opindex;
+
+        current_field_id = insn->bitmap[31-bitpos];
+
+        for (opindex = 0; (opindex < (sizeof(opfields) / sizeof(operand_encoding))); opindex++)
+          if ((opfields[opindex].fpos != -1) && (opfields[opindex].id == insn->bitmap[31-bitpos])) {
+
+            any_operand = 1;
+
+            printf("  %s %s UNUSED = ",opfields[opindex].type,opfields[opindex].name);
+
+            if (opfields[opindex].flags & OP_SIGNX)
+              printf("SIGNEXTEND((%s)",opfields[opindex].type);
+
+            if (opfields[opindex].flags & OP_GPR)
+              printf("GPR[");
+
+            if (opfields[opindex].flags & OP_SHIFT2)
+              printf("(");
+
+            printf("((instruction >> %d) & 0x%08X)",opfields[opindex].fpos,((1 << opfields[opindex].flen) - 1));
+
+            if (opfields[opindex].flags & OP_SHIFT2)
+              printf(" << 2)");
+
+            if (opfields[opindex].flags & OP_GPR)
+              printf("]");
+
+            if (opfields[opindex].flags & OP_BITS5)
+              printf("&0x1F");
+
+            if (opfields[opindex].flags & OP_SIGNX)
+              printf(",%d)",(opfields[opindex].flen + ((opfields[opindex].flags & OP_SHIFT2) ? 2 : 0)));
+
+            printf(";\n");
+
+            if (opfields[opindex].flags & OP_GPR1)
+              {
+                printf("  %s %s1 = GPR1[",opfields[opindex].type,opfields[opindex].name);
+                printf("((instruction >> %d) & 0x%08X)",
+                       opfields[opindex].fpos,
+                       ((1 << opfields[opindex].flen) - 1));
+              printf("];\n");
+              }
+
+            if (opfields[opindex].id == 'j')
+              finish_jump_flag = 1;
+
+            if (opfields[opindex].id == 'e')
+              check_mult = 8;
+            
+            if (opfields[opindex].id == 'w')
+              check_mult = 4;
+
+            if (opfields[opindex].id == 'w')
+              check_mult = 2;
+
+            if (opfields[opindex].id == 'p')
+              check_condition_code = 1;
+
+            if (opfields[opindex].id == 's')
+              sfield_used = 1;
+
+            if (opfields[opindex].id == 'g')
+              gfield_used = 1;
+          }
+      }
+  }
+
+  if ( !any_operand && !(insn->flags & NOARG)) {
+    fprintf(stderr,"Bitmap error: Instruction with no operand fields \"%s\"\n",insn->name) ;
+    exit(5) ;
+  }
+
+  /* Finish constructing the jump address if required: */
+  if (finish_jump_flag)
+    printf("  op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */\n");
+
+  /* Now perform required operand checks: */
+
+  /* The following code has been removed, since it seems perfectly
+     reasonable to have a non-aligned offset that is added to another
+     non-aligned base to create an aligned address. Some more
+     information on exactly what the MIPS IV specification requires is
+     needed before deciding on the best strategy. Experimentation with a
+     VR4300 suggests that we do not need to raise the warning. */
+#if 0
+  /* For MIPS IV (and onwards), certain instruction operand values
+     will give undefined results. For the simulator we could
+     generate explicit exceptions (i.e. ReservedInstruction) to
+     make it easier to spot invalid use. However, for the moment we
+     just raise a warning. NOTE: This is a different check to the
+     later decoding, which checks for the final address being
+     valid. */
+     
+  if (check_mult != 0 && check_mult != 1) {
+    printf("  if (instruction & 0x%1X)\n", check_mult);
+    printf("  {\n");
+    /* NOTE: If we change this to a SignalException(), we must
+       ensure that the following opcode processing is not
+       executed. i.e. the code falls straight out to the simulator
+       control loop. */
+    printf("   sim_io_eprintf(sd,\"Instruction has lo-order offset bits set in instruction\\n\");\n");
+    printf("  }\n");
+  }
+#endif
+
+  /* The extended condition codes only appeared in ISA IV */
+  if (check_condition_code && (doisa < 4)) {
+    printf("  if (condition_code != 0)\n");
+    printf("  {\n");
+    printf("   SignalException(ReservedInstruction,instruction);\n");
+    printf("  }\n");
+    printf("  else\n");
+  }
+  
+  if ((insn->flags & WORD32) && (GETDATASIZEINSN(insn) != WORD)) {
+    fprintf(stderr,"Error in opcode table: WORD32 set for non-WORD opcode\n");
+    exit(1);
+  }
+  
+#if 1
+  /* The R4000 book differs slightly from the MIPS IV ISA
+     manual. An example is the sign-extension of a 64-bit processor
+     SUBU operation, and what is meant by an Undefined Result. This
+     is now provided purely as a warning. After examining a HW
+     implementation, this is now purely a warning... and the actual
+     operation is performed, with possibly undefined results. */
+  if (((insn->flags & WORD32) && proc64) && (features & FEATURE_WARN_RESULT)) {
+    /* The compiler should optimise out an OR with zero */
+    printf("  if (%s | %s)\n",(sfield_used ? "NOTWORDVALUE(op1)" : "0"),(gfield_used ? "NOTWORDVALUE(op2)" : "0"));
+    printf("   UndefinedResult();\n") ;
+  }
+#else
+  /* Check that the source is a 32bit value */
+  if ((insn->flags & WORD32) && proc64) {
+    /* The compiler should optimise out an OR with zero */
+    printf("  if (%s | %s)\n",(sfield_used ? "NOTWORDVALUE(op1)" : "0"),(gfield_used ? "NOTWORDVALUE(op2)" : "0"));
+    printf("   UndefinedResult();\n") ;
+    printf("  else\n") ;
+  }
+#endif
+
+  return;
+}
+
+/* The mips16 operand table.  */
+
+struct mips16_op
+{
+  /* The character which appears in the bitmap string.  */
+  int type;
+  /* The type of the variable in the simulator.  */
+  const char *vartype;
+  /* The name of the variable in the simulator.  */
+  const char *name;
+  /* The number of bits.  */
+  int nbits;
+  /* The number of bits when extended (zero if can not be extended).  */
+  int extbits;
+  /* The amount by which the short form is shifted when it is used;
+     for example, the sw instruction has a shift count of 2.  */
+  int shift;
+  /* Flags.  */
+  int flags;
+};
+
+/* Flags which appears in the mips16 operand table.  */
+
+/* Whether this is a mips16 register index.  */
+#define MIPS16_REG16 (0x1)
+/* Whether this is a register value.  */
+#define MIPS16_REGVAL (0x2)
+/* Whether this is a swapped mips32 register index (MOV32R) */
+#define MIPS16_REG32_SWAPPED (0x4)
+/* Whether this index is also the destination register.  */
+#define MIPS16_DESTREG (0x8)
+/* Whether the short form is unsigned.  */
+#define MIPS16_UNSP (0x10)
+/* Whether the extended form is unsigned.  */
+#define MIPS16_EXTU (0x20)
+/* Implicit stack pointer.  */
+#define MIPS16_SP (0x40)
+/* Implicit program counter.  */
+#define MIPS16_PC (0x80)
+/* Implicit $0.  */
+#define MIPS16_ZERO (0x100)
+/* Implicit $24.  */
+#define MIPS16_TREG (0x200)
+/* Implicit $31.  */
+#define MIPS16_RA (0x400)
+/* Jump address.  */
+#define MIPS16_JUMP_ADDR (0x800)
+/* Branch offset.  */
+#define MIPS16_BRANCH (0x1000)
+
+/* The mips16 operand table.  */
+
+static const struct mips16_op mips16_op_table[] =
+{
+  { 'd', "int", "destreg", 3,  0, 0, MIPS16_REG16 },
+  { 'x', "t_reg", "op1",  3,  0, 0, MIPS16_REG16 | MIPS16_REGVAL },
+  { 'w', "t_reg", "op1",  3,  0, 0, MIPS16_REG16|MIPS16_REGVAL|MIPS16_DESTREG},
+  { 'y', "t_reg", "op2", 3,  0, 0, MIPS16_REG16 | MIPS16_REGVAL },
+  { 'v', "t_reg", "op2", 3,  0, 0, MIPS16_REG16|MIPS16_REGVAL|MIPS16_DESTREG },
+  { 'X', "t_reg", "op1", 5,  0, 0, MIPS16_REGVAL },
+  { 'Y', "int", "destreg", 5,  0, 0, MIPS16_REG32_SWAPPED },
+  { 'a', "ut_reg", "op1", 11,  0, 0, MIPS16_JUMP_ADDR },
+  { 'e', "int", "ext", 11,  0, 0, 0 },
+  { '<', "int", "op1",  3,  5, 0, MIPS16_UNSP | MIPS16_EXTU },
+  { '>', "int", "op1",  3,  5, 0, MIPS16_UNSP | MIPS16_EXTU },
+  { '[', "int", "op1",  3,  6, 0, MIPS16_UNSP | MIPS16_EXTU },
+  { ']', "int", "op1",  3,  6, 0, MIPS16_UNSP | MIPS16_EXTU },
+  { '4', "int", "op2",  4, 15, 0, 0 },
+  { '5', "int", "offset",  5, 16, 0, MIPS16_UNSP },
+  { 'H', "int", "offset",  5, 16, 1, MIPS16_UNSP },
+  { 'W', "int", "offset",  5, 16, 2, MIPS16_UNSP },
+  { 'D', "int", "offset",  5, 16, 3, MIPS16_UNSP },
+  { 'j', "int", "op2",  5, 16, 0, 0 },
+  { '8', "int", "op2",  8, 16, 0, MIPS16_UNSP },
+  { 'V', "int", "offset",  8, 16, 2, MIPS16_UNSP },
+  { 'C', "int", "offset",  8, 16, 3, MIPS16_UNSP },
+  { 'U', "int", "op2",  8, 16, 0, MIPS16_UNSP | MIPS16_EXTU },
+  { 'k', "int", "op2",  8, 16, 0, 0 },
+  { 'K', "int", "op2",  8, 16, 3, 0 },
+  { 'p', "int", "offset",  8, 16, 0, MIPS16_BRANCH },
+  { 'q', "int", "offset", 11, 16, 0, MIPS16_BRANCH },
+  { 'A', "int", "op2",  8, 16, 2, MIPS16_UNSP },
+  { 'B', "int", "op2",  5, 16, 3, MIPS16_UNSP },
+  { 'E', "int", "op2",  5, 16, 2, MIPS16_UNSP },
+
+  /* The remaining operands are special operands which encode implied
+     arguments.  These only appear at the end of a bitmap string, and
+     do not represent actual bits.  */
+  { 's', "t_reg", "op1",  0,  0, 0, MIPS16_SP | MIPS16_REGVAL  },
+  { 'S', "t_reg", "op1",  0,  0, 0, MIPS16_SP|MIPS16_REGVAL|MIPS16_DESTREG },
+  { 'P', "t_reg", "op1",  0,  0, 0, MIPS16_PC },
+  { 'z', "t_reg", "op2",  0,  0, 0, MIPS16_ZERO },
+  { 'Z', "t_reg", "op1",  0,  0, 0, MIPS16_ZERO },
+  { 't', "t_reg", "op1",  0,  0, 0, MIPS16_TREG | MIPS16_REGVAL },
+  { 'T', "int",   "destreg",  0,  0, 0, MIPS16_TREG },
+  { 'r', "t_reg", "op1",  0,  0, 0, MIPS16_RA | MIPS16_REGVAL },
+  { 'R', "int",   "destreg",  0,  0, 0, MIPS16_RA },
+  { 'Q', "t_reg", "op2",  0,  0, 0, MIPS16_RA | MIPS16_REGVAL },
+
+  { '\0', NULL,  NULL,     0, 0,  0, 0 }
+};
+
+/* Build mips16 operands.  */
+
+static void
+build_mips16_operands (bitmap)
+     const char *bitmap;
+{
+  const char *s;
+  int start = -1;
+  const struct mips16_op *op = NULL;
+  const struct mips16_op *ops[3];
+  int opindex = 0;
+  int i;
+
+  for (s = bitmap; *s != '\0'; s++)
+    {
+      if (op != NULL)
+       {
+         if (op->type == *s)
+           continue;
+
+         /* Make sure we saw the right number of bits for that
+             operand.  */
+         if (op->nbits != 0 && (s - bitmap) - op->nbits != start)
+           abort ();
+         op = NULL;
+       }
+
+      if (*s == '0' || *s == '1' || *s == '?')
+       continue;
+
+      start = s - bitmap;
+
+      for (op = mips16_op_table; op->type != *s; ++op)
+       if (op->type == '\0')
+         abort ();
+
+      printf ("  %s %s = ", op->vartype, op->name);
+      if (op->nbits != 0)
+       printf ("(instruction >> %d) & 0x%x",
+               16 - (s - bitmap) - op->nbits,
+               (1 << op->nbits) - 1);
+      else
+       {
+         if ((op->flags & MIPS16_SP) != 0)
+           printf ("29");
+         else if ((op->flags & MIPS16_PC) != 0)
+           {
+             int j;
+
+             printf ("((INDELAYSLOT () ? (INJALDELAYSLOT () ? cia - 4 : cia - 2) : (have_extendval ? cia - 2 : cia)) & ~ (uword64) 1)");
+             for (j = 0; j < opindex; j++)
+               if (ops[j]->shift != 0)
+                 printf (" & ~ (uword64) 0x%x", (1 << ops[j]->shift) - 1);
+           }
+         else if ((op->flags & MIPS16_ZERO) != 0)
+           printf ("0");
+         else if ((op->flags & MIPS16_TREG) != 0)
+           printf ("24");
+         else if ((op->flags & MIPS16_RA) != 0)
+           printf ("31");
+         else
+           abort ();
+       }
+      printf (";\n");
+
+      if ((op->flags & MIPS16_DESTREG) != 0)
+       printf ("  int destreg;\n");
+
+      if (opindex > 2)
+       abort ();
+      ops[opindex] = op;
+      ++opindex;
+    }
+
+  if (op != NULL)
+    {
+      /* Make sure we saw the right number of bits for that
+        operand.  */
+      if (op->nbits != 0 && 16 - op->nbits != start)
+       abort ();
+    }
+
+  for (i = 0; i < opindex; i++)
+    {
+      op = ops[i];
+      if ((op->flags & MIPS16_REG16) != 0)
+       {
+         printf ("  if (%s < 2)\n", op->name);
+         printf ("    %s += 16;\n", op->name);
+       }
+      if ((op->flags & MIPS16_REG32_SWAPPED) != 0)
+       printf ("  %s = (%s >> 2) | ((%s & 3) << 3);\n",
+               op->name, op->name, op->name);
+      if ((op->flags & MIPS16_DESTREG) != 0)
+       printf ("  destreg = %s;\n", op->name);
+      if ((op->flags & MIPS16_REGVAL) != 0)
+       printf ("  %s = GPR[%s];\n", op->name, op->name);
+
+      if (op->extbits != 0)
+       {
+         printf ("  if (have_extendval)\n");
+         printf ("    {\n");
+         if (op->extbits == 16)
+           printf ("      %s |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);\n",
+                   op->name);
+         else if (op->extbits == 15)
+           printf ("      %s |= ((extendval & 0xf) << 11) | (extendval & 0x7f0);\n",
+                   op->name);
+         else if (op->extbits == 6)
+           printf ("      %s = ((extendval >> 6) & 0x1f) | (extendval & 0x20);\n",
+                   op->name);
+         else
+           printf ("      %s = (extendval >> 6) & 0x1f;\n",
+                   op->name);
+         if ((op->flags & MIPS16_EXTU) == 0)
+           {
+             printf ("      if (%s >= 0x%x)\n",
+                     op->name, 1 << (op->extbits - 1));
+             printf ("        %s -= 0x%x;\n",
+                     op->name, 1 << op->extbits);
+           }
+         printf ("      have_extendval = 0;\n");
+         printf ("    }\n");
+         printf ("  else\n");
+         printf ("    {\n");
+         if ((op->flags & MIPS16_UNSP) == 0)
+           {
+             printf ("      if (%s >= 0x%x)\n",
+                     op->name, 1 << (op->nbits - 1));
+             printf ("        %s -= 0x%x;\n",
+                     op->name, 1 << op->nbits);
+           }
+         if (op->shift != 0)
+           printf ("      %s <<= %d;\n", op->name, op->shift);
+         if (op->type == '<' || op->type == '>'
+             || op->type == '[' || op->type == ']')
+           {
+             printf ("      if (%s == 0)\n", op->name);
+             printf ("        %s = 8;\n", op->name);
+           }
+         printf ("    }\n");
+       }
+
+      if ((op->flags & MIPS16_BRANCH) != 0)
+       printf ("  %s *= 2;\n", op->name);
+
+      if ((op->flags & MIPS16_JUMP_ADDR) != 0)
+       {
+         printf ("  {\n");
+         printf ("    address_word paddr;\n");
+         printf ("    int uncached;\n");
+         printf ("    if (AddressTranslation (PC &~ (uword64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))\n");
+         printf ("      {\n");
+         printf ("        uword64 memval;\n");
+         printf ("        unsigned int reverse = (ReverseEndian ? 3 : 0);\n");
+         printf ("        unsigned int bigend = (BigEndianCPU ? 3 : 0);\n");
+         printf ("        unsigned int byte;\n");
+         printf ("        paddr = ((paddr & ~0x7) | ((paddr & 0x7) ^ (reverse << 1)));\n");
+         printf ("        LoadMemory (&memval,0,uncached, AccessLength_HALFWORD, paddr, PC, isINSTRUCTION, isREAL);\n");
+         printf ("        byte = (((PC &~ (uword64) 1) & 0x7) ^ (bigend << 1));\n");
+         printf ("        memval = (memval >> (8 * byte)) & 0xffff;\n");
+         printf ("        %s = (((%s & 0x1f) << 23)\n", op->name, op->name);
+         printf ("              | ((%s & 0x3e0) << 13)\n", op->name);
+         printf ("              | (memval << 2));\n");
+         printf ("        if ((instruction & 0x400) == 0)\n");
+         printf ("          %s |= 1;\n", op->name);
+         printf ("        PC += 2;\n");
+         printf ("      }\n");
+         printf ("  }\n");
+         printf ("  %s |= PC & ~ (uword64) 0x0fffffff;\n", op->name);
+       }
+    }
+
+  /* FIXME: Is this the way to detect an unused extend opcode?  */
+  printf ("  if (have_extendval)\n");
+  printf ("    SignalException (ReservedInstruction, instruction);\n");
+}
+
+/*---------------------------------------------------------------------------*/
+
+typedef enum {
+  s_left,
+  s_right
+} e_endshift;
+
+static void
+build_endian_shift(proc64,datalen,endbit,direction,shift)
+     int proc64;
+     int datalen;
+     int endbit;
+     e_endshift direction;
+     int shift;
+{
+  if (datalen == 4) {
+    printf("    if ((vaddr & (1 << %d)) ^ (BigEndianCPU << %d)) {\n",endbit,endbit);
+    printf("     memval %s= %d;\n",direction == s_left ? "<<" : ">>",shift);
+    printf("    }\n");
+  }
+
+  return;
+}
+
+/*---------------------------------------------------------------------------*/
+/* doisa = number of MIPS ISA simulator table is being constructed for.
+ * proc64 = TRUE if constructing 64bit processor world.
+ * dofp = boolean, TRUE if FP instructions are to be included.
+ * fpsingle = boolean, TRUE if only single precision FP instructions to be included.
+ */
+
+void
+process_instructions(doarch,features)
+     unsigned int doarch;
+     unsigned int features;
+{
+  int doisa = (doarch & MASK_ISA);
+  int limit = (sizeof(MIPS_DECODE) / sizeof(instruction));
+  int gprlen=((features & FEATURE_GP64) ? 64 : 32);
+  int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
+  int dofp = (features & FEATURE_HASFPU);
+  int fpsingle = (features & FEATURE_FPSINGLE);
+  int maxisa;
+  int loop;
+
+  if (limit < 1) {
+    fprintf(stderr,"process_instructions: invalid structure length\n");
+    exit(1);
+  }
+
+  if (proc64 && (gprlen != 64)) {
+    fprintf(stderr,"Error: 64bit processor build specified, with MIPS ISA I or II\n");
+    exit(3);
+  }
+
+  /* NOTE: "proc64" also differentiates between 32- and 64-bit wide memory */
+
+  maxisa = 0;
+  for (loop = 0; (loop < limit); loop++)
+   if ((MIPS_DECODE[loop].isa & MASK_ISA) > maxisa)
+    maxisa = (MIPS_DECODE[loop].isa & MASK_ISA);
+
+  if (doisa == 0)
+   doisa = maxisa;
+
+  if (!(features & FEATURE_IGEN))
+    {
+      printf("#if defined(SIM_MANIFESTS)\n");
+      printf("#define MIPSISA (%d)\n",doisa);
+      if (proc64)
+       printf("#define PROCESSOR_64BIT (1 == 1)\n");
+      else
+       printf("#define PROCESSOR_64BIT (1 == 0)\n");
+#if 1 /* cheat: We only have a 64bit LoadMemory and StoreMemory routines at the moment */
+      printf("#define LOADDRMASK (0x%08X)\n",0x7);
+#else
+      printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
+#endif
+      /* The FP registers are the same width as the CPU registers: */
+      printf("#define GPRLEN (%d)\n",gprlen);
+      printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
+      printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
+      printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
+      if (dofp)
+       printf("#define HASFPU (1 == 1)\n");
+      if (features & FEATURE_FAST)
+       printf("#define FASTSIM (1 == 1)\n");
+      if (features & FEATURE_WARN_STALL)
+       printf("#define WARN_STALL (1 == 1)\n");
+      if (features & FEATURE_WARN_LOHI)
+       printf("#define WARN_LOHI (1 == 1)\n");
+      if (features & FEATURE_WARN_ZERO)
+       printf("#define WARN_ZERO (1 == 1)\n");
+      if (features & FEATURE_WARN_MEM)
+       printf("#define WARN_MEM (1 == 1)\n");
+      if (features & FEATURE_WARN_R31)
+       printf("#define WARN_R31 (1 == 1)\n");
+      if (features & FEATURE_WARN_RESULT)
+       printf("#define WARN_RESULT (1 == 1)\n");
+      
+      printf("#else /* simulator engine */\n");
+      
+      printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
+      printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
+      if (dofp)
+       printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
+      printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
+      
+      if (proc64) {
+       printf("#if !defined(PROCESSOR_64BIT)\n");
+       printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
+       printf("#endif\n");
+      }
+      
+      printf("/* Actual instruction decoding block */\n");
+      printf("if ((vaddr & 1) == 0){\n");
+      {
+       int limit;
+       printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
+       limit = (OP_MASK_OP + 1);
+       
+       printf("#ifdef DEBUG\n");
+       printf("printf(\"DBG: instruction = 0x%%08X\\n\",instruction);\n");
+       printf("#endif\n");
+       
+       printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+       limit += (OP_MASK_SPEC + 1);
+       
+       printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
+       limit += (OP_MASK_RT + 1);
+       
+       printf("else if (num == 0x11) {\n");
+       printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
+       printf("  if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
+       printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
+       printf("  else\n");
+       printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+       limit += (OP_MASK_SPEC + 1);
+       
+       printf(" else\n");
+       /* To keep this code quick, we just clear out the "to" bit
+          here. The proper (though slower) code would be to have another
+          conditional, checking whether this instruction is a branch or
+          not, before limiting the range to the bottom two bits of the
+          move operation. */
+       printf("  num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
+       limit += (OP_MASK_COP1SPEC + 1);
+       
+       printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+       limit += (OP_MASK_SPEC + 1);
+       
+       printf("else if (num == 0x1C) {\n");
+       printf("  int mmi_func = ((instruction >> %d) & 0x%08X);\n",OP_SH_MMI,OP_MASK_MMI);
+       
+       printf("  if (mmi_func == 0x08) \n");
+       printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+       limit += (OP_MASK_MMISUB + 1);
+       
+       printf("  else if (mmi_func == 0x28) \n");
+       printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+       limit += (OP_MASK_MMISUB + 1);
+       
+       printf("  else if (mmi_func == 0x09) \n");
+       printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+       limit += (OP_MASK_MMISUB + 1);
+       
+       printf("  else if (mmi_func == 0x29) \n");
+       printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+       limit += (OP_MASK_MMISUB + 1);
+       
+       printf("  else \n");
+       printf("    num = (%d + mmi_func);\n",limit);
+       limit += (OP_MASK_MMI + 1);
+       
+       printf("}\n");
+       
+       printf("/* Total possible switch entries: %d */\n",limit) ;
+      }
+      
+      printf("#ifdef DEBUG\n");
+      printf("printf(\"DBG: num = %%d\\n\",num);\n");
+      printf("#endif\n");
+      
+      printf("switch (num)\n") ;
+      printf("{\n");
+    }      
+      
+ for (loop = 0; (loop < limit); loop++) {
+   /* First check if the insn is in a requested isa# independent set,
+      then check that the ISA number we are constructing for is
+      valid, then if the instruction matches any of the
+      architecture specific flags. NOTE: We allow a selected ISA of
+      zero to be used to match all standard instructions. */
+   unsigned int isa = MIPS_DECODE[loop].isa;
+   if (((isa & doarch & MASK_ISA_INDEP)
+        || (((isa & MASK_ISA) <= doisa) 
+            && (((isa & MASK_ISA_DEP) == 0) || ((isa & MASK_ISA_DEP) & doarch) != 0)))
+       && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))
+       || (features & FEATURE_IGEN)) {
+     unsigned int onemask;
+     unsigned int zeromask;
+     unsigned int dontmask;
+     unsigned int mask;
+     unsigned int number;
+
+     convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
+
+     if (!(MIPS_DECODE[loop].flags & COPROC) 
+         && ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)
+         && !(features & FEATURE_IGEN)) {
+       fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
+       exit(4);
+     }
+
+#if defined(DEBUG)
+     printf("/* DEBUG: onemask  0x%08X */\n",onemask) ;
+     printf("/* DEBUG: zeromask 0x%08X */\n",zeromask) ;
+     printf("/* DEBUG: dontmask 0x%08X */\n",dontmask) ;
+#endif
+
+     switch (MIPS_DECODE[loop].mark) {
+       case NORMAL :
+        mask = (OP_MASK_OP << OP_SH_OP) ;
+        number = ((onemask >> OP_SH_OP) & OP_MASK_OP) ;
+        break ;
+
+       case SPECIAL :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
+        number = ((OP_MASK_OP + 1) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
+        break ;
+
+       case REGIMM :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_RT << OP_SH_RT)) ;
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_RT) & OP_MASK_RT)) ;
+        break ;
+
+       case COP1 :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
+        break ;
+
+       case COP1S :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_COP1SPEC << OP_SH_COP1SPEC)) ;
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_COP1SPEC) & OP_MASK_COP1SPEC)) ;
+        break;
+
+       case COP1X :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
+        break ;
+
+       case MMI0 :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
+                | (OP_MASK_MMISUB << OP_SH_MMISUB));
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
+           + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
+           + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
+        break ;
+
+       case MMI1 :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
+                | (OP_MASK_MMISUB << OP_SH_MMISUB));
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
+           + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
+           + (OP_MASK_MMISUB + 1)
+           + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
+        break ;
+
+       case MMI2 :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
+                | (OP_MASK_MMISUB << OP_SH_MMISUB));
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
+           + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
+           + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
+           + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
+        break ;
+
+       case MMI3 :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
+                | (OP_MASK_MMISUB << OP_SH_MMISUB));
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
+           + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
+           + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
+           + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
+        break ;
+
+       case MMINORM :
+        mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)) ;
+        number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
+           + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
+           + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
+           + (OP_MASK_MMISUB + 1) 
+           + ((onemask >> OP_SH_MMI) & OP_MASK_MMI)) ;
+        break ;
+
+       default :
+        fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
+        exit(5) ;
+      }
+     
+     if (!(features & FEATURE_IGEN))
+       {
+        printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
+        
+#if defined(DEBUG)
+        printf("/* DEBUG: mask 0x%08X */\n",mask) ;
+        printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
+#endif
+        
+        /* Check if there are any other explicit bits in the instruction: */
+        if ((~mask & (onemask | zeromask)) != 0x00000000) {
+          printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
+          printf(" {\n") ;
+          printf("  SignalException(ReservedInstruction,instruction);\n") ;
+          printf(" }\n") ;
+          printf(" else\n") ;
+        }
+        
+        printf(" {\n") ;
+       }
+     else
+       {
+        /* start-sanitize-cygnus-never */
+        /* If any sanitization occures, this line should be printed */
+        if ((MIPS_DECODE[loop].isa & ARCH_R5900))
+          printf ("// %s-%s-%s\n", "start", "sanitize", "r5900");
+        /* end-sanitize-cygnus-never */
+        printf ("\n");
+        print_igen_insn_format (MIPS_DECODE[loop].bitmap,
+                                MIPS_DECODE[loop].mark, /* format-name */
+                                GETDATASIZEINSN (&MIPS_DECODE[loop]), /* filter-flags */
+                                "", /* options */
+                                MIPS_DECODE[loop].name);
+        print_igen_insn_models (MIPS_DECODE[loop].isa);
+        printf ("{\n") ;
+        printf ("  unsigned32 instruction = instruction_0;\n");
+       }
+     
+     /* Get hold of the operands */
+     /* NOTE: If we wanted to make the simulator code smaller, we
+      * could pull these into a common sequence before we perform
+      * the instruction decoding. However, this would affect the
+      * performance since unnecessary field extraction would be
+      * occurring for certain instructions.
+      *
+      * Also we do not perform checking for multiple definitions of a
+      * particular operand here, since they are caught by the
+      * compilation of the produced code.
+      */
+     build_operands(doisa, features, &MIPS_DECODE[loop]);
+     
+     printf("  {\n") ;
+     
+     build_instruction (doisa, features, 0, &MIPS_DECODE[loop]);
+     
+     printf("  }\n") ;
+     if (!(features & FEATURE_IGEN))
+       {
+        printf(" }\n") ;
+        printf(" break ;\n") ;
+       }
+     else
+       {
+        printf ("}\n");
+        printf ("\n");
+        /* start-sanitize-cygnus-never */
+        /* When sanitized, this output should never be produced */
+        if ((MIPS_DECODE[loop].isa & ARCH_R5900))
+          printf ("// %s-%s-%s\n", "end", "sanitize", "r5900");
+        /* end-sanitize-cygnus-never */
+       }
+   
+   }
+ }
+
+ if (!(features & FEATURE_IGEN))
+   {
+     printf("default : /* Unrecognised instruction */\n") ;
+     printf(" SignalException(ReservedInstruction,instruction);\n") ;
+     printf(" break ;\n") ;
+     printf("}\n}\n") ;
+   }
+ /* Handle mips16 instructions.  The switch table looks like this:
+    0 - 31: I, RI, and RRI instructions by major.
+    32 - 35: ISHIFT instructions by function + 32
+    36 - 37: RRI_A instructions by function + 36
+    38 - 45: I8, I8_MOV32R, and I8_MOVR32 instructions by function + 38
+    46 - 49: RRR instructions by function + 46
+    50 - 81: RR instructions by minor + 50 (except for minor == 0)
+    82 - 89: I64 and RI64 instructions by funct + 82
+    90 - 97: jalr (RR minor 0) by y + 90
+    */
+ if (!(features & FEATURE_IGEN))
+   {
+     printf ("else {\n");
+     printf ("static int extendval;\n");
+     printf ("static int have_extendval;\n");
+     printf ("int num = ((instruction >> %d) & 0x%08X);\n",
+            MIPS16OP_SH_OP, MIPS16OP_MASK_OP);
+     printf ("switch (num)\n{\n");
+     printf ("case 0x6: num = 32 + (instruction & 3); break;\n");
+     printf ("case 0x8: num = 36 + ((instruction & 0x10) >> 4); break;\n");
+     printf ("case 0xc: num = 38 + ((instruction & 0x700) >> 8); break;\n");
+     printf ("case 0x1c: num = 46 + (instruction & 3); break;\n");
+     printf ("case 0x1d: num = 50 + (instruction & 0x1f);\n");
+     printf ("           if (num == 50) num = 90 + ((instruction & 0xe0) >> 5);\n");
+     printf ("           break;\n");
+     printf ("case 0x1f: num = 82 + ((instruction & 0x700) >> 8); break;\n");
+     printf ("default: break;\n}\n");
+     printf ("switch (num)\n{\n");
+   }
+ for (loop = 0; loop < sizeof MIPS16_DECODE / sizeof MIPS16_DECODE[0]; loop++)
+   {
+     const char *bitmap;
+     int num;
+     
+     if (! proc64 && GETDATASIZEINSN (&MIPS16_DECODE[loop]) == DOUBLEWORD)
+       continue;
+     
+     bitmap = MIPS16_DECODE[loop].bitmap;
+     switch (MIPS16_DECODE[loop].mark)
+       {
+       case I:
+       case RI:
+       case RRI:
+        num = bitmap_val (bitmap, 11, 5);
+        break;
+       case ISHIFT:
+        num = 32 + bitmap_val (bitmap, 0, 2);
+        break;
+       case RRI_A:
+        num = 36 + bitmap_val (bitmap, 4, 1);
+        break;
+       case I8:
+       case I8_MOV32R:
+       case I8_MOVR32:
+        num = 38 + bitmap_val (bitmap, 8, 3);
+        break;
+       case RRR:
+        num = 46 + bitmap_val (bitmap, 0, 2);
+        break;
+       case RR:
+        {
+          int minor;
+          
+          minor = bitmap_val (bitmap, 0, 5);
+          if (minor != 0)
+            num = 50 + minor;
+          else
+            num = 90 + bitmap_val (bitmap, 5, 3);
+        }
+        break;
+       case I64:
+       case RI64:
+        num = 82 + bitmap_val (bitmap, 8, 3);
+        break;
+       default:
+        abort ();
+       }
+
+
+     if (!(features & FEATURE_IGEN))
+       {
+        printf ("case %d: /* \"%s\" %s */\n", num, MIPS16_DECODE[loop].name,
+                bitmap);
+        printf (" {\n");
+       }
+     else
+       {
+        printf ("\n");
+        print_igen_insn_format (bitmap,
+                                MIPS16_DECODE[loop].mark, /* format-name */
+                                -1, /* filter-flags -- -1 => MIPS16 */
+                                "", /* options */
+                                MIPS16_DECODE[loop].name);
+        printf ("*mips16:\n");
+        printf ("{\n");
+        printf ("  unsigned32 instruction = instruction_0;\n");
+       }
+
+     build_mips16_operands (bitmap);
+
+     printf ("  {\n") ;
+
+     /* build_instruction doesn't know about extend.  */
+     if (num != 30)
+       build_instruction (doisa, features, 1, &MIPS16_DECODE[loop]);
+     else
+       {
+        printf ("    extendval = ext;\n");
+        printf ("    have_extendval = 1;\n");
+       }
+
+     printf ("  }\n");
+     if (!(features & FEATURE_IGEN))
+       {
+        printf (" }\n") ;
+        printf (" break ;\n") ;
+       }
+     else
+       {
+        printf ("}\n");
+        printf ("\n");
+       }
+   }
+
+ if (!(features & FEATURE_IGEN))
+   {
+     printf ("default : /* Unrecognised instruction */\n") ;
+     printf (" SignalException(ReservedInstruction,instruction);\n") ;
+     printf (" break ;\n") ;
+     printf ("}\n}\n") ;
+     
+     printf("#endif /* simulator engine */\n");
+   }
+     
+ return ;
+}
+
+/* Output the code to execute an instruction, assuming the operands
+   have already been extracted.  */
+
+static void 
+build_instruction (doisa, features, mips16, insn)
+     int doisa;
+     unsigned int features;
+     int mips16;
+     const struct instruction *insn;
+{
+  int gprlen=((features & FEATURE_GP64) ? 64 : 32);
+  int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
+  char *regtype = ((gprlen == 64) ? "uword64" : "unsigned int");
+
+  switch (insn->type) {
+      /* TODO: To make these easier to edit and maintain, they should
+        actually be provided as source macros (or inline functions)
+        OUTSIDE this main switch statement. The PPC simulator has a
+        neater scheme for describing the instruction sequences. */
+
+    case ADD:
+    case SUB:
+     {
+       char *signed_basetype = "unknown";
+       char *unsigned_basetype = "unknown";
+
+       switch (GETDATASIZEINSN(insn)) {
+        case WORD :
+         signed_basetype = "signed int";
+         unsigned_basetype = "unsigned int";
+         break;
+        case DOUBLEWORD :
+         signed_basetype = "word64";
+         unsigned_basetype = "uword64";
+         break;
+        default :
+         fprintf(stderr,"Opcode table error: size of ADD/SUB operands not known (%d)\n",GETDATASIZEINSN(insn));
+         exit(1);
+       }
+
+       if ((insn->type) == ADD) {
+        printf("   %s temp = (%s)(op1 + op2);\n", unsigned_basetype, unsigned_basetype);
+        printf("   %s tempS UNUSED = (%s)temp;\n", signed_basetype, signed_basetype);
+        if (insn->flags & OVERFLOW) {
+          printf("   if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
+          printf("    SignalExceptionIntegerOverflow ();\n");
+          printf("   else\n");
+        }
+        if (!proc64 || (insn->flags & UNSIGNED) || (GETDATASIZEINSN(insn) == DOUBLEWORD))
+         printf("   GPR[destreg] = (%s)temp;\n",regtype);
+        else /* only sign-extend when placing 32bit result in 64bit processor */
+         printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
+       } else { /* SUB */
+        printf("   %s temp = (%s)(op1 - op2);\n", unsigned_basetype, unsigned_basetype);
+        printf("   %s tempS UNUSED = (%s)temp;\n", signed_basetype, signed_basetype);
+        if (insn->flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
+          printf("   if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
+          printf("    SignalExceptionIntegerOverflow ();\n");
+          printf("   else\n");
+        }
+        /* UNSIGNED 32bit operations on a 64bit processor should
+           *STILL* be sign-extended. We have cheated in the
+           data-structure, by not marking it with UNSIGNED, and not
+           setting OVERFLOW. */
+        if (!proc64 || (insn->flags & UNSIGNED) || (GETDATASIZEINSN(insn) == DOUBLEWORD))
+         printf("   GPR[destreg] = (%s)temp;\n",regtype);
+        else /* only sign-extend when placing 32bit result in 64bit processor */
+         printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
+       }
+     }
+     break ;
+
+    case MUL:
+     {
+     char* pipe = (insn->flags & PIPE1) ? "1" : "";
+
+     if (features & FEATURE_WARN_LOHI) {
+       printf("   CHECKHILO(\"Multiplication\");\n");
+     }
+     printf("   {\n");
+     if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
+       printf("   uword64 mid;\n");
+       printf("   uword64 midhi;\n");
+       printf("   uword64 temp;\n");
+       if ((insn->flags & UNSIGNED) == 0)
+        {
+          printf("   int sign = 0;\n");
+          printf("   if (op1 < 0) { op1 = - op1; ++sign; }\n");
+          printf("   if (op2 < 0) { op2 = - op2; ++sign; }\n");
+        }
+       printf("   LO%s = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n",pipe);
+       printf("   HI%s = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n",pipe);
+       printf("   mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
+       printf("   midhi = SET64HI(WORD64LO(mid));\n");
+       printf("   temp = (LO%s + midhi);\n",pipe);
+       printf("   if ((temp == midhi) ? (LO%s != 0) : (temp < midhi))\n",pipe);
+       printf("     HI%s += 1;\n",pipe);
+       printf("   HI%s += WORD64HI(mid);\n",pipe);
+       printf("   mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
+       printf("   midhi = SET64HI(WORD64LO(mid));\n");
+       printf("   LO%s = (temp + midhi);\n",pipe);
+       printf("   if ((LO%s == midhi) ? (temp != 0) : (LO%s < midhi))\n",pipe,pipe);
+       printf("     HI%s += 1;\n",pipe);
+       printf("   HI%s += WORD64HI(mid);\n",pipe);
+       if ((insn->flags & UNSIGNED) == 0)
+        printf("   if (sign & 1) { LO%s = - LO%s; HI%s = (LO%s == 0 ? 0 : -1) - HI%s; }\n",pipe,pipe,pipe,pipe,pipe);
+     } else {
+       if (insn->flags & UNSIGNED)
+        printf("   uword64 temp = ((uword64)(op1 & 0xffffffff) * (uword64)(op2 & 0xffffffff));\n");
+       else
+        printf("   uword64 temp = ((word64) op1 * (word64) op2);\n");
+       printf("   LO%s = SIGNEXTEND((%s)WORD64LO(temp),32);\n",pipe,regtype);
+       printf("   HI%s = SIGNEXTEND((%s)WORD64HI(temp),32);\n",pipe,regtype);
+     }
+     if (insn->flags & OP3)
+       {
+         printf("     if ( destreg != 0 )\n");
+         printf("         GPR[destreg] = LO%s;\n",pipe);
+       }
+     printf("   }\n");
+     break ;
+     }
+    case DIV:
+     {
+      int boolU = (insn->flags & UNSIGNED);
+      char* pipe = (insn->flags & PIPE1) ? "1" : "";
+
+      if (features & FEATURE_WARN_LOHI) {
+        printf("   CHECKHILO(\"Division\");\n");
+      }
+      printf("   {\n");
+
+      if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
+        printf("   %sword64 d1 = op1;\n", (boolU ? "u" : ""));
+        printf("   %sword64 d2 = op2;\n", (boolU ? "u" : ""));
+        printf("   if (d2 == 0)\n");
+        printf("     {\n");
+        printf("     LO%s = SIGNED64 (0x8000000000000000);\n", pipe);
+        printf("     HI%s = 0;\n", pipe);
+        printf("     }\n");
+        printf("   else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000))\n");
+        printf("     {\n");
+        printf("     LO%s = SIGNED64 (0x8000000000000000);\n", pipe);
+        printf("     HI%s = 0;\n", pipe);
+        printf("     }\n");
+        printf("   else\n");
+        printf("     {\n");
+        printf("     LO%s = (d1 / d2);\n", pipe);
+        printf("     HI%s = (d1 %% d2);\n", pipe);
+        printf("     }\n");
+      } else {
+        printf("   %sint d1 = op1;\n", (boolU ? "unsigned " : ""));
+        printf("   %sint d2 = op2;\n", (boolU ? "unsigned " : ""));
+        printf("   if (d2 == 0)\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND(0x80000000,32);\n",pipe);
+       printf("     HI%s = SIGNEXTEND(0,32);\n", pipe);
+        printf("     }\n");
+        printf("   else if (d2 == -1 && d1 == 0x80000000)\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND(0x80000000,32);\n",pipe);
+       printf("     HI%s = SIGNEXTEND(0,32);\n", pipe);
+        printf("     }\n");
+        printf("   else\n");
+        printf("     {\n");
+       printf("     LO%s = SIGNEXTEND((d1 / d2),32);\n", pipe);
+       printf("     HI%s = SIGNEXTEND((d1 %% d2),32);\n", pipe);
+        printf("     }\n");
+      }
+      printf("   }\n");
+     }
+    break ;
+
+    case SHIFT:
+     {
+      int datalen = GETDATASIZEINSN(insn);
+      int bits = ((datalen == WORD) ? 32 : 64);
+      char *ltype = ((datalen == WORD) ? "unsigned int" : "uword64");
+
+      /* Check that the specified SHIFT is valid: */
+      if ((datalen == BYTE) || (datalen == HALFWORD)) {
+       fprintf(stderr,"Shift \"%s\" specified with BYTE or HALFWORD\n",insn->name);
+       exit(9);
+      }
+      if ((insn->flags & LEFT) && (insn->flags & RIGHT)) {
+       fprintf(stderr,"Shift \"%s\" specified with both LEFT and RIGHT\n",insn->name);
+       exit(9);
+      }
+      if (!(insn->flags & LEFT) && !(insn->flags & RIGHT)) {
+       fprintf(stderr,"Shift \"%s\" specified with neither LEFT or RIGHT\n",insn->name);
+       exit(9);
+      }
+      if ((insn->flags & LOGICAL) && (insn->flags & ARITHMETIC)) {
+       fprintf(stderr,"Shift \"%s\" specified with both LOGICAL and ARITHMETIC\n",insn->name);
+       exit(9);
+      }
+      if (!(insn->flags & LOGICAL) && !(insn->flags & ARITHMETIC)) {
+       fprintf(stderr,"Shift \"%s\" specified with neither LOGICAL or ARITHMETIC\n",insn->name);
+       exit(9);
+      }
+      if ((insn->flags & LEFT) && (insn->flags & ARITHMETIC)) {
+       fprintf(stderr,"Arithmetic LEFT shift \"%s\" specified\n",insn->name);
+       exit(9);
+      }
+
+      /* Work around an MSC code generation bug by precomputing a value
+       * with the sign bit set.  */
+      if (insn->flags & ARITHMETIC)
+       printf("   %s highbit = (%s)1 << %d;\n", ltype, ltype, bits - 1);
+
+      /* If register specified shift, then extract the relevant shift amount: */
+      if (insn->flags & REG)
+       printf("   op1 &= 0x%02X;\n",(bits - 1));
+
+      /* If HI32 specified, then shift range is 32..63 */
+      if (insn->flags & HI32)
+       printf("   op1 |= (1 << 5);\n");
+
+      /* We do not need to perform pre-masking with 0xFFFFFFFF when
+        dealing with 32bit shift lefts, since the sign-extension
+        code will replace any remaining hi-bits: */
+      if (insn->flags & LEFT)
+       printf("   GPR[destreg] = ((uword64)op2 << op1);\n");
+      else
+       printf("   GPR[destreg] = ((uword64)(op2%s) >> op1);\n",((bits == 32) ? " & 0xFFFFFFFF" : ""));
+
+      /* For ARITHMETIC shifts, we must duplicate the sign-bit.  We
+        don't do this if op1 is zero, since it is not needed and
+        since that would cause an undefined shift of the number of
+        bits in the type.  */
+      if (insn->flags & ARITHMETIC)
+       printf("   GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((%s)1 << op1) - 1) << (%d - op1)) : 0);\n",ltype,bits);
+
+      /* Ensure WORD values are sign-extended into 64bit registers */
+      if ((bits == 32) && (gprlen == 64))
+       printf("   GPR[destreg] = SIGNEXTEND(GPR[destreg],%d);\n",bits);
+     }
+     break ;
+
+    case MOVE:
+     if (insn->flags & (HI | LO)) {
+       char *regname = ((insn->flags & LO) ? "LO" : "HI");
+       int pipe1 = (insn->flags & PIPE1);
+       if (insn->flags & LEFT)
+       printf("   GPR[destreg] = %s%s;\n",regname,(pipe1 ? "1" : ""));
+       else {
+        if (features & FEATURE_WARN_LOHI) {
+          printf("   if (%s%sACCESS != 0)\n",regname,(pipe1 ? "1" : ""));
+          printf("     sim_io_eprintf(sd,\"MT (move-to) over-writing %s register value\\n\");\n",regname);
+        }
+        printf("   %s%s = op1;\n",regname,(pipe1 ? "1" : ""));
+       }
+       if (features & FEATURE_WARN_LOHI)
+       printf("   %s%sACCESS = 3; /* 3rd instruction will be safe */\n",regname,(pipe1 ? "1" : ""));
+     } else
+      if (insn->flags & SHIFT16)
+       printf("   GPR[destreg] = (op2 << 16);\n");
+      else {
+       /* perform conditional move */
+       if (!(insn->flags & EQ)) {
+         fprintf(stderr,"Standard conditional %s does not have the equality flag\n",insn->name);
+         exit(8);
+       }
+       printf("   if (op2 %c= 0)\n",((insn->flags & NOT) ? '!' : '='));
+       printf("    GPR[destreg] = op1;\n");
+      }
+     break ;
+
+    case SYNC:
+     printf("   SyncOperation(op1);\n");
+     break ;
+
+    case SYSCALL:
+     printf("   SignalException(SystemCall,instruction);\n");
+     break ;
+
+    case BREAK:
+     printf("   SignalException(BreakPoint,instruction);\n");
+     break ;
+
+    case SDBBP:
+     printf("   SignalException(DebugBreakPoint,instruction);\n");
+     break ;
+
+    case TRAP:
+     {
+      int boolNOT = (insn->flags & NOT);
+      int boolEQ  = (insn->flags & EQ);
+      int boolGT  = (insn->flags & GT);
+      int boolLT  = (insn->flags & LT);
+      int boolU   = (insn->flags & UNSIGNED);
+
+      if (boolGT && boolLT) {
+       fprintf(stderr,"GT and LT specified for \"%s\"\n",insn->name);
+       exit(8);
+      }
+
+      if (boolNOT && (boolGT || boolLT)) {
+       fprintf(stderr,"NOT specified with GT or LT specified for \"%s\"\n",insn->name);
+       exit(8);
+      }
+
+      printf("  if ((%sword64)op1 ",(boolU ? "u" : ""));
+      printf("%c%s",(boolNOT ? '!' : (boolLT ? '<' : (boolGT ? '>' : '='))),(boolEQ ? "=" : ""));
+      printf(" (%sword64)op2)\n",(boolU ? "u" : ""));
+      printf("   SignalException(Trap,instruction);\n");
+     }
+     break ;
+
+    case SET:
+     {
+      int boolU = (insn->flags & UNSIGNED);
+
+      if (!(insn->flags & LT)) {
+       fprintf(stderr,"Set instruction without LT specified \"%s\"\n",insn->name);
+       exit(8);
+      }
+
+      printf("   if ((%sword64)op1 < (%sword64)op2)\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
+      printf("    GPR[destreg] = 1;\n");
+      printf("   else\n");
+      printf("    GPR[destreg] = 0;\n");
+     }
+     break ;
+
+    case AND:
+     printf("   GPR[destreg] = (op1 & op2);\n");
+     break ;
+
+    case OR:
+     /* The default mips16 nop instruction does an or to register
+        zero; catch that case, so that we don't get useless warnings
+        from the simulator.  */
+     if (mips16)
+       printf ("   if (destreg != 0)\n");
+     printf("   GPR[destreg] = %s(op1 | op2);\n",((insn->flags & NOT) ? "~" : ""));
+     break ;
+
+    case XOR:
+     printf("   GPR[destreg] = (op1 ^ op2);\n");
+     break ;
+
+    case DECODE:
+     printf("   DecodeCoproc(instruction);\n");
+     break ;
+
+    case CACHE:
+     /* 16-bit offset is sign-extended and added to the base register to make a virtual address */
+     /* The virtual address is translated to a physical address using the TLB */
+     /* The hint specifies a cache operation for that address */
+     printf("    address_word vaddr = (op1 + offset);\n");
+     printf("    address_word paddr;\n");
+     printf("    int uncached;\n");
+     /* NOTE: We are assuming that the AddressTranslation is a load: */
+     printf("    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
+     printf("      CacheOp(hint,vaddr,paddr,instruction);\n");
+     break;
+
+    case MADD16: /* VR4100 specific multiply-add instructions */
+     /* Some of this code is shared with the standard multiply
+       routines, so an effort should be made to merge where
+       possible. */
+     if (features & FEATURE_WARN_LOHI) {
+       printf("   CHECKHILO(\"Multiply-Add\");\n");
+     }
+     if (features & FEATURE_WARN_RESULT) {
+       /* Give user a warning if either op1 or op2 are not 16bit signed integers */
+       printf("   if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
+       printf("     sim_io_eprintf(sd,\"MADD16 operation with non-16bit operands\\n\");\n");
+     }
+     printf("   {\n");
+     printf("    uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
+     if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
+       printf("   LO = LO + temp;\n");
+     } else { /* WORD */
+       printf("   temp += (SET64HI(WORD64LO(HI)) | WORD64LO(LO));\n");
+       printf("   LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
+       printf("   HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
+     }
+     printf("   }\n");
+     break;
+
+    case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
+     if (doisa < 4) {
+       printf("   if (CoProcPresent(3))\n");
+       printf("    SignalExceptionCoProcessorUnusable ();\n");
+       printf("   else\n");
+     }
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     break ;
+
+    case JUMP:
+     if (insn->flags & LINK) {
+       if (!(insn->flags & REG))
+       printf("   int destreg = 31;\n");
+       printf("   GPR[destreg] = (PC + %d); /* NOTE: The PC is already %d ahead within the simulator */\n",
+             mips16 ? 2 : 4, mips16 ? 2 : 4);
+     }
+
+     if (insn->flags & NOT)
+       printf("   op1 ^= 1;\n");
+
+     printf("   /* NOTE: ??? Gdb gets confused if the PC is sign-extended,\n");
+     printf("            so we just truncate it to 32 bits here.  */\n");
+     printf("   op1 = WORD64LO(op1);\n");
+     printf("   /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
+     printf("   DSPC = op1;\n");
+     if ((insn->flags & LINK)
+         && ! (insn->flags & REG))
+       printf("   JALDELAYSLOT();\n");
+     else
+       printf("   DELAYSLOT();\n");
+     break ;
+
+    case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
+     if (insn->flags & FP) {
+       if (doisa < 4) {
+        printf("  if (condition_code != 0)\n");
+        printf("   SignalException(ReservedInstruction,instruction);\n");
+        printf("  else {\n");
+       }
+       /* "PREVCOC1()" should be the COC1 value at the start of the preceding instruction */
+       printf("   int condition = (%s == boolean);\n",((doisa < 4) ? "PREVCOC1()" : "GETFCC(condition_code)"));
+     } else {
+       if ((insn->flags & NOT) && !(insn->flags & EQ)) {
+        fprintf(stderr,"NOT specified when not EQ in \"%s\"\n",insn->name);
+        exit(7);
+       }
+       if ((insn->flags & NOT) && (insn->flags & (GT | LT))) {
+        fprintf(stderr,"NOT specified with GT or LT in \"%s\"\n",insn->name);
+        exit(7);
+       }            
+       /* GT  LT */
+       if (insn->flags & GT)
+       printf("   int condition = (op1 >%s 0);\n",((insn->flags & EQ) ? "=" : ""));
+       else
+       if (insn->flags & LT)
+        printf("   int condition = (op1 <%s 0);\n",((insn->flags & EQ) ? "=" : ""));
+       else
+        if (insn->flags & EQ)
+         printf("   int condition = (op1 %c= op2);\n",((insn->flags & NOT) ? '!' : '='));
+     }
+
+     if (insn->flags & LINK) {
+       if (features & FEATURE_WARN_R31) {
+        printf("   if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
+        printf("    sim_io_eprintf(sd,\"Branch with link using r31 as source operand\\n\");\n");
+       }
+       printf("   GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
+     }
+
+     if (! mips16) {
+       printf("   /* NOTE: The branch occurs AFTER the next instruction has been executed */\n");
+       printf("   if (condition) {\n");
+       printf("    DSPC = (PC + offset);\n");
+       printf("    DELAYSLOT();\n");
+       printf("   }\n");
+     } else {
+       /* No delayed slots for mips16 branches.  */
+       printf("   if (condition)\n");
+       printf("    PC = PC + offset;\n");
+     }
+     if ((insn->flags & FP) && (doisa != 1)) {
+       printf("   else if (likely) {\n");
+       printf("    NULLIFY();\n");
+       printf("   }\n");
+     } else if (insn->flags & LIKELY) {
+       printf("   else\n");
+       printf("    NULLIFY();\n");
+     }
+     if ((insn->flags & FP) && (doisa < 4))
+      printf("   }\n");
+     break ;
+
+    case PREFETCH: /* The beginning is shared with normal load operations */
+    case LOAD:
+    case STORE:
+     {
+      int isload = ((insn->type == LOAD) || (insn->type == PREFETCH));
+      int datalen;
+      char *accesslength = "<UNKNOWN>";
+
+      switch (GETDATASIZEINSN(insn)) {
+       case BYTE :
+        datalen = 1;
+        accesslength = "AccessLength_BYTE";
+        break ;
+
+       case HALFWORD :
+        datalen = 2;
+        accesslength = "AccessLength_HALFWORD";
+        break ;
+
+       case WORD :
+        datalen = 4;
+        accesslength = "AccessLength_WORD";
+        break ;
+
+       case DOUBLEWORD :
+        datalen = 8;
+        accesslength = "AccessLength_DOUBLEWORD";
+        break ;
+        /* start-sanitize-r5900 */
+
+       case QUADWORD :
+        datalen = 16;
+        accesslength = "AccessLength_QUADWORD";
+        break ;
+        /* end-sanitize-r5900 */
+      }
+
+      if (insn->flags & REG)
+       printf("   address_word vaddr = ((uword64)op1 + op2);\n");
+      else
+       printf("   address_word vaddr = ((uword64)op1 + offset);\n");
+      printf("   address_word paddr;\n");
+      printf("   int uncached;\n");
+
+      /* The following check should only occur on normal (non-shifted) memory loads */
+      if ((datalen != 1) && !(insn->flags & (LEFT | RIGHT))) {
+       printf("   if ((vaddr & %d) != 0)\n",(datalen - 1));
+       printf("    SignalException%s();\n",(isload ? "AddressLoad" : "AddressStore"));
+       printf("   else\n") ;
+      }
+
+      printf("   {\n");
+      printf("    if (AddressTranslation(vaddr,isDATA,%s,&paddr,&uncached,isTARGET,isREAL))\n",(isload ? "isLOAD" : "isSTORE"));
+
+      if (insn->type == PREFETCH)
+       printf("     Prefetch(uncached,paddr,vaddr,isDATA,hint);\n");
+      else {
+       printf("    {\n");
+       printf("     uword64 memval = 0;\n");
+        printf("     uword64 memval1 = 0;\n");
+
+       if ((insn->flags & COPROC) && ((datalen != 4) && (datalen != 8))) {
+         fprintf(stderr,"Co-processor transfer operation not WORD or DOUBLEWORD in length \"%s\"\n",insn->name);
+         exit(6);
+       }
+
+       if (insn->flags & (LEFT | RIGHT)) {
+         if ((insn->flags & LEFT) && (insn->flags & RIGHT)) {
+           fprintf(stderr,"Memory transfer with both LEFT and RIGHT specified \"%s\"\n",insn->name);
+           exit(4);
+         }
+
+         switch (datalen) {
+          case 8:
+            if (!(features & FEATURE_IGEN))
+              {
+                if (!proc64) {
+                  fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",insn->name);
+                  exit(4);
+                }
+              }
+            /* fall through to... */
+          case 4:
+           {
+             printf("     uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
+             printf("     unsigned int reverse = (ReverseEndian ? mask : 0);\n");
+             printf("     unsigned int bigend = (BigEndianCPU ? mask : 0);\n");
+             printf("     int byte;\n");
+             printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
+             printf("     byte = ((vaddr & mask) ^ bigend);\n");
+             printf("     if (%sBigEndianMem)\n",((insn->flags & LEFT) ? "!" : ""));
+             printf("      paddr &= ~mask;\n");
+
+             if (isload) {
+               if (insn->flags & LEFT)
+                  {
+                    printf("     LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL);\n");
+                  }
+               else
+                  {
+                    printf("     LoadMemory(&memval,&memval1,uncached,(%d - byte),paddr,vaddr,isDATA,isREAL);\n",(datalen - 1));
+                  }
+             }
+
+             if (insn->flags & LEFT) {
+               if (isload) {
+                 /* For WORD transfers work out if the value will
+                    be in the top or bottom of the DOUBLEWORD
+                    returned: */
+#if 1
+                 build_endian_shift(proc64,datalen,2,s_right,32);
+#else
+                 if (proc64 && (datalen == 4)) {
+                   printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
+                   printf("      memval >>= 32;\n");
+                   printf("     }\n");
+                 }
+#endif
+                 printf("     GPR[destreg] = ((memval << ((%d - byte) * 8)) | (GPR[destreg] & (((uword64)1 << ((%d - byte) * 8)) - 1)));\n",(datalen - 1),(datalen - 1));
+                 if (proc64 && (datalen == 4))
+                  printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
+               } else { /* store */
+                 printf("     memval = (op2 >> (8 * (%d - byte)));\n",(datalen - 1));
+#if 1
+                 build_endian_shift(proc64,datalen,2,s_left,32);
+#else
+                 /* TODO: This is duplicated in the LOAD code
+                    above - and the RIGHT LOAD and STORE code
+                    below. It should be merged if possible. */
+                 if (proc64 && (datalen == 4)) {
+                   printf("    if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
+                   printf("     memval <<= 32;\n");
+                   printf("    }\n");
+                 }
+#endif
+                 printf("     StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL);\n");
+               }
+             } else { /* RIGHT */
+               if (isload) {
+#if 1
+                 build_endian_shift(proc64,datalen,2,s_right,32);
+#else
+                 if (proc64 && (datalen == 4)) {
+                   printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
+                   printf("      memval >>= 32;\n");
+                   printf("     }\n");
+                 }
+#endif
+                 printf("     {\n");
+                 printf("      uword64 srcmask;\n");
+                 /* All of this extra code is just a bodge
+                    required because some hosts don't allow
+                    ((v) << 64). The SPARC just leaves the (v)
+                    value un-touched. */
+                 printf("      if (byte == 0)\n");
+                 printf("       srcmask = 0;\n");
+                 printf("      else\n");
+                 printf("       srcmask = ((uword64)-1 << (8 * (%d - byte)));\n",datalen);
+                 printf("      GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));\n");
+                 printf("     }\n");
+                 if (proc64 && (datalen == 4))
+                  printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
+               } else { /* store */
+                 printf("     memval = ((uword64) op2 << (byte * 8));\n");
+                 build_endian_shift(proc64,datalen,2,s_left,32);
+                 printf("     StoreMemory(uncached,(%s - byte),memval,memval1,paddr,vaddr,isREAL);\n",accesslength);
+               }
+             }
+           }
+           break;
+
+          default:
+           fprintf(stderr,"Shifted memory transfer not WORD or DOUBLEWORD in length \"%s\"\n",insn->name);
+           exit(6);
+         }
+       } else { /* normal memory transfer */
+         if (!(features & FEATURE_IGEN))
+           {
+             if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
+               fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
+               exit(4);
+               /* TODO: The R4000 documentation states that a LWU
+                  instruction executed when in a 32bit processor mode
+                  should cause a ReservedInstruction exception. This
+                  will mean adding a run-time check into the code
+                  sequence. */
+             }
+           }
+         
+         if (isload) {
+#if 1 /* see the comments attached to LOADDRMASK above */
+           printf("     uword64 mask = 0x7;\n");
+#else
+           printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
+#endif
+           printf("     unsigned int shift = %d;\n",(datalen >> 1));
+           printf("     unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0);\n");
+           printf("     unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0);\n");
+           printf("     unsigned int byte UNUSED;\n");
+
+/* TODO: This should really also check for 32bit world performing 32bit access */
+           if (datalen < 8)
+             /* not for DOUBLEWORD */
+             /* start-sanitize-r5900 */
+             /* not for QUADWORD */
+             /* end-sanitize-r5900 */
+             printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
+
+           printf("     LoadMemory(&memval,&memval1,uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
+              
+           /* The following will only make sense if the
+              "LoadMemory" above returns a DOUBLEWORD entity */
+           if (datalen < 8) {
+             /* not for DOUBLEWORD */
+             /* start-sanitize-r5900 */
+             /* not for QUADWORD */
+             /* end-sanitize-r5900 */
+             int valmask;
+             switch (datalen) {
+              case 1:
+               valmask = 0xFF;
+               break;
+
+              case 2:
+               valmask = 0xFFFF;
+               break;
+
+              case 4:
+               valmask = 0xFFFFFFFF;
+               break;
+
+              default:
+               fprintf(stderr,"Unrecognised datalen (%d) when processing \"%s\"\n",datalen,insn->name);
+               exit(4);
+             }
+             printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
+             /* NOTE: The R4000 user manual has the COP_LW
+                occuring in the same cycle as the rest of the
+                instruction, yet the MIPS IV shows the operation
+                happening on the next cycle. To keep the simulator
+                simple, this code follows the R4000
+                manual. Experimentation with a silicon
+                implementation will be needed to ascertain the
+                correct operation. */
+             if (insn->flags & COPROC)
+              printf("     COP_LW(%s,destreg,(unsigned int)",
+                     ((insn->flags & REG)
+                      ? "1"
+                      : "((instruction >> 26) & 0x3)"));
+             else
+              printf("     GPR[destreg] = (");
+
+             if (insn->flags & SIGNEXTEND)
+              printf("SIGNEXTEND(");
+             printf("((memval >> (8 * byte)) & 0x%08X)",valmask);
+             if (insn->flags & SIGNEXTEND)
+              printf(",%d)",(datalen * 8));
+             printf(");\n");
+           } else {
+             if (insn->flags & COPROC)
+              printf("     COP_LD(%s,destreg,memval);;\n",
+                     ((insn->flags & REG)
+                      ? "1"
+                      : "((instruction >> 26) & 0x3)"));
+             else
+                {
+                  printf("     GPR[destreg] = memval;\n");
+                  if (datalen > 8)
+                    printf("     GPR1[destreg] = memval1;\n");
+                }
+           }
+         } else { /* store operation */
+           if ((datalen == 1) || (datalen == 2)) {
+             /* SH and SB */
+#if 1 /* see the comments attached to LOADDRMASK above */
+             printf("     uword64 mask = 0x7;\n");
+#else
+             printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
+#endif
+             printf("     unsigned int shift = %d;\n",(datalen >> 1));
+             printf("     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
+             printf("     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
+             printf("     unsigned int byte;\n");
+
+             printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
+             printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
+             printf("     memval = ((uword64) op2 << (8 * byte));\n");
+           } else
+            if (datalen == 4) { /* SC and SW */
+#if 1 /* see the comments attached to LOADDRMASK above */
+              printf("     uword64 mask = 0x7;\n");
+#else
+              printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
+#endif
+              printf("     unsigned int byte;\n");
+              printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
+              printf("     byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
+              if (insn->flags & COPROC)
+               printf("     memval = (((uword64)COP_SW(%s,%s)) << (8 * byte));\n",
+                      ((insn->flags & REG)
+                       ? "1"
+                       : "((instruction >> 26) & 0x3)"),
+                      ((insn->flags & FP) ? "fs" : "destreg"));
+              else
+               printf("     memval = ((uword64) op2 << (8 * byte));\n");
+            } else if (datalen <= 8) { /* SD and SCD */
+              if (! (features & FEATURE_IGEN))
+                {
+                  if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
+                    fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
+                    exit(4);
+                  }
+                }
+              if (insn->flags & COPROC)
+               printf("     memval = (uword64)COP_SD(%s,%s);\n",
+                      ((insn->flags & REG)
+                       ? "1"
+                       : "((instruction >> 26) & 0x3)"),
+                      ((insn->flags & FP) ? "fs" : "destreg"));
+              else
+               printf("     memval = op2;\n");
+            } else { /* wider than 8 */
+               if (insn->flags & COPROC) {
+                fprintf(stderr,"COPROC not available for 128 bit operations \"%s\"\n",insn->name);
+                exit(4);
+               }
+               printf("     memval  = rt_reg;\n");
+               printf("     memval1 = rt_reg1;\n");
+            }
+
+           if (insn->flags & ATOMIC)
+            printf("      if (LLBIT)\n");
+
+           printf("      {\n");
+           printf("       StoreMemory(uncached,%s,memval,memval1,paddr,vaddr,isREAL);\n",accesslength);
+           printf("      }\n");
+         }
+
+         if (insn->flags & ATOMIC) {
+           if ((datalen != 4) && (datalen != 8)) {
+             fprintf(stderr,"ATOMIC can only be applied to WORD and DOUBLEWORD instructions \"%s\"\n",insn->name);
+             exit(4);
+           } else
+            if (isload)
+             printf("     LLBIT = 1;\n");
+            else {
+              /* The documentation states that:
+
+                 SC *WILL* fail if coherent store into the same
+                 block occurs, or if an exception occurs between
+                 the LL and SC instructions.
+
+                 SC *MAY* fail if a load, store or prefetch is
+                 executed on the processor (VR4300 doesn't seem
+                 to), or if the instructions between the LL and
+                 SC are not in a 2048byte contiguous VM range.
+
+                 SC *MUST* have been preceded by an LL
+                 (i.e. LLBIT will be set), and it must use the
+                 same Vaddr, Paddr and cache-coherence algorithm
+                 as the LL (which means we should store this
+                 information from the load-conditional).
+                 */
+              printf("     GPR[(instruction >> %d) & 0x%08X] = LLBIT;\n",OP_SH_RT,OP_MASK_RT);
+            }
+         }
+       }
+       printf("    }\n");
+      }
+      printf("   }\n");
+     }
+     break ;
+
+    case FPPREFX:
+     /* This code could be merged with the PREFIX generation above: */
+     printf("   address_word vaddr = ((uword64)op1 + (uword64)op2);\n");
+     printf("   address_word paddr;\n");
+     printf("   int uncached;\n");
+     printf("   if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
+     printf("    Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
+     break ;
+
+    case FPMOVEC:
+     if (insn->flags & CONTROL) {
+       /* The following "magic" of interpreting the FP
+         control-register number would not be needed if we were not
+         trying to match our internal register numbers with those
+         used by GDB. */
+       printf("    if (to) {\n");
+       if (doisa < 4) {
+        printf("     if (fs == 0) {\n");
+        printf("      PENDING_FILL((fs + FCR0IDX),WORD64LO(GPR[ft]));\n");
+        printf("     } else if (fs == 31) {\n");
+        printf("      PENDING_FILL((fs + FCR31IDX),WORD64LO(GPR[ft]));\n");
+        printf("     } /* else NOP */\n");
+        printf("     PENDING_FILL(COCIDX,0); /* special case */\n");
+       } else {
+        printf("     if (fs == 0) {\n");
+        printf("      FCR0 = WORD64LO(GPR[ft]);\n");
+        printf("     } else if (fs == 31) {\n");
+        printf("      FCR31 = WORD64LO(GPR[ft]);\n");
+        printf("     } /* else NOP */\n");
+        printf("     SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); /* COC[1] */\n");
+       }
+       printf("    } else { /* control from */\n");
+       if (doisa < 4) {
+        printf("     if (fs == 0) {\n");
+        printf("      PENDING_FILL(ft,SIGNEXTEND(FCR0,32));\n");
+        printf("     } else if (fs == 31) {\n");
+        printf("      PENDING_FILL(ft,SIGNEXTEND(FCR31,32));\n");
+        printf("     } /* else NOP */\n");
+       } else {
+        printf("     if (fs == 0) {\n");
+        printf("      GPR[ft] = SIGNEXTEND(FCR0,32);\n");
+        printf("     } else if (fs == 31) {\n");
+        printf("      GPR[ft] = SIGNEXTEND(FCR31,32);\n");
+        printf("     } /* else NOP */\n");
+       }
+       printf("    }\n");
+     } else {
+       printf("    if (to) {\n");
+       if (GETDATASIZEINSN(insn) == WORD) {
+        if (doisa < 4) { 
+          printf("     if (SizeFGR() == 64) {\n");
+          printf("      PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft])));\n");
+          printf("     } else { \n");
+          printf("      PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
+          printf("     }\n");
+        } else {
+          printf("     if (SizeFGR() == 64)\n");
+          printf("      FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
+          printf("     else\n");
+          printf("      FGR[fs] = WORD64LO(GPR[ft]);\n");
+          printf("     FPR_STATE[fs] = fmt_uninterpreted;\n");
+        }
+       } else if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
+        if (doisa < 4) {
+          printf("     if (SizeFGR() == 64) {\n");
+          printf("      PENDING_FILL((fs + FGRIDX),GPR[ft]);\n");
+          printf("     } else\n");
+          printf("      if ((fs & 0x1) == 0)\n");
+          printf("       {\n");
+          printf("        PENDING_FILL(((fs + 1) + FGRIDX),WORD64HI(GPR[ft]));\n");
+          printf("        PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
+          printf("       }\n");
+          if (features & FEATURE_WARN_RESULT) {
+            printf("      else\n");
+            printf("       UndefinedResult();\n");
+          }
+        } else {
+          printf("     if (SizeFGR() == 64) {\n");
+          printf("      FGR[fs] = GPR[ft];\n");
+          printf("      FPR_STATE[fs] = fmt_uninterpreted;\n");
+          printf("     } else\n");
+          printf("      if ((fs & 0x1) == 0)\n");
+          printf("       {\n");
+          printf("        FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
+          printf("        FGR[fs] = WORD64LO(GPR[ft]);\n");
+          printf("        FPR_STATE[fs + 1] = fmt_uninterpreted;\n");
+          printf("        FPR_STATE[fs] = fmt_uninterpreted;\n");
+          printf("       }\n");
+          if (features & FEATURE_WARN_RESULT) {
+            printf("      else\n");
+            printf("       UndefinedResult();\n");
+          }
+        }
+       } else {
+        fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
+        exit(1);
+       }
+       printf("    } else {\n");
+       if (GETDATASIZEINSN(insn) == WORD) {
+        if (doisa < 4) /* write-back occurs in next cycle */
+         printf("     PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32));\n");
+        else /* in this cycle */
+         printf("     GPR[ft] = SIGNEXTEND(FGR[fs],32);\n");
+       } else if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
+        if (doisa < 4) { 
+          printf("     if (SizeFGR() == 64) {\n");
+          printf("      PENDING_FILL(ft,FGR[fs]);\n");
+          printf("     } else\n");
+          printf("      if ((fs & 0x1) == 0) {\n");
+          printf("       PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs]));\n");
+          printf("      } else {\n");
+          printf("       PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
+          if (features & FEATURE_WARN_RESULT)
+          printf("        UndefinedResult();\n");
+          printf("      }\n");
+        } else {
+          printf("     if (SizeFGR() == 64)\n");
+          printf("      GPR[ft] = FGR[fs];\n");
+          printf("     else\n");
+          printf("      if ((fs & 0x1) == 0)\n");
+          printf("       GPR[ft] = (SET64HI(FGR[fs + 1]) | FGR[fs]);\n");
+          printf("      else {\n");
+          printf("       GPR[ft] = (SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
+          if (features & FEATURE_WARN_RESULT)
+          printf("       UndefinedResult();\n");
+          printf("      }\n");
+        }
+       } else {
+        fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
+        exit(1);
+       }
+       printf("    }\n");
+     }
+     break ;
+
+    case FPMOVE:
+     if (insn->flags & CONDITIONAL) {
+       if (insn->flags & INTEGER) { /* moving GPR - testing FGR */
+        printf("   if (GETFCC(condition_code) == boolean)\n");
+        printf("    GPR[destreg] = op1;\n");
+       } else {
+        if (insn->flags & EQ) /* moving FGR - testing GPR */
+         printf("   if (op2 %c= 0)\n",((insn->flags & NOT) ? '!' : '='));
+        else
+         printf("   if (GETFCC(condition_code) == boolean)\n");
+        printf("    StoreFPR(destreg,format,ValueFPR(fs,format));\n");
+        printf("   else\n");
+        printf("    StoreFPR(destreg,format,ValueFPR(destreg,format));\n");
+       }
+     } else { /* simple MOVE */
+       printf("   StoreFPR(destreg,format,ValueFPR(fs,format));\n");
+     }
+     break ;
+
+    case FPNEG:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));\n");
+     break ;
+
+    case FPABS:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));\n");
+     break ;
+
+    case FPDIV:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
+     break ;
+
+    case FPMUL:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
+     break ;
+
+    case FPRECIP:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));\n");
+     break ;
+
+    case FPSQRT:
+     printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("  else\n");
+     printf("   StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)%s));\n",
+           ((insn->flags & RECIP) ? "Recip" : ""),
+           ((insn->flags & RECIP) ? ",format" : ""));
+     break ;
+
+    case FPCEIL:
+    case FPFLOOR:
+    case FPTRUNC:
+    case FPROUND:
+     {
+       char *op = "";
+       char *type = "";
+
+       switch (insn->type) {
+        case FPCEIL:
+         op = "FP_RM_TOPINF";
+         break;
+        case FPFLOOR:
+         op = "FP_RM_TOMINF";
+         break;
+        case FPTRUNC:
+         op = "FP_RM_TOZERO";
+         break;
+        case FPROUND:
+         op = "FP_RM_NEAREST";
+         break;
+        default:
+         fprintf(stderr,"Error: Handled missing for FP reason code %d\n",insn->type);
+         exit(1);
+       }
+
+       switch (GETDATASIZEINSN(insn)) {
+        case WORD :
+         type = "fmt_word";
+         break;
+        case DOUBLEWORD :
+         type = "fmt_long";
+         break;
+        default:
+         fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
+         exit(1);
+       }
+       printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+       printf("   SignalException(ReservedInstruction,instruction);\n");
+       printf("  else\n");
+       printf("   StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
+     }
+     break ;
+
+    case FPCONVERT:
+     {
+       char *type = "";
+       switch (GETDATASIZEINSN(insn)) {
+        case SINGLE:
+         type = "fmt_single";
+         break;
+        case DOUBLE:
+         type = "fmt_double";
+         break;
+        case WORD:
+         type = "fmt_word";
+         break;
+        case DOUBLEWORD:
+         type = "fmt_long";
+         break;
+        default :
+         fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZEINSN(insn));
+         exit(1);
+       }
+
+       /* Not all combinations of conversion are valid at the
+         moment: When converting to a fixed-point format, only
+         floating-point sources are allowed. */
+       printf("   if ((format == %s) | %s)\n",type,((insn->flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
+       printf("    SignalException(ReservedInstruction,instruction);\n");
+       printf("   else\n");
+       printf("    StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
+     }
+     break ;
+
+    case FPSUB:
+     if (insn->flags & MULTIPLY) {
+       char *type = "";
+       switch (GETDATASIZEINSN(insn)) {
+        case SINGLE:
+         type = "fmt_single";
+         break;
+        case DOUBLE:
+         type = "fmt_double";
+         break;
+        default:
+         fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZEINSN(insn));
+         exit(1);
+       }
+       if (insn->flags & NOT)
+        printf ("   StoreFPR(destreg,%s,Negate(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
+                type, type, type, type, type, type, type);
+       else
+        printf ("   StoreFPR(destreg,%s,Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
+                type, type, type, type, type, type);
+     } else {
+       printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+       printf("   SignalException(ReservedInstruction,instruction);\n");
+       printf("  else\n");
+       printf("   StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
+     }
+     break ;
+
+    case FPADD:
+     if (insn->flags & MULTIPLY) {
+       char *type = "";
+       switch (GETDATASIZEINSN(insn)) {
+        case SINGLE:
+         type = "fmt_single";
+         break;
+        case DOUBLE:
+         type = "fmt_double";
+         break;
+        default:
+         fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZEINSN(insn));
+         exit(1);
+       }
+       if (insn->flags & NOT)
+        printf ("   StoreFPR(destreg,%s,Negate(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
+                type, type, type, type, type, type, type);
+       else
+        printf ("   StoreFPR(destreg,%s,Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
+                type, type, type, type, type, type);
+     } else {
+       printf("  if ((format != fmt_single) && (format != fmt_double))\n");
+       printf("   SignalException(ReservedInstruction,instruction);\n");
+       printf("  else\n");
+       printf("   StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
+     }
+     break ;
+
+    case FPCOMPARE:
+     /* For the MIPS I,II or III there *MUST* be at least one
+       instruction between the compare that sets a condition code
+       and the branch that tests it. NOTE: However the hardware
+       does not detect this condition. */
+     /* Explicitly limit the operation to S and D formats: */
+     printf("   if ((format != fmt_single) && (format != fmt_double))\n");
+     printf("    SignalException(ReservedInstruction,instruction);\n") ;
+     printf("   else {\n");
+     if (doisa < 4) {
+       printf("    if (condition_code != 0)\n");
+       printf("     SignalException(ReservedInstruction,instruction);\n") ;
+       printf("    else\n");
+     }
+     printf("     {\n");
+     printf("      int ignore = 0;\n");
+     printf("      int less = 0;\n");
+     printf("      int equal = 0;\n");
+     printf("      int unordered = 1;\n");
+     printf("      uword64 ofs = ValueFPR(fs,format);\n");
+     printf("      uword64 oft = ValueFPR(ft,format);\n");
+     printf("      if (NaN(ofs,format) || NaN(oft,format)) {\n");
+     printf("      if (FCSR & FP_ENABLE(IO)) {\n");
+     printf("       FCSR |= FP_CAUSE(IO);\n");
+     printf("       SignalExceptionFPE ();\n");
+     printf("       ignore = 1;\n");
+     printf("      }\n");
+     printf("     } else {\n");
+     printf("      less = Less(ofs,oft,format);\n");
+     printf("      equal = Equal(ofs,oft,format);\n");
+     printf("      unordered = 0;\n");
+     printf("     }\n");
+     printf("     if (!ignore) {\n");
+     printf("      int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
+     printf("      SETFCC(condition_code,condition);\n");
+     printf("     }\n");
+     printf("    }\n");
+     printf("   }\n");
+     break ;
+
+    case MADD:
+     {
+       char* pipeline = (insn->flags & PIPE1) ? "1" : "";
+       int notsigned = (insn->flags & UNSIGNED);
+       char* prodtype = notsigned ? "uword64" : "word64";
+
+       printf("%s prod = (%s)WORD64(WORD64LO(HI%s),WORD64LO(LO%s)) + ((%s)%s(op1%s) * (%s)%s(op2%s));\n",
+              prodtype, prodtype, pipeline, pipeline, 
+              prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32"),
+              prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32")
+              );
+       printf("LO%s = SIGNEXTEND(prod,32);\n", pipeline );
+       printf("HI%s = SIGNEXTEND( WORD64HI(prod), 32);\n", pipeline );
+       printf("if( destreg != 0 ) GPR[destreg] = LO%s;\n", pipeline );
+       break;
+     }
+
+/* start-sanitize-r5900 */
+    case MxSA:
+      {
+        if (insn->flags & TO)
+          printf("SA = op1;\n");
+        else
+          printf("GPR[destreg] = SA;\n");
+        break;
+      }
+
+    case MTSAB:
+     printf("SA = ((op1 & 0xF) ^ (op2 & 0xF)) * 8;\n");
+     break;
+
+    case MTSAH:
+     printf("SA = ((op1 & 0x7) ^ (op2 & 0x7)) * 16;\n");
+     break;
+
+    case QFSRV:
+     printf("int bytes = (SA / 8) %% 16;\n");   /* mod 16 to avoid garbage */
+     printf("if (SA %% 8)\n");
+     printf("   SignalException(ReservedInstruction,instruction);\n");
+     printf("else\n");
+     printf("    {\n");
+     printf("    int i;\n");
+     printf("    for(i=0;i<(16-bytes);i++)\n");
+     printf("        GPR_SB(destreg,i) = RT_SB(bytes+i);\n");
+     printf("    for(;i<16;i++)\n");
+     printf("        GPR_SB(destreg,i) = RS_SB(i-(16-bytes));\n");
+     printf("    }\n");
+     break;
+
+    case PADD:
+     {
+       char* op = (insn->flags & SUBTRACT) ? "-" : "+";
+       char* name = name_for_data_len( insn );
+       char* letter = letter_for_data_len( insn );
+
+       char* tmptype;
+       char* maximum;
+       char* maxsat;
+       char* minimum;
+       char* signletter;
+
+       if ( insn->flags & UNSIGNED )
+         {
+           tmptype = type_for_data_len( insn, 0/*unsigned*/ );
+          signletter = "U";
+           maximum = umax_for_data_len( insn );
+          maxsat = (insn->flags & SUBTRACT) ? "0" : maximum;
+           minimum = 0;
+         }
+       else if ( insn->flags & SATURATE )
+         {
+           tmptype = type_for_data_len( insn, 1/*signed*/ );
+          signletter = "S";
+           maximum = max_for_data_len( insn );
+          maxsat = maximum;
+           minimum = min_for_data_len( insn );
+         }
+       else
+         {
+           tmptype = type_for_data_len( insn, 1/*signed*/ );
+          signletter = "S";
+           maximum = 0;
+          maxsat = 0;
+           minimum = 0;
+         }
+
+       printf("   int i;\n");
+       printf("   for (i=0; i < %sS_IN_MMI_REGS; i++)\n", name );
+       printf("    {\n");
+       printf("     %s s = RS_%s%s(i);\n", tmptype, signletter, letter);
+       printf("     %s t = RT_%s%s(i);\n", tmptype, signletter, letter);
+       printf("     %s r = s %s t;\n", tmptype, op);
+       if ( maximum )
+         {
+           printf("     if (r > %s)\n", maximum);
+           printf("      GPR_%s%s(destreg,i) = %s;\n", signletter, letter, maxsat );
+           if ( minimum )
+            {
+              printf("     else if (r < %s)\n", minimum);
+              printf("      GPR_%s%s(destreg,i) = %s;\n", signletter, letter, minimum );
+            }
+          printf("     else\n");
+          printf(" ");
+         }
+       printf("     GPR_%s%s(destreg,i) = r;\n", signletter, letter );
+       printf("    }\n");
+       break;
+     }
+
+    case PMULTH:
+     {
+       char* op;
+       if ( insn->flags & SUBTRACT )
+         op = "-";
+       else if ( insn->flags & ADDITION )
+         op = "+";
+       else
+         op = "";
+
+       printf("GPR_SW(destreg,0) = LO_SW(0) %s= (RS_SH(0) * RT_SH(0));\n", op);
+       printf("                    LO_SW(1) %s= (RS_SH(1) * RT_SH(1));\n", op);
+       printf("GPR_SW(destreg,1) = HI_SW(0) %s= (RS_SH(2) * RT_SH(2));\n", op);
+       printf("                    HI_SW(1) %s= (RS_SH(3) * RT_SH(3));\n", op);
+       printf("GPR_SW(destreg,2) = LO_SW(2) %s= (RS_SH(4) * RT_SH(4));\n", op);
+       printf("                    LO_SW(3) %s= (RS_SH(5) * RT_SH(5));\n", op);
+       printf("GPR_SW(destreg,3) = HI_SW(2) %s= (RS_SH(6) * RT_SH(6));\n", op);
+       printf("                    HI_SW(3) %s= (RS_SH(7) * RT_SH(7));\n", op);
+       break;
+     }
+
+    case PMULTW:
+     {
+       char* op;
+       char* sign  = (insn->flags & UNSIGNED) ? "U" : "S";
+       char* prodtype = (insn->flags & UNSIGNED) ? "unsigned64" : "signed64";
+       char* constructor = (insn->flags & UNSIGNED) ? "UWORD64" : "WORD64";
+
+       if ( insn->flags & SUBTRACT )
+         {
+           op = "-";
+           printf("   %s sum0 = %s( HI_SW(0), LO_SW(0) );\n", prodtype, constructor );
+           printf("   %s sum1 = %s( HI_SW(2), LO_SW(2) );\n", prodtype, constructor );
+         }
+       else if ( insn->flags & ADDITION )
+         {
+           op = "+";
+           printf("   %s sum0 = %s( HI_SW(0), LO_SW(0) );\n", prodtype, constructor );
+           printf("   %s sum1 = %s( HI_SW(2), LO_SW(2) );\n", prodtype, constructor );
+         }
+       else
+        {
+          op = "";
+          printf("   %s sum0 = 0;\n", prodtype );
+          printf("   %s sum1 = 0;\n", prodtype );
+        }
+          
+       printf("   %s prod0 = (%s)RS_%sW(0) * (%s)RT_%sW(0);\n", prodtype, prodtype, sign, prodtype, sign );
+       printf("   %s prod1 = (%s)RS_%sW(2) * (%s)RT_%sW(2);\n", prodtype, prodtype, sign, prodtype, sign );
+
+       printf("   sum0 %s= prod0;\n", op );
+       printf("   sum1 %s= prod1;\n", op );
+
+       printf("   GPR_%sD(destreg,0) = sum0;\n", sign );
+       printf("   GPR_%sD(destreg,1) = sum1;\n", sign );
+
+       printf("   LO  = SIGNEXTEND( sum0, 32 );\n");
+       printf("   HI  = SIGNEXTEND( WORD64HI(sum0), 32 );\n");
+       printf("   LO1 = SIGNEXTEND( sum1, 32 );\n");
+       printf("   HI1 = SIGNEXTEND( WORD64HI(sum1), 32 );\n");
+       break;
+     }
+
+    case PDIVW:
+     {
+       char* sign = (insn->flags & UNSIGNED) ? "U" : "S";
+       int i;
+       for (i = 0; i < 2; i ++)
+        {
+          char hi = (i == 0 ? ' ' : '1');
+          int d = i * 2;
+          if (! (insn->flags & UNSIGNED))
+            {
+              printf("if (RT_SW(%d) == -1)\n", d );
+              printf(" {\n");
+              printf("  LO%c = -RS_%sW(%d);\n", hi, sign, d );
+              printf("  HI%c = 0;\n", hi );
+              printf(" }\nelse ");
+            };
+          printf("if (RT_UW(%d) != 0)\n", d );
+          printf(" {\n");
+          printf("  LO%c = (signed32)(RS_%sW(%d) / RT_%sW(%d));\n", hi, sign, d, sign, d );
+          printf("  HI%c = (signed32)(RS_%sW(%d) %% RT_%sW(%d));\n", hi, sign, d, sign, d );
+          printf(" }\n");
+        }
+       break;
+     }
+
+    case PDIVBW:
+      printf("signed32 devisor = RT_SH(0);\n");
+      printf("if (devisor == -1)\n");
+      printf(" {\n");
+      printf("  LO_SW(0) = -RS_SW(0);\n");
+      printf("  HI_SW(0) = 0;\n");
+      printf("  LO_SW(1) = -RS_SW(1);\n");
+      printf("  HI_SW(1) = 0;\n");
+      printf("  LO_SW(2) = -RS_SW(2);\n");
+      printf("  HI_SW(2) = 0;\n");
+      printf("  LO_SW(3) = -RS_SW(3);\n");
+      printf("  HI_SW(3) = 0;\n");
+      printf(" }\n");
+      printf("else if (devisor != 0)\n");
+      printf(" {\n");
+      printf("  LO_SW(0) = RS_SW(0) / devisor;\n");
+      printf("  HI_SW(0) = SIGNEXTEND( (RS_SW(0) %% devisor), 16 );\n");
+      printf("  LO_SW(1) = RS_SW(1) / devisor;\n");
+      printf("  HI_SW(1) = SIGNEXTEND( (RS_SW(1) %% devisor), 16 );\n");
+      printf("  LO_SW(2) = RS_SW(2) / devisor;\n");
+      printf("  HI_SW(2) = SIGNEXTEND( (RS_SW(2) %% devisor), 16 );\n");
+      printf("  LO_SW(3) = RS_SW(3) / devisor;\n");
+      printf("  HI_SW(3) = SIGNEXTEND( (RS_SW(3) %% devisor), 16 );\n");
+      printf(" }\n");
+      break;
+
+    case PADSBH:
+     printf("int i;\n");
+     printf("for(i=0;i<HALFWORDS_IN_MMI_REGS/2;i++)\n");
+     printf("  GPR_SH(destreg,i) = RS_SH(i) - RT_SH(i);\n");
+     printf("for(;i<HALFWORDS_IN_MMI_REGS;i++)\n");
+     printf("  GPR_SH(destreg,i) = RS_SH(i) + RT_SH(i);\n");
+     break;
+
+    case PHMADDH:
+     {
+       char* op = (insn->flags & SUBTRACT) ? "-" : "+";
+       printf("GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) %s (RS_SH(0) * RT_SH(0));\n", op );
+       printf("GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) %s (RS_SH(2) * RT_SH(2));\n", op );
+       printf("GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) %s (RS_SH(4) * RT_SH(4));\n", op );
+       printf("GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) %s (RS_SH(6) * RT_SH(6));\n", op );
+     }
+     break;
+
+    case PSHIFT:
+     {
+       char* name = name_for_data_len( insn );
+       char* letter = letter_for_data_len( insn );
+       char* bits = bits_for_data_len( insn );
+       char* shift = (insn->flags & RIGHT) ? ">>" : "<<";
+       char* sign = (insn->flags & ARITHMETIC) ? "S" : "U";
+
+       printf("int shift_by = op1 & (%s-1);\n", bits );
+       printf("int i;\n");
+       printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
+       printf("    GPR_%s%s(destreg,i) = ", sign, letter );
+       if ( insn->flags & ARITHMETIC )
+         printf("SIGNEXTEND( ");
+       printf("(RT_%s%s(i) %s shift_by)", sign, letter, shift );
+       if ( insn->flags & ARITHMETIC )
+         printf(", (%s-shift_by) )", bits );
+       printf(";\n");
+       break;
+     }
+
+    case PSLLVW:
+     printf("int s0 = (RS_UB(0) & 0x1F);\n");
+     printf("int s1 = (RS_UB(8) & 0x1F);\n");
+     printf("signed32 temp0 = RT_UW(0) << s0;\n");
+     printf("signed32 temp1 = RT_UW(2) << s1;\n");
+     printf("GPR_SD(destreg,0) = (signed64)temp0;\n");
+     printf("GPR_SD(destreg,1) = (signed64)temp1;\n");
+     break;
+
+    case PSRLVW:
+     printf("GPR_UD(destreg,0) = SIGNEXTEND ( RT_UW(0) >> (RS_UB(0) & 0x1F), 31);\n");
+     printf("GPR_UD(destreg,1) = SIGNEXTEND ( RT_UW(2) >> (RS_UB(8) & 0x1F), 31);\n");
+     break;
+
+    case PSRAVW:
+     printf("GPR_SD(destreg,0) = SIGNEXTEND( (RT_SW (0) >> (RS_UB(0) & 0x1F)), 32-(RS_UB(0) & 0x1F) );\n");
+     printf("GPR_SD(destreg,1) = SIGNEXTEND( (RT_SW (2) >> (RS_UB(8) & 0x1F)), 32-(RS_UB(8) & 0x1F) );\n");
+     break;
+
+    case POP:
+     {
+       char* op1;
+       char* op2;
+       
+       if ( GET_OP_FROM_INSN(insn) == POP_AND )
+         {
+           op1 = "&";
+           op2 = "";
+         }
+       else if ( GET_OP_FROM_INSN(insn) == POP_OR )
+         {
+           op1 = "|";
+           op2 = "";
+         }
+       else if ( GET_OP_FROM_INSN(insn) == POP_NOR )
+         {
+           op1 = "|";
+           op2 = "~";
+         }
+       else if ( GET_OP_FROM_INSN(insn) == POP_XOR )
+         {
+           op1 = "^";
+           op2 = "";
+         }
+       
+       printf("int i;\n");
+       printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
+       printf("  GPR_UW(destreg,i) = %s(RS_UW(i) %s RT_UW(i));\n", op2, op1 );
+       break;
+     }
+
+    case PCMP:
+     {
+       char* name = name_for_data_len( insn );
+       char* letter = letter_for_data_len( insn );
+       char* maximum = umax_for_data_len( insn );
+       char* op = (insn->flags & GT) ? ">" : "==";
+
+       printf("int i;\n");
+       printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
+       printf("     {\n");
+       printf("     if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = %s;\n", 
+              letter, op, letter, letter, maximum );
+       printf("     else                        GPR_S%s(destreg,i) = 0;\n", letter );
+       printf("     }\n");
+       break;
+     }
+
+    case PMAXMIN:
+     {
+       char* name = name_for_data_len( insn );
+       char* letter = letter_for_data_len( insn );
+       char* op = (insn->flags & GT) ? ">" : "<";
+
+       printf("int i;\n");
+       printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
+       printf("     {\n");
+       printf("     if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = RS_S%s(i);\n", 
+              letter, op, letter, letter, letter );
+       printf("     else                        GPR_S%s(destreg,i) = RT_S%s(i);\n", letter, letter );
+       printf("     }\n");
+       break;
+     }
+
+    case PABS:
+     {
+       char* name = name_for_data_len( insn );
+       char* letter = letter_for_data_len( insn );
+       char* min = min_for_data_len( insn );
+       char* max = max_for_data_len( insn );
+
+       printf("int i;\n");
+       printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
+       printf("  {\n");
+       printf("  if (RT_S%s(i) >= 0)\n", letter );
+       printf("    GPR_S%s(destreg,i) =  RT_S%s(i);\n", letter, letter );
+       printf("  else if (RT_S%s(i) == %s)\n", letter, min );
+       printf("    GPR_S%s(destreg,i) = %s;\n", letter, max );
+       printf("  else\n");
+       printf("    GPR_S%s(destreg,i) = -RT_S%s(i);\n", letter, letter );
+       printf("  }\n");
+       break;
+     }
+
+    case PCPYH:
+     printf("GPR_UH(destreg,7) = GPR_UH(destreg,6) = GPR_UH(destreg,5) = GPR_UH(destreg,4) = RT_UH(4);\n");
+     printf("GPR_UH(destreg,3) = GPR_UH(destreg,2) = GPR_UH(destreg,1) = GPR_UH(destreg,0) = RT_UH(0);\n");
+     break;
+
+    case PCPYLD:
+     printf("GPR_UD(destreg,0) = RT_UD(0);\n");
+     printf("GPR_UD(destreg,1) = RS_UD(0);\n");
+     break;
+
+    case PCPYUD:
+     printf("GPR_UD(destreg,0) = RS_UD(1);\n");
+     printf("GPR_UD(destreg,1) = RT_UD(1);\n");
+     break;
+
+    case PEXCH:
+     printf("GPR_UH(destreg,0) = RT_UH(0);\n");
+     printf("GPR_UH(destreg,1) = RT_UH(2);\n");
+     printf("GPR_UH(destreg,2) = RT_UH(1);\n");
+     printf("GPR_UH(destreg,3) = RT_UH(3);\n");
+     printf("GPR_UH(destreg,4) = RT_UH(4);\n");
+     printf("GPR_UH(destreg,5) = RT_UH(6);\n");
+     printf("GPR_UH(destreg,6) = RT_UH(5);\n");
+     printf("GPR_UH(destreg,7) = RT_UH(7);\n");
+     break;
+
+    case PEXCW:
+     printf("GPR_UW(destreg,0) = RT_UW(0);\n");
+     printf("GPR_UW(destreg,1) = RT_UW(2);\n");
+     printf("GPR_UW(destreg,2) = RT_UW(1);\n");
+     printf("GPR_UW(destreg,3) = RT_UW(3);\n");
+     break;
+
+    case PEXOH:
+     printf("GPR_UH(destreg,0) = RT_UH(2);\n");
+     printf("GPR_UH(destreg,1) = RT_UH(1);\n");
+     printf("GPR_UH(destreg,2) = RT_UH(0);\n");
+     printf("GPR_UH(destreg,3) = RT_UH(3);\n");
+     printf("GPR_UH(destreg,4) = RT_UH(6);\n");
+     printf("GPR_UH(destreg,5) = RT_UH(5);\n");
+     printf("GPR_UH(destreg,6) = RT_UH(4);\n");
+     printf("GPR_UH(destreg,7) = RT_UH(7);\n");
+     break;
+
+    case PEXOW:
+     printf("GPR_UW(destreg,0) = RT_UW(2);\n");
+     printf("GPR_UW(destreg,1) = RT_UW(1);\n");
+     printf("GPR_UW(destreg,2) = RT_UW(0);\n");
+     printf("GPR_UW(destreg,3) = RT_UW(3);\n");
+     break;
+
+    case PEXTLB:
+     printf("GPR_UB(destreg,0)  = RT_UB(0);\n");
+     printf("GPR_UB(destreg,1)  = RS_UB(0);\n");
+     printf("GPR_UB(destreg,2)  = RT_UB(1);\n");
+     printf("GPR_UB(destreg,3)  = RS_UB(1);\n");
+     printf("GPR_UB(destreg,4)  = RT_UB(2);\n");
+     printf("GPR_UB(destreg,5)  = RS_UB(2);\n");
+     printf("GPR_UB(destreg,6)  = RT_UB(3);\n");
+     printf("GPR_UB(destreg,7)  = RS_UB(3);\n");
+     printf("GPR_UB(destreg,8)  = RT_UB(4);\n");
+     printf("GPR_UB(destreg,9)  = RS_UB(4);\n");
+     printf("GPR_UB(destreg,10) = RT_UB(5);\n");
+     printf("GPR_UB(destreg,11) = RS_UB(5);\n");
+     printf("GPR_UB(destreg,12) = RT_UB(6);\n");
+     printf("GPR_UB(destreg,13) = RS_UB(6);\n");
+     printf("GPR_UB(destreg,14) = RT_UB(7);\n");
+     printf("GPR_UB(destreg,15) = RS_UB(7);\n");
+     break;
+
+    case PEXTLH:
+     printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
+     printf("GPR_UH(destreg,1)  = RS_UH(0);\n");
+     printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
+     printf("GPR_UH(destreg,3)  = RS_UH(1);\n");
+     printf("GPR_UH(destreg,4)  = RT_UH(2);\n");
+     printf("GPR_UH(destreg,5)  = RS_UH(2);\n");
+     printf("GPR_UH(destreg,6)  = RT_UH(3);\n");
+     printf("GPR_UH(destreg,7)  = RS_UH(3);\n");
+     break;
+
+    case PEXTLW:
+     printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
+     printf("GPR_UW(destreg,1)  = RS_UW(0);\n");
+     printf("GPR_UW(destreg,2)  = RT_UW(1);\n");
+     printf("GPR_UW(destreg,3)  = RS_UW(1);\n");
+     break;
+
+    case PEXTUB:
+     printf("GPR_UB(destreg,0)  = RT_UB(8);\n");
+     printf("GPR_UB(destreg,1)  = RS_UB(8);\n");
+     printf("GPR_UB(destreg,2)  = RT_UB(9);\n");
+     printf("GPR_UB(destreg,3)  = RS_UB(9);\n");
+     printf("GPR_UB(destreg,4)  = RT_UB(10);\n");
+     printf("GPR_UB(destreg,5)  = RS_UB(10);\n");
+     printf("GPR_UB(destreg,6)  = RT_UB(11);\n");
+     printf("GPR_UB(destreg,7)  = RS_UB(11);\n");
+     printf("GPR_UB(destreg,8)  = RT_UB(12);\n");
+     printf("GPR_UB(destreg,9)  = RS_UB(12);\n");
+     printf("GPR_UB(destreg,10) = RT_UB(13);\n");
+     printf("GPR_UB(destreg,11) = RS_UB(13);\n");
+     printf("GPR_UB(destreg,12) = RT_UB(14);\n");
+     printf("GPR_UB(destreg,13) = RS_UB(14);\n");
+     printf("GPR_UB(destreg,14) = RT_UB(15);\n");
+     printf("GPR_UB(destreg,15) = RS_UB(15);\n");
+     break;
+
+    case PEXTUH:
+     printf("GPR_UH(destreg,0)  = RT_UH(4);\n");
+     printf("GPR_UH(destreg,1)  = RS_UH(4);\n");
+     printf("GPR_UH(destreg,2)  = RT_UH(5);\n");
+     printf("GPR_UH(destreg,3)  = RS_UH(5);\n");
+     printf("GPR_UH(destreg,4)  = RT_UH(6);\n");
+     printf("GPR_UH(destreg,5)  = RS_UH(6);\n");
+     printf("GPR_UH(destreg,6)  = RT_UH(7);\n");
+     printf("GPR_UH(destreg,7)  = RS_UH(7);\n");
+     break;
+
+    case PEXTUW:
+     printf("GPR_UW(destreg,0)  = RT_UW(2);\n");
+     printf("GPR_UW(destreg,1)  = RS_UW(2);\n");
+     printf("GPR_UW(destreg,2)  = RT_UW(3);\n");
+     printf("GPR_UW(destreg,3)  = RS_UW(3);\n");
+     break;
+
+    case PPACB:
+     printf("GPR_UB(destreg,0)  = RT_UB(0);\n");
+     printf("GPR_UB(destreg,1)  = RT_UB(2);\n");
+     printf("GPR_UB(destreg,2)  = RT_UB(4);\n");
+     printf("GPR_UB(destreg,3)  = RT_UB(6);\n");
+     printf("GPR_UB(destreg,4)  = RT_UB(8);\n");
+     printf("GPR_UB(destreg,5)  = RT_UB(10);\n");
+     printf("GPR_UB(destreg,6)  = RT_UB(12);\n");
+     printf("GPR_UB(destreg,7)  = RT_UB(14);\n");
+     printf("GPR_UB(destreg,8)  = RS_UB(0);\n");
+     printf("GPR_UB(destreg,9)  = RS_UB(2);\n");
+     printf("GPR_UB(destreg,10) = RS_UB(4);\n");
+     printf("GPR_UB(destreg,11) = RS_UB(6);\n");
+     printf("GPR_UB(destreg,12) = RS_UB(8);\n");
+     printf("GPR_UB(destreg,13) = RS_UB(10);\n");
+     printf("GPR_UB(destreg,14) = RS_UB(12);\n");
+     printf("GPR_UB(destreg,15) = RS_UB(14);\n");
+     break;
+
+    case PPACH:
+     printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
+     printf("GPR_UH(destreg,1)  = RT_UH(2);\n");
+     printf("GPR_UH(destreg,2)  = RT_UH(4);\n");
+     printf("GPR_UH(destreg,3)  = RT_UH(6);\n");
+     printf("GPR_UH(destreg,4)  = RS_UH(0);\n");
+     printf("GPR_UH(destreg,5)  = RS_UH(2);\n");
+     printf("GPR_UH(destreg,6)  = RS_UH(4);\n");
+     printf("GPR_UH(destreg,7)  = RS_UH(6);\n");
+     break;
+
+    case PPACW:
+     printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
+     printf("GPR_UW(destreg,1)  = RT_UW(2);\n");
+     printf("GPR_UW(destreg,2)  = RS_UW(0);\n");
+     printf("GPR_UW(destreg,3)  = RS_UW(2);\n");
+     break;
+
+    case PREVH:
+     printf("GPR_UH(destreg,0)  = RT_UH(3);\n");
+     printf("GPR_UH(destreg,1)  = RT_UH(2);\n");
+     printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
+     printf("GPR_UH(destreg,3)  = RT_UH(0);\n");
+     printf("GPR_UH(destreg,4)  = RT_UH(7);\n");
+     printf("GPR_UH(destreg,5)  = RT_UH(6);\n");
+     printf("GPR_UH(destreg,6)  = RT_UH(5);\n");
+     printf("GPR_UH(destreg,7)  = RT_UH(4);\n");
+     break;
+
+    case PROT3W:
+     printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
+     printf("GPR_UW(destreg,1)  = RT_UW(3);\n");
+     printf("GPR_UW(destreg,2)  = RT_UW(1);\n");
+     printf("GPR_UW(destreg,3)  = RT_UW(2);\n");
+     break;
+
+    case PINTH:
+     printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
+     printf("GPR_UH(destreg,1)  = RS_UH(4);\n");
+     printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
+     printf("GPR_UH(destreg,3)  = RS_UH(5);\n");
+     printf("GPR_UH(destreg,4)  = RT_UH(2);\n");
+     printf("GPR_UH(destreg,5)  = RS_UH(6);\n");
+     printf("GPR_UH(destreg,6)  = RT_UH(3);\n");
+     printf("GPR_UH(destreg,7)  = RS_UH(7);\n");
+     break;
+
+    case PINTOH:
+     printf("GPR_UH(destreg,0) = RT_UH(0);\n");
+     printf("GPR_UH(destreg,1) = RS_UH(0);\n");
+     printf("GPR_UH(destreg,2) = RT_UH(2);\n");
+     printf("GPR_UH(destreg,3) = RS_UH(2);\n");
+     printf("GPR_UH(destreg,4) = RT_UH(4);\n");
+     printf("GPR_UH(destreg,5) = RS_UH(4);\n");
+     printf("GPR_UH(destreg,6) = RT_UH(6);\n");
+     printf("GPR_UH(destreg,7) = RS_UH(6);\n");
+     break;
+
+    case PMXX:  /* Parallel move HI or LO / TO or FROM */
+     {
+       if ( (insn->flags & (HI|FROM)) == (HI|FROM) )
+         {
+           printf("GPR_SD(destreg,0) = HI;\n");
+           printf("GPR_SD(destreg,1) = HI1;\n");
+         }
+       else if ( (insn->flags & (LO|FROM)) == (LO|FROM) )
+         {
+           printf("GPR_SD(destreg,0) = LO;\n");
+           printf("GPR_SD(destreg,1) = LO1;\n");
+         }
+       else if ( (insn->flags & (HI|TO)) == (HI|TO) )
+         {
+           printf("HI  = RS_SD(0);\n");
+           printf("HI1 = RS_SD(1);\n");
+         }
+       else if ( (insn->flags & (LO|TO)) == (LO|TO) )
+         {
+           printf("LO  = RS_SD(0);\n");
+           printf("LO1 = RS_SD(1);\n");
+         }
+       break;
+     }
+
+    case PMTHL:
+     printf("LO_UW(0) = RS_UW(0);\n");
+     printf("HI_UW(0) = RS_UW(1);\n");
+     printf("LO_UW(2) = RS_UW(2);\n");
+     printf("HI_UW(2) = RS_UW(3);\n");
+     break;
+
+    case PMFHL:
+     printf("if (op1 == 0)\n");
+     printf("  {\n");
+     printf("  GPR_UW(destreg,0) = LO_UW(0);\n");
+     printf("  GPR_UW(destreg,1) = HI_UW(0);\n");
+     printf("  GPR_UW(destreg,2) = LO_UW(2);\n");
+     printf("  GPR_UW(destreg,3) = HI_UW(2);\n");
+     printf("  }\n");
+     printf("else if (op1 == 1)\n");
+     printf("  {\n");
+     printf("  GPR_UW(destreg,0) = LO_UW(1);\n");
+     printf("  GPR_UW(destreg,1) = HI_UW(1);\n");
+     printf("  GPR_UW(destreg,2) = LO_UW(3);\n");
+     printf("  GPR_UW(destreg,3) = HI_UW(3);\n");
+     printf("  }\n");
+     printf("else if (op1 == 2)\n");
+     printf("  {\n");
+     printf("  /* NOTE: This code implements a saturate according to the\n");
+     printf("           figure on page B-115 and not according to the\n");
+     printf("           definition on page B-113 */\n");
+     printf("  signed64 t = ((unsigned64)HI_UW(0) << 32) | (unsigned64)LO_UW(0);\n");
+     printf("  signed64 u = ((unsigned64)HI_UW(2) << 32) | (unsigned64)LO_UW(2);\n");
+     printf("  if ( t > SIGNED64 (0x000000007FFFFFFF) )\n");
+     printf("    GPR_SD(destreg,0) = SIGNED64 (0x000000007FFFFFFF);\n");
+     printf("  else if ( t < - SIGNED64 (0x0000000080000000) )\n");
+     printf("    GPR_SD(destreg,0) = - SIGNED64 (0x0000000080000000);\n");
+     printf("  else\n");
+     printf("    GPR_SD(destreg,0) = t;\n");
+     printf("  if ( u > SIGNED64 (0x000000007FFFFFFF) )\n");
+     printf("    GPR_SD(destreg,1) = SIGNED64 (0x000000007FFFFFFF);\n");
+     printf("  else if ( u < - SIGNED64 (0x0000000080000000) )\n");
+     printf("    GPR_SD(destreg,1) = - SIGNED64 (0x0000000080000000);\n");
+     printf("  else\n");
+     printf("    GPR_SD(destreg,1) = u;\n");
+     printf("  }\n");
+     printf("else if (op1 == 3)\n");
+     printf("  {\n");
+     printf("  GPR_UH(destreg,0) = LO_UH(0);\n");
+     printf("  GPR_UH(destreg,1) = LO_UH(2);\n");
+     printf("  GPR_UH(destreg,2) = HI_UH(0);\n");
+     printf("  GPR_UH(destreg,3) = HI_UH(2);\n");
+     printf("  GPR_UH(destreg,4) = LO_UH(4);\n");
+     printf("  GPR_UH(destreg,5) = LO_UH(6);\n");
+     printf("  GPR_UH(destreg,6) = HI_UH(4);\n");
+     printf("  GPR_UH(destreg,7) = HI_UH(6);\n");
+     printf("  }\n");
+     printf("else if (op1 == 4)\n");
+     printf("  {\n");
+     printf("  if (LO_SW(0) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,0) = 0x7FFF;\n");
+     printf("  else if (LO_SW(0) < -0x8000)\n");
+     printf("    GPR_UH(destreg,0) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,0) = LO_UH(0);\n");
+
+     printf("  if (LO_SW(1) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,1) = 0x7FFF;\n");
+     printf("  else if (LO_SW(1) < -0x8000)\n");
+     printf("    GPR_UH(destreg,1) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,1) = LO_UH(2);\n");
+
+     printf("  if (HI_SW(0) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,2) = 0x7FFF;\n");
+     printf("  else if (HI_SW(0) < -0x8000)\n");
+     printf("    GPR_UH(destreg,2) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,2) = HI_UH(0);\n");
+
+     printf("  if (HI_SW(1) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,3) = 0x7FFF;\n");
+     printf("  else if (HI_SW(1) < -0x8000)\n");
+     printf("    GPR_UH(destreg,3) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,3) = HI_UH(2);\n");
+
+     printf("  if (LO_SW(2) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,4) = 0x7FFF;\n");
+     printf("  else if (LO_SW(2) < -0x8000)\n");
+     printf("    GPR_UH(destreg,4) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,4) = LO_UH(4);\n");
+
+     printf("  if (LO_SW(3) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,5) = 0x7FFF;\n");
+     printf("  else if (LO_SW(3) < -0x8000)\n");
+     printf("    GPR_UH(destreg,5) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,5) = LO_UH(6);\n");
+
+     printf("  if (HI_SW(2) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,6) = 0x7FFF;\n");
+     printf("  else if (HI_SW(2) < -0x8000)\n");
+     printf("    GPR_UH(destreg,6) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,6) = HI_UH(4);\n");
+
+     printf("  if (HI_SW(3) > 0x7FFF)\n");
+     printf("    GPR_UH(destreg,7) = 0x7FFF;\n");
+     printf("  else if (HI_SW(3) < -0x8000)\n");
+     printf("    GPR_UH(destreg,7) = 0x8000;\n");
+     printf("  else\n");
+     printf("    GPR_UH(destreg,7) = HI_UH(6);\n");
+
+     printf("  }\n");
+     break;
+
+    case PLZCW:
+      printf("unsigned long value;\n");
+      printf("int test;\n");
+      printf("int count;\n");
+      printf("int i;\n");
+
+      printf("value = RS_UW(0);\n");
+      printf("count = 0;\n");
+      printf("test = !!(value & (1 << 31));\n");
+      printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
+      printf("  count++;\n");
+      printf("GPR_UW(destreg,0) = count;\n");
+
+      printf("value = RS_UW(1);\n");
+      printf("count = 0;\n");
+      printf("test = !!(value & (1 << 31));\n");
+      printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
+      printf("  count++;\n");
+      printf("GPR_UW(destreg,1) = count;\n");
+      break;
+
+    case PEXT5:
+      printf("int i;\n");
+      printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
+      printf("  {\n");
+      printf("  unsigned32 x = RT_UW(i);\n");
+      printf("  GPR_UW(destreg,i) = ((x & (1  << 15)) << (31 - 15))  \n");
+      printf("                    | ((x & (31 << 10)) << (19 - 10))  \n");
+      printf("                    | ((x & (31 << 5))  << (11 - 5))   \n");
+      printf("                    | ((x & (31 << 0))  << (3  - 0));  \n");
+      printf("  }\n");
+      break;
+
+    case PPAC5:
+      printf("int i;\n");
+      printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
+      printf("  {\n");
+      printf("  unsigned32 x = RT_UW(i);\n");
+      printf("  GPR_UW(destreg,i) = ((x & (1  << 31)) >> (31 - 15))  \n");
+      printf("                    | ((x & (31 << 19)) >> (19 - 10))  \n");
+      printf("                    | ((x & (31 << 11)) >> (11 - 5))   \n");
+      printf("                    | ((x & (31 <<  3)) >> (3  - 0));  \n");
+      printf("  }\n");
+      break;
+/* end-sanitize-r5900 */
+
+    case NYI:
+     fprintf(stderr,"Warning: Unimplemented opcode: %s\n",insn->name) ;
+
+     printf("SignalException(ReservedInstruction,instruction);\n");
+     break;
+
+    default:
+     fprintf(stderr,"Unrecognised opcode type %d\n",insn->type) ;
+     exit(6) ;
+   }
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* The command-line feature controls are presented in a similar style
+   to those offered by GCC, in the aim of providing a consistent
+   interface to the user. */
+typedef enum {
+  T_NONE,  /* no argument - mask and value fields control "feature" definition */
+  T_NUM,   /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
+  T_STRING /* string argument - optionally prcededed by '=' */
+} mactypes;
+
+struct {
+  char *name;
+  mactypes type;
+  unsigned int mask;
+  unsigned int value;
+  char *desc;
+} machine_options[] = {
+  {"ips",         T_NUM,   MASK_ISA,0,"\tSelect MIPS ISA version"},
+  {"cpu",         T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
+  {"gp64",        T_NONE,  FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
+  {"gp32",        T_NONE,  FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
+  {"no-fp",       T_NONE,  FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
+  {"single-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
+  {"double-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
+  {0,             T_NONE,  0,0}
+};
+
+/* The following architecture identies are those accepted by the "-mcpu" option: */
+struct architectures {
+ const char *name;    /* ASCII string identifier for command-line, no white-space allowed */
+ unsigned int idflag; /* or-ed into "isa" value */
+};
+
+static const struct architectures available_architectures[] = {
+  {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
+  {"3900",ARCH_R3900},   /* Toshiba R3900 (TX39) */
+  /* start-sanitize-tx49 */
+  {"4900",ARCH_R4900},   /* Toshiba R4900 (TX49) */
+  /* end-sanitize-tx49  */
+  /* start-sanitize-tx19 */
+  {"1900",ARCH_R3900},   /* Toshiba R1900 (TX19) */
+  /* end-sanitize-tx19  */
+  /* start-sanitize-r5900 */
+  {"5900",ARCH_R5900},
+  /* end-sanitize-r5900 */
+  {0,     0}            /* terminator */
+};
+
+/*---------------------------------------------------------------------------*/
+
+static void
+usage(name)
+     char *name;
+{
+ int loop;
+
+ fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
+
+ fprintf(stderr,"\
+The output of this program is a block of 'C' code designed to be\n\
+included into the main simulation control loop of a device specific\n\
+simulator.\n");
+
+ fprintf(stderr,"\nOptions:\n");
+ fprintf(stderr," -h --help\t\tProvide this help text\n");
+ fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
+ fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
+
+ for (loop = 0; (machine_options[loop].name != 0); loop++) {
+   fprintf(stderr," -m%s",machine_options[loop].name);
+   switch (machine_options[loop].type) {
+     case T_NUM :
+       fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
+     case T_NONE :
+       break;
+
+     case T_STRING :
+       fprintf(stderr,"=name");
+       break;
+
+     default :
+       fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",name,machine_options[loop].type);
+       exit(1);
+   }
+   fprintf(stderr,"%s\n",machine_options[loop].desc);
+ }
+
+ fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
+ for (loop = 0; (available_architectures[loop].name != 0); loop++)
+   fprintf(stderr,"%s ",available_architectures[loop].name);
+ fprintf(stderr,"\n\n");
+
+ fprintf(stderr,"\
+The \"trace\" and \"warnings\" options do not define the output stream.\n\
+They only inform the code that includes the constructed engine to provide\n\
+the required features.\n\n\
+The \"-mips0\" option forces the construction of a simulator supporting\n\
+the highest available MIPS ISA supported.\n");
+
+ return;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int
+main(argc,argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  char *progname = argv[0];
+  unsigned int doarch = DEF_ISA;
+  unsigned int features = 0; /* default state */
+
+  if (DEF_FP)
+   features |= FEATURE_HASFPU;
+  if (!DEF_PROC64)
+   features |= FEATURE_PROC32;
+  if (DEF_FPSINGLE)
+   features |= FEATURE_FPSINGLE;
+
+  if (features & FEATURE_PROC32)
+   features &= ~FEATURE_GP64;
+  else
+   features |= FEATURE_GP64;
+
+  while (1) {
+    int option_index = 0;
+    static struct option cmdline[] = {
+      {"fast",    0,0,'f'},
+      {"help",    0,0,'h'},
+      {"warnings",0,0,'w'},
+      {"igen",    0,0,'i'},
+      {0,         0,0,0}
+    };
+   
+    c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
+    if (c == -1)
+     break ; /* out of the while loop */
+
+    switch (c) {
+      case 'h' : /* help */
+       usage(progname);
+       exit(0);
+
+      case 'f' : /* fast */
+       features |= FEATURE_FAST;
+       break;
+
+      case 'i' : /* igen formatted output */
+       features |= FEATURE_IGEN;
+       break;
+
+      case 'w' : /* warnings */
+       features |= FEATURE_WARNINGS;
+       /* TODO: Future extension: Allow better control over the warnings generated:
+        disable warnings                -wnone                                  ~FEATURE_WARNINGS
+        all possible warnings           -wall                                   FEATURE_WARNINGS
+       pipeline stall occuring         -wstall                                 FEATURE_WARN_STALL
+       LO/HI corruption                -wlo or -whi or -wlohi or -whilo        FEATURE_WARN_HILO
+        write to zero                   -wzero                                  FEATURE_WARN_ZERO       actually performed in external code - though we should set a manifest
+        bad r31 use                     -wr31                                   FEATURE_WARN_R31
+        undefined results               -wresult                                FEATURE_WARN_RESULT
+       */
+       break;
+
+      case 'm' : /* machine options */
+       {
+         int loop;
+
+         for (loop = 0; (machine_options[loop].name != 0); loop++)
+          if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
+            char *loptarg = (optarg + strlen(machine_options[loop].name));
+            switch (machine_options[loop].type) {
+              case T_NONE :
+               if (*loptarg) {
+                 fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
+                 exit(1);
+               }
+               features &= ~(machine_options[loop].mask);
+               features |= machine_options[loop].value;
+               break;
+
+              case T_NUM :
+               if (*loptarg && *loptarg == '=')
+                loptarg++;
+
+               if (strcmp(machine_options[loop].name,"ips") == 0) {
+                 unsigned int num;
+
+                 if (!*loptarg) {
+                   fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
+                   exit(1);
+                 }
+
+                 num = my_strtoul(loptarg,&loptarg,10);
+
+                 if ((num == ULONG_MAX) && (errno = ERANGE)) {
+                   fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
+                   exit(1);
+                 }
+
+                 if (*loptarg) {
+                   fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
+                   exit(1);
+                 }
+
+                 if (num > MASK_ISA) {
+                   fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
+                   exit(1);
+                 }
+
+                 doarch = ((doarch & ~MASK_ISA) | num);
+                 if ((num == 0) || (num > 2)) {
+                   if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
+                    fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
+                   features |= FEATURE_GP64;
+                   features &= ~FEATURE_PROC32;
+                 } else {
+                   if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
+                    fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
+                   features &= ~FEATURE_GP64;
+                   features |= FEATURE_PROC32;
+                 }
+               } else {
+                 fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
+                 exit(1);
+               }
+               break;
+
+              case T_STRING :
+               if (*loptarg && *loptarg == '=')
+                loptarg++;
+
+               if (strcmp(machine_options[loop].name,"cpu") == 0) {
+                 int archloop;
+
+                 if (!*loptarg) {
+                   fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
+                   exit(1);
+                 }
+
+                 for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
+                   if ((*loptarg == 'v') || (*loptarg == 'V'))
+                    loptarg++;
+
+                   if ((*loptarg == 'r') || (*loptarg == 'R'))
+                   loptarg++;
+
+                   if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
+                     doarch |= available_architectures[archloop].idflag;
+                     break;
+                   }
+                 }
+
+                 if (available_architectures[archloop].name == 0) {
+                   fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
+                   exit(1);
+                 }
+               } else {
+                 fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
+                 exit(1);
+               }
+               break;
+
+              default :
+               fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
+               exit(1);
+            }
+            break;
+          }
+
+         if (machine_options[loop].name == 0) {
+           fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
+           exit(1);
+         }
+       }
+       break;
+
+      case '?' :
+       /* An error message should already have been displayed */
+       exit(1);
+
+      default :
+       fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
+       exit(1);
+    }
+  }
+
+  if (optind < argc) {
+    fprintf(stderr,"%s: Spurios non-option arguments ",progname);
+    while (optind < argc)
+     fprintf(stderr,"\"%s\" ",argv[optind++]);
+    fprintf(stderr,"\n");
+    exit(1);
+  }
+
+  if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
+   fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
+
+  process_instructions(doarch,features) ;
+  return(0) ;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* We can't assume that the compiler for the build system has strtoul,
+   so we provide our own copy.  */
+
+/*
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static unsigned long
+my_strtoul(nptr, endptr, base)
+       const char *nptr;
+       char **endptr;
+       register int base;
+{
+       register const char *s = nptr;
+       register unsigned long acc;
+       register int c;
+       register unsigned long cutoff;
+       register int neg = 0, any, cutlim;
+
+       /*
+        * See strtol for comments as to the logic used.
+        */
+       do {
+               c = *s++;
+       } while (isspace(c));
+       if (c == '-') {
+               neg = 1;
+               c = *s++;
+       } else if (c == '+')
+               c = *s++;
+       if ((base == 0 || base == 16) &&
+           c == '0' && (*s == 'x' || *s == 'X')) {
+               c = s[1];
+               s += 2;
+               base = 16;
+       }
+       if (base == 0)
+               base = c == '0' ? 8 : 10;
+       cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
+       cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
+       for (acc = 0, any = 0;; c = *s++) {
+               if (isdigit(c))
+                       c -= '0';
+               else if (isalpha(c))
+                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+               else
+                       break;
+               if (c >= base)
+                       break;
+               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+                       any = -1;
+               else {
+                       any = 1;
+                       acc *= base;
+                       acc += c;
+               }
+       }
+       if (any < 0) {
+               acc = ULONG_MAX;
+               errno = ERANGE;
+       } else if (neg)
+               acc = -acc;
+       if (endptr != 0)
+               *endptr = (char *) (any ? s - 1 : nptr);
+       return (acc);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*> EOF gencode.c <*/
diff --git a/sim/txvu/gpuif.c b/sim/txvu/gpuif.c
new file mode 100644 (file)
index 0000000..9787bf4
--- /dev/null
@@ -0,0 +1,55 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "gpuif.h"
+
+int
+gpuif_io_read_buffer(device *me,
+                      void *dest,
+                      int space,
+                      address_word addr,
+                      unsigned nr_bytes,
+                      sim_cpu *processor,
+                      sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+       return nr_bytes;
+}
+
+int
+gpuif_io_write_buffer(device *me,
+                       const void *source,
+                       int space,
+                       address_word addr,
+                       unsigned nr_bytes,
+                       sim_cpu *processor,
+                       sim_cia cia)
+{
+       printf("%s: Write!\n", me->name);
+       return nr_bytes;
+}
+
+device gpuif_device = 
+  {
+    "Gpuif deivce", 
+    &gpuif_io_read_buffer,
+    &gpuif_io_write_buffer 
+  };
+
+void 
+gpuif_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd, NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   GPUIF_REGISTER_WINDOW_START,
+                   GPUIF_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &gpuif_device,
+                   NULL /*buffer*/);
+}
diff --git a/sim/txvu/gpuif.h b/sim/txvu/gpuif.h
new file mode 100644 (file)
index 0000000..d38e1fd
--- /dev/null
@@ -0,0 +1,19 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef GPUIF_H_
+#define GPUIF_H_
+
+#include "sim-main.h"
+
+void gpuif_attach(SIM_DESC sd);
+
+#define GPUIF_REGISTER_WINDOW_START 0x10000700
+
+#define GPUIF_CTRL_ADDR 0x10000700
+
+#define GPUIF_REGISTER_WINDOW_END   0x10000790
+#define GPUIF_REGISTER_WINDOW_SIZE (GPUIF_REGISTER_WINDOW_END - GPUIF_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/txvu/hardware.c b/sim/txvu/hardware.c
new file mode 100644 (file)
index 0000000..2e87c18
--- /dev/null
@@ -0,0 +1,24 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "gpuif.h"
+#include "dma.h"
+#include "pke0.h"
+#include "pke1.h"
+#include "vu0.h"
+#include "vu1.h"
+
+#include "hardware.h"
+
+void 
+register_devices(SIM_DESC sd)
+{
+  /* Attach a bunch of devices... */
+  gpuif_attach(sd);
+  dma_attach(sd);
+  pke0_attach(sd);
+  vu0_attach(sd);
+  vu1_attach(sd);
+  pke1_attach(sd);
+}
diff --git a/sim/txvu/hardware.h b/sim/txvu/hardware.h
new file mode 100644 (file)
index 0000000..b70231b
--- /dev/null
@@ -0,0 +1,12 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef _HARDWARE_H_
+#define _HARDWARE_H_
+
+#include "sim-main.h"
+
+void create_devices(SIM_DESC sd);
+
+#endif
diff --git a/sim/txvu/interp.c b/sim/txvu/interp.c
new file mode 100644 (file)
index 0000000..52fba47
--- /dev/null
@@ -0,0 +1,3457 @@
+/*> interp.c <*/
+/* Simulator for the MIPS architecture.
+
+   This file is part of the MIPS sim
+
+               THIS SOFTWARE IS NOT COPYRIGHTED
+
+   Cygnus offers the following for use in the public domain.  Cygnus
+   makes no warranty with regard to the software or it's performance
+   and the user accepts the software "AS IS" with all faults.
+
+   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
+   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+   $Revision$
+     $Author$
+       $Date$             
+
+NOTEs:
+
+The IDT monitor (found on the VR4300 board), seems to lie about
+register contents. It seems to treat the registers as sign-extended
+32-bit values. This cause *REAL* problems when single-stepping 64-bit
+code on the hardware.
+
+*/
+
+/* The TRACE manifests enable the provision of extra features. If they
+   are not defined then a simpler (quicker) simulator is constructed
+   without the required run-time checks, etc. */
+#if 1 /* 0 to allow user build selection, 1 to force inclusion */
+#define TRACE (1)
+#endif
+
+#include "bfd.h"
+#include "sim-main.h"
+#include "sim-utils.h"
+#include "sim-options.h"
+#include "sim-assert.h"
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <ansidecl.h>
+#include <ctype.h>
+#include <limits.h>
+#include <math.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+#include "getopt.h"
+#include "libiberty.h"
+#include "bfd.h"
+#include "callback.h"   /* GDB simulator callback interface */
+#include "remote-sim.h" /* GDB simulator interface */
+
+#include "sysdep.h"
+
+#ifndef PARAMS
+#define PARAMS(x) 
+#endif
+
+#include "hardware.h"
+
+char* pr_addr PARAMS ((SIM_ADDR addr));
+char* pr_uword64 PARAMS ((uword64 addr));
+
+
+/* Get the simulator engine description, without including the code: */
+#define SIM_MANIFESTS
+#include "oengine.c"
+#undef SIM_MANIFESTS
+
+
+/* The following reserved instruction value is used when a simulator
+   trap is required. NOTE: Care must be taken, since this value may be
+   used in later revisions of the MIPS ISA. */
+#define RSVD_INSTRUCTION           (0x00000005)
+#define RSVD_INSTRUCTION_MASK      (0xFC00003F)
+
+#define RSVD_INSTRUCTION_ARG_SHIFT 6
+#define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
+
+
+/* Bits in the Debug register */
+#define Debug_DBD 0x80000000   /* Debug Branch Delay */
+#define Debug_DM  0x40000000   /* Debug Mode         */
+#define Debug_DBp 0x00000002   /* Debug Breakpoint indicator */
+
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*-- GDB simulator interface ------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+static void ColdReset PARAMS((SIM_DESC sd));
+
+/*---------------------------------------------------------------------------*/
+
+
+
+#define DELAYSLOT()     {\
+                          if (STATE & simDELAYSLOT)\
+                            sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
+                          STATE |= simDELAYSLOT;\
+                        }
+
+#define JALDELAYSLOT() {\
+                         DELAYSLOT ();\
+                         STATE |= simJALDELAYSLOT;\
+                       }
+
+#define NULLIFY()       {\
+                          STATE &= ~simDELAYSLOT;\
+                          STATE |= simSKIPNEXT;\
+                        }
+
+#define CANCELDELAYSLOT() {\
+                            DSSTATE = 0;\
+                            STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
+                          }
+
+#define INDELAYSLOT()  ((STATE & simDELAYSLOT) != 0)
+#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
+
+#define K0BASE  (0x80000000)
+#define K0SIZE  (0x20000000)
+#define K1BASE  (0xA0000000)
+#define K1SIZE  (0x20000000)
+#define MONITOR_BASE (0xBFC00000)
+#define MONITOR_SIZE (1 << 11)
+#define MEM_SIZE (2 << 20)
+
+#if defined(TRACE)
+static char *tracefile = "trace.din"; /* default filename for trace log */
+FILE *tracefh = NULL;
+static void open_trace PARAMS((SIM_DESC sd));
+#endif /* TRACE */
+
+#define OPTION_DINERO_TRACE  200
+#define OPTION_DINERO_FILE   201
+
+static SIM_RC
+mips_option_handler (sd, opt, arg)
+     SIM_DESC sd;
+     int opt;
+     char *arg;
+{
+  switch (opt)
+    {
+    case OPTION_DINERO_TRACE: /* ??? */
+#if defined(TRACE)
+      /* Eventually the simTRACE flag could be treated as a toggle, to
+        allow external control of the program points being traced
+        (i.e. only from main onwards, excluding the run-time setup,
+        etc.). */
+      if (arg == NULL)
+       STATE |= simTRACE;
+      else if (strcmp (arg, "yes") == 0)
+       STATE |= simTRACE;
+      else if (strcmp (arg, "no") == 0)
+       STATE &= ~simTRACE;
+      else if (strcmp (arg, "on") == 0)
+       STATE |= simTRACE;
+      else if (strcmp (arg, "off") == 0)
+       STATE &= ~simTRACE;
+      else
+       {
+         fprintf (stderr, "Unreconized dinero-trace option `%s'\n", arg);
+         return SIM_RC_FAIL;
+       }
+      return SIM_RC_OK;
+#else /* !TRACE */
+      fprintf(stderr,"\
+Simulator constructed without dinero tracing support (for performance).\n\
+Re-compile simulator with \"-DTRACE\" to enable this option.\n");
+      return SIM_RC_FAIL;
+#endif /* !TRACE */
+
+    case OPTION_DINERO_FILE:
+#if defined(TRACE)
+      if (optarg != NULL) {
+       char *tmp;
+       tmp = (char *)malloc(strlen(optarg) + 1);
+       if (tmp == NULL)
+         {
+           sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
+           return SIM_RC_FAIL;
+         }
+       else {
+         strcpy(tmp,optarg);
+         tracefile = tmp;
+         sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
+       }
+      }
+#endif /* TRACE */
+      return SIM_RC_OK;
+
+    }
+
+  return SIM_RC_OK;
+}
+
+static const OPTION mips_options[] =
+{
+  { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
+      '\0', "on|off", "Enable dinero tracing",
+      mips_option_handler },
+  { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
+      '\0', "FILE", "Write dinero trace to FILE",
+      mips_option_handler },
+  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
+};
+
+
+int interrupt_pending;
+
+static void
+interrupt_event (SIM_DESC sd, void *data)
+{
+  if (SR & status_IE)
+    {
+      interrupt_pending = 0;
+      SignalExceptionInterrupt ();
+    }
+  else if (!interrupt_pending)
+    sim_events_schedule (sd, 1, interrupt_event, data);
+}
+
+extern device gpuif_device;
+
+/*---------------------------------------------------------------------------*/
+/*-- GDB simulator interface ------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+SIM_DESC
+sim_open (kind, cb, abfd, argv)
+     SIM_OPEN_KIND kind;
+     host_callback *cb;
+     struct _bfd *abfd;
+     char **argv;
+{
+  SIM_DESC sd = sim_state_alloc (kind, cb);
+  sim_cpu *cpu = STATE_CPU (sd, 0);
+
+  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+  /* FIXME: watchpoints code shouldn't need this */
+  STATE_WATCHPOINTS (sd)->pc = &(PC);
+  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
+  STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
+
+  STATE = 0;
+  
+  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+    return 0;
+  sim_add_option_table (sd, mips_options);
+
+  /* Allocate core managed memory */
+
+  /* the monitor  */
+  sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
+  /* For compatibility with the old code - under this (at level one)
+     are the kernel spaces K0 & K1.  Both of these map to a single
+     smaller sub region */
+  sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
+                  K1BASE, K0SIZE,
+                  MEM_SIZE, /* actual size */
+                  K0BASE);
+
+  register_devices(sd);
+
+  /* getopt will print the error message so we just have to exit if this fails.
+     FIXME: Hmmm...  in the case of gdb we need getopt to call
+     print_filtered.  */
+  if (sim_parse_args (sd, argv) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* check for/establish the a reference program image */
+  if (sim_analyze_program (sd,
+                          (STATE_PROG_ARGV (sd) != NULL
+                           ? *STATE_PROG_ARGV (sd)
+                           : NULL),
+                          abfd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* Configure/verify the target byte order and other runtime
+     configuration options */
+  if (sim_config (sd) != SIM_RC_OK)
+    {
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  if (sim_post_argv_init (sd) != SIM_RC_OK)
+    {
+      /* Uninstall the modules to avoid memory leaks,
+        file descriptor leaks, etc.  */
+      sim_module_uninstall (sd);
+      return 0;
+    }
+
+  /* verify assumptions the simulator made about the host type system.
+     This macro does not return if there is a problem */
+  SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
+  SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
+
+#if defined(HASFPU)
+  /* Check that the host FPU conforms to IEEE 754-1985 for the SINGLE
+     and DOUBLE binary formats. This is a bit nasty, requiring that we
+     trust the explicit manifests held in the source: */
+  /* TODO: We need to cope with the simulated target and the host not
+     having the same endianness. This will require the high and low
+     words of a (double) to be swapped when converting between the
+     host and the simulated target. */
+  {
+    union {
+      unsigned int i[2];
+      double d;
+      float f[2];
+    } s;
+
+    s.d = (double)523.2939453125;
+
+    if ((s.i[0] == 0 && (s.f[1] != (float)4.01102924346923828125
+                        || s.i[1] != 0x40805A5A))
+       || (s.i[1] == 0 && (s.f[0] != (float)4.01102924346923828125
+                           || s.i[0] != 0x40805A5A)))
+      {
+       fprintf(stderr,"The host executing the simulator does not seem to have IEEE 754-1985 std FP\n");
+       return 0;
+      }
+  }
+#endif /* HASFPU */
+
+  /* This is NASTY, in that we are assuming the size of specific
+     registers: */
+  {
+    int rn;
+    for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++) {
+      if (rn < 32)
+       cpu->register_widths[rn] = GPRLEN;
+      else if ((rn >= FGRIDX) && (rn < (FGRIDX + 32)))
+       cpu->register_widths[rn] = GPRLEN;
+      else if ((rn >= 33) && (rn <= 37))
+       cpu->register_widths[rn] = GPRLEN;
+      else if ((rn == SRIDX) || (rn == FCR0IDX) || (rn == FCR31IDX) || ((rn >= 72) && (rn <= 89)))
+       cpu->register_widths[rn] = 32;
+      else
+       cpu->register_widths[rn] = 0;
+    }
+    /* start-sanitize-r5900 */
+
+    /* set the 5900 "upper" registers to 64 bits */
+    for( rn = LAST_EMBED_REGNUM+1; rn < NUM_REGS; rn++)
+      cpu->register_widths[rn] = 64;      
+    /* end-sanitize-r5900 */
+  }
+
+#if defined(TRACE)
+  if (STATE & simTRACE)
+    open_trace(sd);
+#endif /* TRACE */
+
+  /* Write the monitor trap address handlers into the monitor (eeprom)
+     address space.  This can only be done once the target endianness
+     has been determined. */
+  {
+    unsigned loop;
+    /* Entry into the IDT monitor is via fixed address vectors, and
+       not using machine instructions. To avoid clashing with use of
+       the MIPS TRAP system, we place our own (simulator specific)
+       "undefined" instructions into the relevant vector slots. */
+    for (loop = 0; (loop < MONITOR_SIZE); loop += 4)
+      {
+       address_word vaddr = (MONITOR_BASE + loop);
+       unsigned32 insn = (RSVD_INSTRUCTION | (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK) << RSVD_INSTRUCTION_ARG_SHIFT));
+       H2T (insn);
+       sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
+      }
+    /* The PMON monitor uses the same address space, but rather than
+       branching into it the address of a routine is loaded. We can
+       cheat for the moment, and direct the PMON routine to IDT style
+       instructions within the monitor space. This relies on the IDT
+       monitor not using the locations from 0xBFC00500 onwards as its
+       entry points.*/
+    for (loop = 0; (loop < 24); loop++)
+      {
+        address_word vaddr = (MONITOR_BASE + 0x500 + (loop * 4));
+        unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
+        switch (loop)
+          {
+            case 0: /* read */
+              value = 7;
+              break;
+            case 1: /* write */
+              value = 8;
+              break;
+            case 2: /* open */
+              value = 6;
+              break;
+            case 3: /* close */
+              value = 10;
+              break;
+            case 5: /* printf */
+              value = ((0x500 - 16) / 8); /* not an IDT reason code */
+              break;
+            case 8: /* cliexit */
+              value = 17;
+              break;
+            case 11: /* flush_cache */
+              value = 28;
+              break;
+          }
+       /* FIXME - should monitor_base be SIM_ADDR?? */
+        value = ((unsigned int)MONITOR_BASE + (value * 8));
+       H2T (value);
+       sim_write (sd, vaddr, (char *)&value, sizeof (value));
+
+       /* The LSI MiniRISC PMON has its vectors at 0x200, not 0x500.  */
+       vaddr -= 0x300;
+       sim_write (sd, vaddr, (char *)&value, sizeof (value));
+      }
+  }
+
+  return sd;
+}
+
+#if defined(TRACE)
+static void
+open_trace(sd)
+     SIM_DESC sd;
+{
+  tracefh = fopen(tracefile,"wb+");
+  if (tracefh == NULL)
+    {
+      sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
+      tracefh = stderr;
+  }
+}
+#endif /* TRACE */
+
+void
+sim_close (sd, quitting)
+     SIM_DESC sd;
+     int quitting;
+{
+#ifdef DEBUG
+  printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
+#endif
+
+  /* "quitting" is non-zero if we cannot hang on errors */
+
+  /* Ensure that any resources allocated through the callback
+     mechanism are released: */
+  sim_io_shutdown (sd);
+
+#if defined(TRACE)
+  if (tracefh != NULL && tracefh != stderr)
+   fclose(tracefh);
+  tracefh = NULL;
+  STATE &= ~simTRACE;
+#endif /* TRACE */
+
+  return;
+}
+
+
+int
+sim_write (sd,addr,buffer,size)
+     SIM_DESC sd;
+     SIM_ADDR addr;
+     unsigned char *buffer;
+     int size;
+{
+  int index;
+
+  /* Return the number of bytes written, or zero if error. */
+#ifdef DEBUG
+  sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
+#endif
+
+  /* We use raw read and write routines, since we do not want to count
+     the GDB memory accesses in our statistics gathering. */
+
+  for (index = 0; index < size; index++)
+    {
+      address_word vaddr = (address_word)addr + index;
+      address_word paddr;
+      int cca;
+      if (!address_translation (sd, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
+       break;
+      if (sim_core_write_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1)
+       break;
+    }
+
+  return(index);
+}
+
+int
+sim_read (sd,addr,buffer,size)
+     SIM_DESC sd;
+     SIM_ADDR addr;
+     unsigned char *buffer;
+     int size;
+{
+  int index;
+
+  /* Return the number of bytes read, or zero if error. */
+#ifdef DEBUG
+  sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
+#endif /* DEBUG */
+
+  for (index = 0; (index < size); index++)
+    {
+      address_word vaddr = (address_word)addr + index;
+      address_word paddr;
+      int cca;
+      if (!address_translation (sd, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
+       break;
+      if (sim_core_read_buffer (sd, NULL, sim_core_read_map, buffer + index, paddr, 1) != 1)
+       break;
+    }
+
+  return(index);
+}
+
+void
+sim_store_register (sd,rn,memory)
+     SIM_DESC sd;
+     int rn;
+     unsigned char *memory;
+{
+  sim_cpu *cpu = STATE_CPU (sd, 0);
+  /* NOTE: gdb (the client) stores registers in target byte order
+     while the simulator uses host byte order */
+#ifdef DEBUG
+  sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
+#endif /* DEBUG */
+
+  /* Unfortunately this suffers from the same problem as the register
+     numbering one. We need to know what the width of each logical
+     register number is for the architecture being simulated. */
+
+  if (cpu->register_widths[rn] == 0)
+    sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
+  /* start-sanitize-r5900 */
+  else if (rn == REGISTER_SA)
+    SA = T2H_8(*(uword64*)memory);
+  else if (rn > LAST_EMBED_REGNUM)
+    cpu->registers1[rn - LAST_EMBED_REGNUM - 1] = T2H_8(*(uword64*)memory);
+  /* end-sanitize-r5900 */
+  else if (cpu->register_widths[rn] == 32)
+    cpu->registers[rn] = T2H_4 (*(unsigned int*)memory);
+  else
+    cpu->registers[rn] = T2H_8 (*(uword64*)memory);
+
+  return;
+}
+
+void
+sim_fetch_register (sd,rn,memory)
+     SIM_DESC sd;
+     int rn;
+     unsigned char *memory;
+{
+  sim_cpu *cpu = STATE_CPU (sd, 0);
+  /* NOTE: gdb (the client) stores registers in target byte order
+     while the simulator uses host byte order */
+#ifdef DEBUG
+  sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
+#endif /* DEBUG */
+
+  if (cpu->register_widths[rn] == 0)
+    sim_io_eprintf(sd,"Invalid register width for %d (register fetch ignored)\n",rn);
+  /* start-sanitize-r5900 */
+  else if (rn == REGISTER_SA)
+    *((uword64 *)memory) = H2T_8(SA);
+  else if (rn > LAST_EMBED_REGNUM)
+    *((uword64 *)memory) = H2T_8(cpu->registers1[rn - LAST_EMBED_REGNUM - 1]);
+  /* end-sanitize-r5900 */
+  else if (cpu->register_widths[rn] == 32)
+    *((unsigned int *)memory) = H2T_4 ((unsigned int)(cpu->registers[rn] & 0xFFFFFFFF));
+  else /* 64bit register */
+    *((uword64 *)memory) = H2T_8 (cpu->registers[rn]);
+
+  return;
+}
+
+
+void
+sim_info (sd,verbose)
+     SIM_DESC sd;
+     int verbose;
+{
+  /* Accessed from the GDB "info files" command: */
+  if (STATE_VERBOSE_P (sd) || verbose)
+    {
+      
+      sim_io_printf (sd, "MIPS %d-bit %s endian simulator\n",
+                    (PROCESSOR_64BIT ? 64 : 32),
+                    (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? "Big" : "Little"));
+      
+#if !defined(FASTSIM)
+      /* It would be a useful feature, if when performing multi-cycle
+        simulations (rather than single-stepping) we keep the start and
+        end times of the execution, so that we can give a performance
+        figure for the simulator. */
+#endif /* !FASTSIM */
+      sim_io_printf (sd, "Number of execution cycles = %ld\n",
+                    (long) sim_events_time (sd));
+      
+      /* print information pertaining to MIPS ISA and architecture being simulated */
+      /* things that may be interesting */
+      /* instructions executed - if available */
+      /* cycles executed - if available */
+      /* pipeline stalls - if available */
+      /* virtual time taken */
+      /* profiling size */
+      /* profiling frequency */
+      /* profile minpc */
+      /* profile maxpc */
+    }
+  profile_print (sd, STATE_VERBOSE_P (sd), NULL, NULL);
+}
+
+
+SIM_RC
+sim_create_inferior (sd, abfd, argv,env)
+     SIM_DESC sd;
+     struct _bfd *abfd;
+     char **argv;
+     char **env;
+{
+
+#ifdef DEBUG
+  printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
+        pr_addr(PC));
+#endif /* DEBUG */
+
+  ColdReset(sd);
+
+  if (abfd != NULL)
+    /* override PC value set by ColdReset () */
+    PC = (unsigned64) bfd_get_start_address (abfd);
+
+#if 0 /* def DEBUG */
+  if (argv || env)
+    {
+      /* We should really place the argv slot values into the argument
+        registers, and onto the stack as required. However, this
+        assumes that we have a stack defined, which is not
+        necessarily true at the moment. */
+      char **cptr;
+      sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
+      for (cptr = argv; (cptr && *cptr); cptr++)
+       printf("DBG: arg \"%s\"\n",*cptr);
+    }
+#endif /* DEBUG */
+
+  return SIM_RC_OK;
+}
+
+void
+sim_do_command (sd,cmd)
+     SIM_DESC sd;
+     char *cmd;
+{
+  if (sim_args_command (sd, cmd) != SIM_RC_OK)
+    sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
+                  cmd);
+}
+
+/*---------------------------------------------------------------------------*/
+/*-- Private simulator support interface ------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+/* Read a null terminated string from memory, return in a buffer */
+static char *
+fetch_str (sd, addr)
+     SIM_DESC sd;
+     address_word addr;
+{
+  char *buf;
+  int nr = 0;
+  char null;
+  while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
+    nr++;
+  buf = NZALLOC (char, nr + 1);
+  sim_read (sd, addr, buf, nr);
+  return buf;
+}
+
+/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
+static void
+sim_monitor(sd,cia,reason)
+     SIM_DESC sd;
+     address_word cia;
+     unsigned int reason;
+{
+#ifdef DEBUG
+  printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
+#endif /* DEBUG */
+
+  /* The IDT monitor actually allows two instructions per vector
+     slot. However, the simulator currently causes a trap on each
+     individual instruction. We cheat, and lose the bottom bit. */
+  reason >>= 1;
+
+  /* The following callback functions are available, however the
+     monitor we are simulating does not make use of them: get_errno,
+     isatty, lseek, rename, system, time and unlink */
+  switch (reason)
+    {
+
+    case 6: /* int open(char *path,int flags) */
+      {
+       char *path = fetch_str (sd, A0);
+       V0 = sim_io_open (sd, path, (int)A1);
+       zfree (path);
+       break;
+      }
+
+    case 7: /* int read(int file,char *ptr,int len) */
+      {
+       int fd = A0;
+       int nr = A2;
+       char *buf = zalloc (nr);
+       V0 = sim_io_read (sd, fd, buf, nr);
+       sim_write (sd, A1, buf, nr);
+       zfree (buf);
+      }
+      break;
+
+    case 8: /* int write(int file,char *ptr,int len) */
+      {
+       int fd = A0;
+       int nr = A2;
+       char *buf = zalloc (nr);
+       sim_read (sd, A1, buf, nr);
+       V0 = sim_io_write (sd, fd, buf, nr);
+       zfree (buf);
+       break;
+      }
+
+    case 10: /* int close(int file) */
+      {
+       V0 = sim_io_close (sd, (int)A0);
+       break;
+      }
+
+    case 2:  /* Densan monitor: char inbyte(int waitflag) */
+      {
+       if (A0 == 0)    /* waitflag == NOWAIT */
+         V0 = (ut_reg)-1;
+      }
+     /* Drop through to case 11 */
+
+    case 11: /* char inbyte(void) */
+      {
+        char tmp;
+        if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
+         {
+           sim_io_error(sd,"Invalid return from character read");
+           V0 = (ut_reg)-1;
+         }
+        else
+         V0 = (ut_reg)tmp;
+       break;
+      }
+
+    case 3:  /* Densan monitor: void co(char chr) */
+    case 12: /* void outbyte(char chr) : write a byte to "stdout" */
+      {
+        char tmp = (char)(A0 & 0xFF);
+        sim_io_write_stdout (sd, &tmp, sizeof(char));
+       break;
+      }
+
+    case 17: /* void _exit() */
+      {
+       sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
+       sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA, sim_exited,
+                        (unsigned int)(A0 & 0xFFFFFFFF));
+       break;
+      }
+
+    case 28 : /* PMON flush_cache */
+      break;
+
+    case 55: /* void get_mem_info(unsigned int *ptr) */
+      /* in:  A0 = pointer to three word memory location */
+      /* out: [A0 + 0] = size */
+      /*      [A0 + 4] = instruction cache size */
+      /*      [A0 + 8] = data cache size */
+      {
+       address_word value = MEM_SIZE /* FIXME STATE_MEM_SIZE (sd) */;
+       H2T (value);
+       sim_write (sd, A0, (char *)&value, sizeof (value));
+       /* sim_io_eprintf (sd, "sim: get_mem_info() depreciated\n"); */
+       break;
+      }
+    
+    case 158 : /* PMON printf */
+      /* in:  A0 = pointer to format string */
+      /*      A1 = optional argument 1 */
+      /*      A2 = optional argument 2 */
+      /*      A3 = optional argument 3 */
+      /* out: void */
+      /* The following is based on the PMON printf source */
+      {
+       address_word s = A0;
+       char c;
+       signed_word *ap = &A1; /* 1st argument */
+        /* This isn't the quickest way, since we call the host print
+           routine for every character almost. But it does avoid
+           having to allocate and manage a temporary string buffer. */
+       /* TODO: Include check that we only use three arguments (A1,
+           A2 and A3) */
+       while (sim_read (sd, s++, &c, 1) && c != '\0')
+         {
+            if (c == '%')
+             {
+               char tmp[40];
+               enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
+               int width = 0, trunc = 0, haddot = 0, longlong = 0;
+               while (sim_read (sd, s++, &c, 1) && c != '\0')
+                 {
+                   if (strchr ("dobxXulscefg%", s))
+                     break;
+                   else if (c == '-')
+                     fmt = FMT_LJUST;
+                   else if (c == '0')
+                     fmt = FMT_RJUST0;
+                   else if (c == '~')
+                     fmt = FMT_CENTER;
+                   else if (c == '*')
+                     {
+                       if (haddot)
+                         trunc = (int)*ap++;
+                       else
+                         width = (int)*ap++;
+                     }
+                   else if (c >= '1' && c <= '9')
+                     {
+                       address_word t = s;
+                       unsigned int n;
+                       while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
+                         tmp[s - t] = c;
+                       tmp[s - t] = '\0';
+                       n = (unsigned int)strtol(tmp,NULL,10);
+                       if (haddot)
+                         trunc = n;
+                       else
+                         width = n;
+                       s--;
+                     }
+                   else if (c == '.')
+                     haddot = 1;
+                 }
+               switch (c)
+                 {
+                 case '%':
+                   sim_io_printf (sd, "%%");
+                   break;
+                 case 's':
+                   if ((int)*ap != 0)
+                     {
+                       address_word p = *ap++;
+                       char ch;
+                       while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
+                         sim_io_printf(sd, "%c", ch);
+                     }
+                   else
+                     sim_io_printf(sd,"(null)");
+                   break;
+                 case 'c':
+                   sim_io_printf (sd, "%c", (int)*ap++);
+                   break;
+                 default:
+                   if (c == 'l')
+                     {
+                       sim_read (sd, s++, &c, 1);
+                       if (c == 'l')
+                         {
+                           longlong = 1;
+                           sim_read (sd, s++, &c, 1);
+                         }
+                     }
+                   if (strchr ("dobxXu", c))
+                     {
+                       word64 lv = (word64) *ap++;
+                       if (c == 'b')
+                         sim_io_printf(sd,"<binary not supported>");
+                       else
+                         {
+                           sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
+                           if (longlong)
+                             sim_io_printf(sd, tmp, lv);
+                           else
+                             sim_io_printf(sd, tmp, (int)lv);
+                         }
+                     }
+                   else if (strchr ("eEfgG", c))
+                     {
+                       double dbl = *(double*)(ap++);
+                       sprintf (tmp, "%%%d.%d%c", width, trunc, c);
+                       sim_io_printf (sd, tmp, dbl);
+                       trunc = 0;
+                     }
+                 }
+             }
+           else
+             sim_io_printf(sd, "%c", c);
+         }
+       break;
+      }
+
+    default:
+      sim_io_error (sd, "TODO: sim_monitor(%d) : PC = 0x%s\n",
+                   reason, pr_addr(cia));
+      break;
+  }
+  return;
+}
+
+/* Store a word into memory.  */
+
+static void
+store_word (sd, cia, vaddr, val)
+     SIM_DESC sd;
+     address_word cia;
+     uword64 vaddr;
+     t_reg val;
+{
+  address_word paddr;
+  int uncached;
+
+  if ((vaddr & 3) != 0)
+    SignalExceptionAddressStore ();
+  else
+    {
+      if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                             isTARGET, isREAL))
+       {
+         const uword64 mask = 7;
+         uword64 memval;
+         unsigned int byte;
+
+         paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
+         byte = (vaddr & mask) ^ (BigEndianCPU << 2);
+         memval = ((uword64) val) << (8 * byte);
+         StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
+                      isREAL);
+       }
+    }
+}
+
+/* Load a word from memory.  */
+
+static t_reg
+load_word (sd, cia, vaddr)
+     SIM_DESC sd;
+     address_word cia;
+     uword64 vaddr;
+{
+  if ((vaddr & 3) != 0)
+    SignalExceptionAddressLoad ();
+  else
+    {
+      address_word paddr;
+      int uncached;
+
+      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                             isTARGET, isREAL))
+       {
+         const uword64 mask = 0x7;
+         const unsigned int reverse = ReverseEndian ? 1 : 0;
+         const unsigned int bigend = BigEndianCPU ? 1 : 0;
+         uword64 memval;
+         unsigned int byte;
+
+         paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
+         LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
+                              isDATA, isREAL);
+         byte = (vaddr & mask) ^ (bigend << 2);
+         return SIGNEXTEND (((memval >> (8 * byte)) & 0xffffffff), 32);
+       }
+    }
+
+  return 0;
+}
+
+/* Simulate the mips16 entry and exit pseudo-instructions.  These
+   would normally be handled by the reserved instruction exception
+   code, but for ease of simulation we just handle them directly.  */
+
+static void
+mips16_entry (sd,insn)
+     SIM_DESC sd;
+     unsigned int insn;
+{
+  int aregs, sregs, rreg;
+
+#ifdef DEBUG
+  printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
+#endif /* DEBUG */
+
+  aregs = (insn & 0x700) >> 8;
+  sregs = (insn & 0x0c0) >> 6;
+  rreg =  (insn & 0x020) >> 5;
+
+  /* This should be checked by the caller.  */
+  if (sregs == 3)
+    abort ();
+
+  if (aregs < 5)
+    {
+      int i;
+      t_reg tsp;
+
+      /* This is the entry pseudo-instruction.  */
+
+      for (i = 0; i < aregs; i++)
+       store_word ((uword64) (SP + 4 * i), GPR[i + 4]);
+
+      tsp = SP;
+      SP -= 32;
+
+      if (rreg)
+       {
+         tsp -= 4;
+         store_word ((uword64) tsp, RA);
+       }
+
+      for (i = 0; i < sregs; i++)
+       {
+         tsp -= 4;
+         store_word ((uword64) tsp, GPR[16 + i]);
+       }
+    }
+  else
+    {
+      int i;
+      t_reg tsp;
+
+      /* This is the exit pseudo-instruction.  */
+
+      tsp = SP + 32;
+
+      if (rreg)
+       {
+         tsp -= 4;
+         RA = load_word ((uword64) tsp);
+       }
+
+      for (i = 0; i < sregs; i++)
+       {
+         tsp -= 4;
+         GPR[i + 16] = load_word ((uword64) tsp);
+       }
+
+      SP += 32;
+
+#if defined(HASFPU)
+      if (aregs == 5)
+       {
+         FGR[0] = WORD64LO (GPR[4]);
+         FPR_STATE[0] = fmt_uninterpreted;
+       }
+      else if (aregs == 6)
+       {
+         FGR[0] = WORD64LO (GPR[5]);
+         FGR[1] = WORD64LO (GPR[4]);
+         FPR_STATE[0] = fmt_uninterpreted;
+         FPR_STATE[1] = fmt_uninterpreted;
+       }
+#endif /* defined(HASFPU) */
+
+      PC = RA;
+    }
+}
+
+/*-- trace support ----------------------------------------------------------*/
+
+/* The TRACE support is provided (if required) in the memory accessing
+   routines. Since we are also providing the architecture specific
+   features, the architecture simulation code can also deal with
+   notifying the TRACE world of cache flushes, etc. Similarly we do
+   not need to provide profiling support in the simulator engine,
+   since we can sample in the instruction fetch control loop. By
+   defining the TRACE manifest, we add tracing as a run-time
+   option. */
+
+#if defined(TRACE)
+/* Tracing by default produces "din" format (as required by
+   dineroIII). Each line of such a trace file *MUST* have a din label
+   and address field. The rest of the line is ignored, so comments can
+   be included if desired. The first field is the label which must be
+   one of the following values:
+
+       0       read data
+        1       write data
+        2       instruction fetch
+        3       escape record (treated as unknown access type)
+        4       escape record (causes cache flush)
+
+   The address field is a 32bit (lower-case) hexadecimal address
+   value. The address should *NOT* be preceded by "0x".
+
+   The size of the memory transfer is not important when dealing with
+   cache lines (as long as no more than a cache line can be
+   transferred in a single operation :-), however more information
+   could be given following the dineroIII requirement to allow more
+   complete memory and cache simulators to provide better
+   results. i.e. the University of Pisa has a cache simulator that can
+   also take bus size and speed as (variable) inputs to calculate
+   complete system performance (a much more useful ability when trying
+   to construct an end product, rather than a processor). They
+   currently have an ARM version of their tool called ChARM. */
+
+
+void
+dotrace (SIM_DESC sd,FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
+{
+  if (STATE & simTRACE) {
+    va_list ap;
+    fprintf(tracefh,"%d %s ; width %d ; ", 
+               type,
+               pr_addr(address),
+               width);
+    va_start(ap,comment);
+    vfprintf(tracefh,comment,ap);
+    va_end(ap);
+    fprintf(tracefh,"\n");
+  }
+  /* NOTE: Since the "din" format will only accept 32bit addresses, and
+     we may be generating 64bit ones, we should put the hi-32bits of the
+     address into the comment field. */
+
+  /* TODO: Provide a buffer for the trace lines. We can then avoid
+     performing writes until the buffer is filled, or the file is
+     being closed. */
+
+  /* NOTE: We could consider adding a comment field to the "din" file
+     produced using type 3 markers (unknown access). This would then
+     allow information about the program that the "din" is for, and
+     the MIPs world that was being simulated, to be placed into the
+     trace file. */
+
+  return;
+}
+#endif /* TRACE */
+
+/*---------------------------------------------------------------------------*/
+/*-- simulator engine -------------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+static void
+ColdReset (sd)
+     SIM_DESC sd;
+{
+  /* RESET: Fixed PC address: */
+  PC = UNSIGNED64 (0xFFFFFFFFBFC00000);
+  /* The reset vector address is in the unmapped, uncached memory space. */
+
+  SR &= ~(status_SR | status_TS | status_RP);
+  SR |= (status_ERL | status_BEV);
+
+  /* Cheat and allow access to the complete register set immediately */
+  if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
+      && WITH_TARGET_WORD_BITSIZE == 64)
+    SR |= status_FR; /* 64bit registers */
+
+  /* Ensure that any instructions with pending register updates are
+     cleared: */
+  {
+    int loop;
+    for (loop = 0; (loop < PSLOTS); loop++)
+     PENDING_SLOT_REG[loop] = (LAST_EMBED_REGNUM + 1);
+    PENDING_IN = PENDING_OUT = PENDING_TOTAL = 0;
+  }
+
+  /* Initialise the FPU registers to the unknown state */
+  if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
+    {
+      int rn;
+      for (rn = 0; (rn < 32); rn++)
+       FPR_STATE[rn] = fmt_uninterpreted;
+    }
+
+  return;
+}
+
+/* Description from page A-22 of the "MIPS IV Instruction Set" manual
+   (revision 3.1) */
+/* Translate a virtual address to a physical address and cache
+   coherence algorithm describing the mechanism used to resolve the
+   memory reference. Given the virtual address vAddr, and whether the
+   reference is to Instructions ot Data (IorD), find the corresponding
+   physical address (pAddr) and the cache coherence algorithm (CCA)
+   used to resolve the reference. If the virtual address is in one of
+   the unmapped address spaces the physical address and the CCA are
+   determined directly by the virtual address. If the virtual address
+   is in one of the mapped address spaces then the TLB is used to
+   determine the physical address and access type; if the required
+   translation is not present in the TLB or the desired access is not
+   permitted the function fails and an exception is taken.
+
+   NOTE: Normally (RAW == 0), when address translation fails, this
+   function raises an exception and does not return. */
+
+int
+address_translation(sd,cia,vAddr,IorD,LorS,pAddr,CCA,raw)
+     SIM_DESC sd;
+     address_word cia;
+     address_word vAddr;
+     int IorD;
+     int LorS;
+     address_word *pAddr;
+     int *CCA;
+     int raw;
+{
+  int res = -1; /* TRUE : Assume good return */
+
+#ifdef DEBUG
+  sim_io_printf(sd,"AddressTranslation(0x%s,%s,%s,...);\n",pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "iSTORE" : "isLOAD"));
+#endif
+
+  /* Check that the address is valid for this memory model */
+
+  /* For a simple (flat) memory model, we simply pass virtual
+     addressess through (mostly) unchanged. */
+  vAddr &= 0xFFFFFFFF;
+
+  *pAddr = vAddr; /* default for isTARGET */
+  *CCA = Uncached; /* not used for isHOST */
+
+  return(res);
+}
+
+/* Description from page A-23 of the "MIPS IV Instruction Set" manual
+   (revision 3.1) */
+/* Prefetch data from memory. Prefetch is an advisory instruction for
+   which an implementation specific action is taken. The action taken
+   may increase performance, but must not change the meaning of the
+   program, or alter architecturally-visible state. */
+
+void 
+prefetch(sd,cia,CCA,pAddr,vAddr,DATA,hint)
+     SIM_DESC sd;
+     address_word cia;
+     int CCA;
+     address_word pAddr;
+     address_word vAddr;
+     int DATA;
+     int hint;
+{
+#ifdef DEBUG
+  sim_io_printf(sd,"Prefetch(%d,0x%s,0x%s,%d,%d);\n",CCA,pr_addr(pAddr),pr_addr(vAddr),DATA,hint);
+#endif /* DEBUG */
+
+  /* For our simple memory model we do nothing */
+  return;
+}
+
+/* Description from page A-22 of the "MIPS IV Instruction Set" manual
+   (revision 3.1) */
+/* Load a value from memory. Use the cache and main memory as
+   specified in the Cache Coherence Algorithm (CCA) and the sort of
+   access (IorD) to find the contents of AccessLength memory bytes
+   starting at physical location pAddr. The data is returned in the
+   fixed width naturally-aligned memory element (MemElem). The
+   low-order two (or three) bits of the address and the AccessLength
+   indicate which of the bytes within MemElem needs to be given to the
+   processor. If the memory access type of the reference is uncached
+   then only the referenced bytes are read from memory and valid
+   within the memory element. If the access type is cached, and the
+   data is not present in cache, an implementation specific size and
+   alignment block of memory is read and loaded into the cache to
+   satisfy a load reference. At a minimum, the block is the entire
+   memory element. */
+void
+load_memory(sd,cia,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
+     SIM_DESC sd;
+     address_word cia;
+     uword64* memvalp;
+     uword64* memval1p;
+     int CCA;
+     int AccessLength;
+     address_word pAddr;
+     address_word vAddr;
+     int IorD;
+{
+  uword64 value = 0;
+  uword64 value1 = 0;
+
+#ifdef DEBUG
+  sim_io_printf(sd,"DBG: LoadMemory(%p,%p,%d,%d,0x%s,0x%s,%s)\n",memvalp,memval1p,CCA,AccessLength,pr_addr(pAddr),pr_addr(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"));
+#endif /* DEBUG */
+
+#if defined(WARN_MEM)
+  if (CCA != uncached)
+    sim_io_eprintf(sd,"LoadMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
+#endif /* WARN_MEM */
+
+  /* If instruction fetch then we need to check that the two lo-order
+     bits are zero, otherwise raise a InstructionFetch exception: */
+  if ((IorD == isINSTRUCTION)
+      && ((pAddr & 0x3) != 0)
+      && (((pAddr & 0x1) != 0) || ((vAddr & 0x1) == 0)))
+    SignalExceptionInstructionFetch ();
+
+  if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
+    {
+      /* In reality this should be a Bus Error */
+      sim_io_error (sd, "AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",
+                   AccessLength,
+                   (LOADDRMASK + 1) << 2,
+                   pr_addr (pAddr));
+    }
+
+#if defined(TRACE)
+  dotrace(sd,tracefh,((IorD == isDATA) ? 0 : 2),(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"load%s",((IorD == isDATA) ? "" : " instruction"));
+#endif /* TRACE */
+  
+  /* Read the specified number of bytes from memory.  Adjust for
+     host/target byte ordering/ Align the least significant byte
+     read. */
+
+  switch (AccessLength)
+    {
+    case AccessLength_QUADWORD :
+      {
+       unsigned_16 val = sim_core_read_aligned_16 (STATE_CPU (sd, 0), NULL_CIA,
+                                                   sim_core_read_map, pAddr);
+       value1 = VH8_16 (val);
+       value = VL8_16 (val);
+       break;
+      }
+    case AccessLength_DOUBLEWORD :
+      value = sim_core_read_aligned_8 (STATE_CPU (sd, 0), NULL_CIA,
+                                      sim_core_read_map, pAddr);
+      break;
+    case AccessLength_SEPTIBYTE :
+      value = sim_core_read_misaligned_7 (STATE_CPU (sd, 0), NULL_CIA,
+                                         sim_core_read_map, pAddr);
+    case AccessLength_SEXTIBYTE :
+      value = sim_core_read_misaligned_6 (STATE_CPU (sd, 0), NULL_CIA,
+                                         sim_core_read_map, pAddr);
+    case AccessLength_QUINTIBYTE :
+      value = sim_core_read_misaligned_5 (STATE_CPU (sd, 0), NULL_CIA,
+                                         sim_core_read_map, pAddr);
+    case AccessLength_WORD :
+      value = sim_core_read_aligned_4 (STATE_CPU (sd, 0), NULL_CIA,
+                                      sim_core_read_map, pAddr);
+      break;
+    case AccessLength_TRIPLEBYTE :
+      value = sim_core_read_misaligned_3 (STATE_CPU (sd, 0), NULL_CIA,
+                                         sim_core_read_map, pAddr);
+    case AccessLength_HALFWORD :
+      value = sim_core_read_aligned_2 (STATE_CPU (sd, 0), NULL_CIA,
+                                      sim_core_read_map, pAddr);
+      break;
+    case AccessLength_BYTE :
+      value = sim_core_read_aligned_1 (STATE_CPU (sd, 0), NULL_CIA,
+                                      sim_core_read_map, pAddr);
+      break;
+    default:
+      abort ();
+    }
+  
+#ifdef DEBUG
+  printf("DBG: LoadMemory() : (offset %d) : value = 0x%s%s\n",
+        (int)(pAddr & LOADDRMASK),pr_uword64(value1),pr_uword64(value));
+#endif /* DEBUG */
+  
+  /* See also store_memory. */
+  if (AccessLength <= AccessLength_DOUBLEWORD)
+    {
+      if (BigEndianMem)
+       /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
+          shifted to the most significant byte position.  */
+       value <<= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
+      else
+       /* For little endian target, byte (pAddr&LOADDRMASK == 0)
+          is already in the correct postition. */
+       value <<= ((pAddr & LOADDRMASK) * 8);
+    }
+  
+#ifdef DEBUG
+  printf("DBG: LoadMemory() : shifted value = 0x%s%s\n",
+        pr_uword64(value1),pr_uword64(value));
+#endif /* DEBUG */
+  
+  *memvalp = value;
+  if (memval1p) *memval1p = value1;
+}
+
+
+/* Description from page A-23 of the "MIPS IV Instruction Set" manual
+   (revision 3.1) */
+/* Store a value to memory. The specified data is stored into the
+   physical location pAddr using the memory hierarchy (data caches and
+   main memory) as specified by the Cache Coherence Algorithm
+   (CCA). The MemElem contains the data for an aligned, fixed-width
+   memory element (word for 32-bit processors, doubleword for 64-bit
+   processors), though only the bytes that will actually be stored to
+   memory need to be valid. The low-order two (or three) bits of pAddr
+   and the AccessLength field indicates which of the bytes within the
+   MemElem data should actually be stored; only these bytes in memory
+   will be changed. */
+
+void
+store_memory(sd,cia,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
+     SIM_DESC sd;
+     address_word cia;
+     int CCA;
+     int AccessLength;
+     uword64 MemElem;
+     uword64 MemElem1;   /* High order 64 bits */
+     address_word pAddr;
+     address_word vAddr;
+{
+#ifdef DEBUG
+  sim_io_printf(sd,"DBG: StoreMemory(%d,%d,0x%s,0x%s,0x%s,0x%s)\n",CCA,AccessLength,pr_uword64(MemElem),pr_uword64(MemElem1),pr_addr(pAddr),pr_addr(vAddr));
+#endif /* DEBUG */
+  
+#if defined(WARN_MEM)
+  if (CCA != uncached)
+    sim_io_eprintf(sd,"StoreMemory CCA (%d) is not uncached (currently all accesses treated as cached)\n",CCA);
+#endif /* WARN_MEM */
+  
+  if (((pAddr & LOADDRMASK) + AccessLength) > LOADDRMASK)
+    sim_io_error(sd,"AccessLength of %d would extend over %dbit aligned boundary for physical address 0x%s\n",AccessLength,(LOADDRMASK + 1)<<2,pr_addr(pAddr));
+  
+#if defined(TRACE)
+  dotrace(sd,tracefh,1,(unsigned int)(pAddr&0xFFFFFFFF),(AccessLength + 1),"store");
+#endif /* TRACE */
+  
+#ifdef DEBUG
+  printf("DBG: StoreMemory: offset = %d MemElem = 0x%s%s\n",(unsigned int)(pAddr & LOADDRMASK),pr_uword64(MemElem1),pr_uword64(MemElem));
+#endif /* DEBUG */
+  
+  /* See also load_memory */
+  if (AccessLength <= AccessLength_DOUBLEWORD)
+    {
+      if (BigEndianMem)
+       /* for big endian target, byte (pAddr&LOADDRMASK == 0) is
+          shifted to the most significant byte position.  */
+       MemElem >>= (((7 - (pAddr & LOADDRMASK)) - AccessLength) * 8);
+      else
+       /* For little endian target, byte (pAddr&LOADDRMASK == 0)
+          is already in the correct postition. */
+       MemElem >>= ((pAddr & LOADDRMASK) * 8);
+    }
+  
+#ifdef DEBUG
+  printf("DBG: StoreMemory: shift = %d MemElem = 0x%s%s\n",shift,pr_uword64(MemElem1),pr_uword64(MemElem));
+#endif /* DEBUG */
+  
+  switch (AccessLength)
+    {
+    case AccessLength_QUADWORD :
+      {
+       unsigned_16 val = U16_8 (MemElem1, MemElem);
+       sim_core_write_aligned_16 (STATE_CPU (sd, 0), NULL_CIA,
+                                  sim_core_write_map, pAddr, val);
+       break;
+      }
+    case AccessLength_DOUBLEWORD :
+      sim_core_write_aligned_8 (STATE_CPU (sd, 0), NULL_CIA,
+                               sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_SEPTIBYTE :
+      sim_core_write_misaligned_7 (STATE_CPU (sd, 0), NULL_CIA,
+                                  sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_SEXTIBYTE :
+      sim_core_write_misaligned_6 (STATE_CPU (sd, 0), NULL_CIA,
+                                  sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_QUINTIBYTE :
+      sim_core_write_misaligned_5 (STATE_CPU (sd, 0), NULL_CIA,
+                                  sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_WORD :
+      sim_core_write_aligned_4 (STATE_CPU (sd, 0), NULL_CIA,
+                               sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_TRIPLEBYTE :
+      sim_core_write_misaligned_3 (STATE_CPU (sd, 0), NULL_CIA,
+                                  sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_HALFWORD :
+      sim_core_write_aligned_2 (STATE_CPU (sd, 0), NULL_CIA,
+                               sim_core_write_map, pAddr, MemElem);
+      break;
+    case AccessLength_BYTE :
+      sim_core_write_aligned_1 (STATE_CPU (sd, 0), NULL_CIA,
+                               sim_core_write_map, pAddr, MemElem);
+      break;
+    default:
+      abort ();
+    }  
+  
+  return;
+}
+
+
+unsigned32
+ifetch32 (SIM_DESC sd,
+         address_word cia,
+         address_word vaddr)
+{
+  /* Copy the action of the LW instruction */
+  address_word reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
+  address_word bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
+  unsigned64 value;
+  address_word paddr;
+  unsigned32 instruction;
+  unsigned byte;
+  int cca;
+  AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &cca, isTARGET, isREAL);
+  paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
+  LoadMemory (&value, NULL, cca, AccessLength_WORD, paddr, vaddr, isINSTRUCTION, isREAL);
+  byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
+  instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
+  return instruction;
+}
+
+
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* Order loads and stores to synchronise shared memory. Perform the
+   action necessary to make the effects of groups of synchronizable
+   loads and stores indicated by stype occur in the same order for all
+   processors. */
+void
+sync_operation(sd,cia,stype)
+     SIM_DESC sd;
+     address_word cia;
+     int stype;
+{
+#ifdef DEBUG
+  sim_io_printf(sd,"SyncOperation(%d) : TODO\n",stype);
+#endif /* DEBUG */
+  return;
+}
+
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* Signal an exception condition. This will result in an exception
+   that aborts the instruction. The instruction operation pseudocode
+   will never see a return from this function call. */
+
+void
+signal_exception (SIM_DESC sd,
+                 address_word cia,
+                 int exception,...)
+{
+  int vector;
+
+#ifdef DEBUG
+  sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
+#endif /* DEBUG */
+
+  /* Ensure that any active atomic read/modify/write operation will fail: */
+  LLBIT = 0;
+
+  switch (exception) {
+    /* TODO: For testing purposes I have been ignoring TRAPs. In
+       reality we should either simulate them, or allow the user to
+       ignore them at run-time.
+       Same for SYSCALL */
+    case Trap :
+     sim_io_eprintf(sd,"Ignoring instruction TRAP (PC 0x%s)\n",pr_addr(cia));
+     break;
+
+    case SystemCall :
+      {
+        va_list ap;
+        unsigned int instruction;
+        unsigned int code;
+
+        va_start(ap,exception);
+        instruction = va_arg(ap,unsigned int);
+        va_end(ap);
+
+        code = (instruction >> 6) & 0xFFFFF;
+        
+        sim_io_eprintf(sd,"Ignoring instruction `syscall %d' (PC 0x%s)\n",
+                    code, pr_addr(cia));
+      }
+     break;
+
+    case DebugBreakPoint :
+      if (! (Debug & Debug_DM))
+        {
+          if (INDELAYSLOT())
+            {
+              CANCELDELAYSLOT();
+              
+              Debug |= Debug_DBD;  /* signaled from within in delay slot */
+              DEPC = cia - 4;      /* reference the branch instruction */
+            }
+          else
+            {
+              Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
+              DEPC = cia;
+            }
+        
+          Debug |= Debug_DM;            /* in debugging mode */
+          Debug |= Debug_DBp;           /* raising a DBp exception */
+          PC = 0xBFC00200;
+          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, NULL_CIA);
+        }
+      break;
+
+    case ReservedInstruction :
+     {
+       va_list ap;
+       unsigned int instruction;
+       va_start(ap,exception);
+       instruction = va_arg(ap,unsigned int);
+       va_end(ap);
+       /* Provide simple monitor support using ReservedInstruction
+          exceptions. The following code simulates the fixed vector
+          entry points into the IDT monitor by causing a simulator
+          trap, performing the monitor operation, and returning to
+          the address held in the $ra register (standard PCS return
+          address). This means we only need to pre-load the vector
+          space with suitable instruction values. For systems were
+          actual trap instructions are used, we would not need to
+          perform this magic. */
+       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
+        {
+          sim_monitor(sd, cia, ((instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK) );
+          /* NOTE: This assumes that a branch-and-link style
+             instruction was used to enter the vector (which is the
+             case with the current IDT monitor). */
+          sim_engine_restart (sd, STATE_CPU (sd, 0), NULL, RA);
+        }
+       /* Look for the mips16 entry and exit instructions, and
+          simulate a handler for them.  */
+       else if ((cia & 1) != 0
+               && (instruction & 0xf81f) == 0xe809
+               && (instruction & 0x0c0) != 0x0c0)
+        {
+          mips16_entry (instruction);
+          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
+        }
+       /* else fall through to normal exception processing */
+       sim_io_eprintf(sd,"ReservedInstruction 0x%08X at PC = 0x%s\n",instruction,pr_addr(cia));
+     }
+
+    case BreakPoint:
+#ifdef DEBUG
+      sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
+#endif /* DEBUG */
+      /* Keep a copy of the current A0 in-case this is the program exit
+        breakpoint:  */
+      {
+       va_list ap;
+       unsigned int instruction;
+       va_start(ap,exception);
+       instruction = va_arg(ap,unsigned int);
+       va_end(ap);
+       /* Check for our special terminating BREAK: */
+       if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
+         sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia,
+                          sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+       }
+      }
+      if (STATE & simDELAYSLOT)
+       PC = cia - 4; /* reference the branch instruction */
+      else
+       PC = cia;
+      sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, cia,
+                      sim_stopped, SIM_SIGTRAP);
+
+    default:
+     /* Store exception code into current exception id variable (used
+        by exit code): */
+
+     /* TODO: If not simulating exceptions then stop the simulator
+        execution. At the moment we always stop the simulation. */
+
+     /* See figure 5-17 for an outline of the code below */
+     if (! (SR & status_EXL))
+       {
+        CAUSE = (exception << 2);
+        if (STATE & simDELAYSLOT)
+          {
+            STATE &= ~simDELAYSLOT;
+            CAUSE |= cause_BD;
+            EPC = (cia - 4); /* reference the branch instruction */
+          }
+        else
+          EPC = cia;
+        /* FIXME: TLB et.al. */
+        vector = 0x180;
+       }
+     else
+       {
+        CAUSE = (exception << 2);
+        vector = 0x180;
+       }
+     SR |= status_EXL;
+     /* Store exception code into current exception id variable (used
+        by exit code): */
+     if (SR & status_BEV)
+       PC = (signed)0xBFC00200 + 0x180;
+     else
+       PC = (signed)0x80000000 + 0x180;
+
+     switch ((CAUSE >> 2) & 0x1F)
+       {
+       case Interrupt:
+        /* Interrupts arrive during event processing, no need to
+            restart */
+        return;
+        
+       case TLBModification:
+       case TLBLoad:
+       case TLBStore:
+       case AddressLoad:
+       case AddressStore:
+       case InstructionFetch:
+       case DataReference:
+        /* The following is so that the simulator will continue from the
+           exception address on breakpoint operations. */
+        PC = EPC;
+        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                         sim_stopped, SIM_SIGBUS);
+
+       case ReservedInstruction:
+       case CoProcessorUnusable:
+        PC = EPC;
+        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                         sim_stopped, SIM_SIGILL);
+
+       case IntegerOverflow:
+       case FPE:
+        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                         sim_stopped, SIM_SIGFPE);
+
+       case Trap:
+       case Watch:
+       case SystemCall:
+        PC = EPC;
+        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                         sim_stopped, SIM_SIGTRAP);
+
+       case BreakPoint:
+        PC = EPC;
+        sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
+                          "FATAL: Should not encounter a breakpoint\n");
+
+       default : /* Unknown internal exception */
+        PC = EPC;
+        sim_engine_halt (sd, STATE_CPU (sd, 0), NULL, NULL_CIA,
+                         sim_stopped, SIM_SIGABRT);
+
+       }
+
+    case SimulatorFault:
+     {
+       va_list ap;
+       char *msg;
+       va_start(ap,exception);
+       msg = va_arg(ap,char *);
+       va_end(ap);
+       sim_engine_abort (sd, STATE_CPU (sd, 0), NULL_CIA,
+                        "FATAL: Simulator error \"%s\"\n",msg);
+     }
+   }
+
+  return;
+}
+
+#if defined(WARN_RESULT)
+/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
+/* This function indicates that the result of the operation is
+   undefined. However, this should not affect the instruction
+   stream. All that is meant to happen is that the destination
+   register is set to an undefined result. To keep the simulator
+   simple, we just don't bother updating the destination register, so
+   the overall result will be undefined. If desired we can stop the
+   simulator by raising a pseudo-exception. */
+#define UndefinedResult() undefined_result (sd,cia)
+static void
+undefined_result(sd,cia)
+     SIM_DESC sd;
+     address_word cia;
+{
+  sim_io_eprintf(sd,"UndefinedResult: PC = 0x%s\n",pr_addr(cia));
+#if 0 /* Disabled for the moment, since it actually happens a lot at the moment. */
+  state |= simSTOP;
+#endif
+  return;
+}
+#endif /* WARN_RESULT */
+
+void
+cache_op(sd,cia,op,pAddr,vAddr,instruction)
+     SIM_DESC sd;
+     address_word cia;
+     int op;
+     address_word pAddr;
+     address_word vAddr;
+     unsigned int instruction;
+{
+#if 1 /* stop warning message being displayed (we should really just remove the code) */
+  static int icache_warning = 1;
+  static int dcache_warning = 1;
+#else
+  static int icache_warning = 0;
+  static int dcache_warning = 0;
+#endif
+
+  /* If CP0 is not useable (User or Supervisor mode) and the CP0
+     enable bit in the Status Register is clear - a coprocessor
+     unusable exception is taken. */
+#if 0
+  sim_io_printf(sd,"TODO: Cache availability checking (PC = 0x%s)\n",pr_addr(cia));
+#endif
+
+  switch (op & 0x3) {
+    case 0: /* instruction cache */
+      switch (op >> 2) {
+        case 0: /* Index Invalidate */
+        case 1: /* Index Load Tag */
+        case 2: /* Index Store Tag */
+        case 4: /* Hit Invalidate */
+        case 5: /* Fill */
+        case 6: /* Hit Writeback */
+          if (!icache_warning)
+            {
+              sim_io_eprintf(sd,"Instruction CACHE operation %d to be coded\n",(op >> 2));
+              icache_warning = 1;
+            }
+          break;
+
+        default:
+          SignalException(ReservedInstruction,instruction);
+          break;
+      }
+      break;
+
+    case 1: /* data cache */
+      switch (op >> 2) {
+        case 0: /* Index Writeback Invalidate */
+        case 1: /* Index Load Tag */
+        case 2: /* Index Store Tag */
+        case 3: /* Create Dirty */
+        case 4: /* Hit Invalidate */
+        case 5: /* Hit Writeback Invalidate */
+        case 6: /* Hit Writeback */ 
+          if (!dcache_warning)
+            {
+              sim_io_eprintf(sd,"Data CACHE operation %d to be coded\n",(op >> 2));
+              dcache_warning = 1;
+            }
+          break;
+
+        default:
+          SignalException(ReservedInstruction,instruction);
+          break;
+      }
+      break;
+
+    default: /* unrecognised cache ID */
+      SignalException(ReservedInstruction,instruction);
+      break;
+  }
+
+  return;
+}
+
+/*-- FPU support routines ---------------------------------------------------*/
+
+#if defined(HASFPU) /* Only needed when building FPU aware simulators */
+
+/* Numbers are held in normalized form. The SINGLE and DOUBLE binary
+   formats conform to ANSI/IEEE Std 754-1985. */
+/* SINGLE precision floating:
+ *    seeeeeeeefffffffffffffffffffffff
+ *      s =  1bit  = sign
+ *      e =  8bits = exponent
+ *      f = 23bits = fraction
+ */
+/* SINGLE precision fixed:
+ *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ *      s =  1bit  = sign
+ *      i = 31bits = integer
+ */
+/* DOUBLE precision floating:
+ *    seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
+ *      s =  1bit  = sign
+ *      e = 11bits = exponent
+ *      f = 52bits = fraction
+ */
+/* DOUBLE precision fixed:
+ *    siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+ *      s =  1bit  = sign
+ *      i = 63bits = integer
+ */
+
+/* Extract sign-bit: */
+#define FP_S_s(v)    (((v) & ((unsigned)1 << 31)) ? 1 : 0)
+#define FP_D_s(v)    (((v) & ((uword64)1 << 63)) ? 1 : 0)
+/* Extract biased exponent: */
+#define FP_S_be(v)   (((v) >> 23) & 0xFF)
+#define FP_D_be(v)   (((v) >> 52) & 0x7FF)
+/* Extract unbiased Exponent: */
+#define FP_S_e(v)    (FP_S_be(v) - 0x7F)
+#define FP_D_e(v)    (FP_D_be(v) - 0x3FF)
+/* Extract complete fraction field: */
+#define FP_S_f(v)    ((v) & ~((unsigned)0x1FF << 23))
+#define FP_D_f(v)    ((v) & ~((uword64)0xFFF << 52))
+/* Extract numbered fraction bit: */
+#define FP_S_fb(b,v) (((v) & (1 << (23 - (b)))) ? 1 : 0)
+#define FP_D_fb(b,v) (((v) & (1 << (52 - (b)))) ? 1 : 0)
+
+/* Explicit QNaN values used when value required: */
+#define FPQNaN_SINGLE   (0x7FBFFFFF)
+#define FPQNaN_WORD     (0x7FFFFFFF)
+#define FPQNaN_DOUBLE   (((uword64)0x7FF7FFFF << 32) | 0xFFFFFFFF)
+#define FPQNaN_LONG     (((uword64)0x7FFFFFFF << 32) | 0xFFFFFFFF)
+
+/* Explicit Infinity values used when required: */
+#define FPINF_SINGLE    (0x7F800000)
+#define FPINF_DOUBLE    (((uword64)0x7FF00000 << 32) | 0x00000000)
+
+#if 1 /* def DEBUG */
+#define RMMODE(v) (((v) == FP_RM_NEAREST) ? "Round" : (((v) == FP_RM_TOZERO) ? "Trunc" : (((v) == FP_RM_TOPINF) ? "Ceil" : "Floor")))
+#define DOFMT(v)  (((v) == fmt_single) ? "single" : (((v) == fmt_double) ? "double" : (((v) == fmt_word) ? "word" : (((v) == fmt_long) ? "long" : (((v) == fmt_unknown) ? "<unknown>" : (((v) == fmt_uninterpreted) ? "<uninterpreted>" : "<format error>"))))))
+#endif /* DEBUG */
+
+uword64
+value_fpr(sd,cia,fpr,fmt)
+     SIM_DESC sd;
+     address_word cia;
+     int fpr;
+     FP_formats fmt;
+{
+  uword64 value = 0;
+  int err = 0;
+
+  /* Treat unused register values, as fixed-point 64bit values: */
+  if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))
+#if 1
+   /* If request to read data as "uninterpreted", then use the current
+      encoding: */
+   fmt = FPR_STATE[fpr];
+#else
+   fmt = fmt_long;
+#endif
+
+  /* For values not yet accessed, set to the desired format: */
+  if (FPR_STATE[fpr] == fmt_uninterpreted) {
+    FPR_STATE[fpr] = fmt;
+#ifdef DEBUG
+    printf("DBG: Register %d was fmt_uninterpreted. Now %s\n",fpr,DOFMT(fmt));
+#endif /* DEBUG */
+  }
+  if (fmt != FPR_STATE[fpr]) {
+    sim_io_eprintf(sd,"FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",fpr,DOFMT(FPR_STATE[fpr]),DOFMT(fmt),pr_addr(cia));
+    FPR_STATE[fpr] = fmt_unknown;
+  }
+
+  if (FPR_STATE[fpr] == fmt_unknown) {
+   /* Set QNaN value: */
+   switch (fmt) {
+    case fmt_single:
+     value = FPQNaN_SINGLE;
+     break;
+
+    case fmt_double:
+     value = FPQNaN_DOUBLE;
+     break;
+
+    case fmt_word:
+     value = FPQNaN_WORD;
+     break;
+
+    case fmt_long:
+     value = FPQNaN_LONG;
+     break;
+
+    default:
+     err = -1;
+     break;
+   }
+  } else if (SizeFGR() == 64) {
+    switch (fmt) {
+     case fmt_single:
+     case fmt_word:
+      value = (FGR[fpr] & 0xFFFFFFFF);
+      break;
+
+     case fmt_uninterpreted:
+     case fmt_double:
+     case fmt_long:
+      value = FGR[fpr];
+      break;
+
+     default :
+      err = -1;
+      break;
+    }
+  } else {
+    switch (fmt) {
+     case fmt_single:
+     case fmt_word:
+      value = (FGR[fpr] & 0xFFFFFFFF);
+      break;
+
+     case fmt_uninterpreted:
+     case fmt_double:
+     case fmt_long:
+      if ((fpr & 1) == 0) { /* even registers only */
+       value = ((((uword64)FGR[fpr+1]) << 32) | (FGR[fpr] & 0xFFFFFFFF));
+      } else {
+       SignalException(ReservedInstruction,0);
+      }
+      break;
+
+     default :
+      err = -1;
+      break;
+    }
+  }
+
+  if (err)
+   SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR()");
+
+#ifdef DEBUG
+  printf("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
+#endif /* DEBUG */
+
+  return(value);
+}
+
+void
+store_fpr(sd,cia,fpr,fmt,value)
+     SIM_DESC sd;
+     address_word cia;
+     int fpr;
+     FP_formats fmt;
+     uword64 value;
+{
+  int err = 0;
+
+#ifdef DEBUG
+  printf("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR() = %d\n",fpr,DOFMT(fmt),pr_addr(value),pr_addr(cia),SizeFGR());
+#endif /* DEBUG */
+
+  if (SizeFGR() == 64) {
+    switch (fmt) {
+      case fmt_uninterpreted_32:
+       fmt = fmt_uninterpreted;
+      case fmt_single :
+      case fmt_word :
+       FGR[fpr] = (((uword64)0xDEADC0DE << 32) | (value & 0xFFFFFFFF));
+       FPR_STATE[fpr] = fmt;
+       break;
+
+      case fmt_uninterpreted_64:
+       fmt = fmt_uninterpreted;
+      case fmt_uninterpreted:
+      case fmt_double :
+      case fmt_long :
+       FGR[fpr] = value;
+       FPR_STATE[fpr] = fmt;
+       break;
+
+      default :
+       FPR_STATE[fpr] = fmt_unknown;
+       err = -1;
+       break;
+    }
+  } else {
+    switch (fmt) {
+      case fmt_uninterpreted_32:
+       fmt = fmt_uninterpreted;
+      case fmt_single :
+      case fmt_word :
+       FGR[fpr] = (value & 0xFFFFFFFF);
+       FPR_STATE[fpr] = fmt;
+       break;
+
+      case fmt_uninterpreted_64:
+       fmt = fmt_uninterpreted;
+      case fmt_uninterpreted:
+      case fmt_double :
+      case fmt_long :
+       if ((fpr & 1) == 0) { /* even register number only */
+         FGR[fpr+1] = (value >> 32);
+         FGR[fpr] = (value & 0xFFFFFFFF);
+         FPR_STATE[fpr + 1] = fmt;
+         FPR_STATE[fpr] = fmt;
+       } else {
+         FPR_STATE[fpr] = fmt_unknown;
+         FPR_STATE[fpr + 1] = fmt_unknown;
+         SignalException(ReservedInstruction,0);
+       }
+       break;
+
+      default :
+       FPR_STATE[fpr] = fmt_unknown;
+       err = -1;
+       break;
+    }
+  }
+#if defined(WARN_RESULT)
+  else
+    UndefinedResult();
+#endif /* WARN_RESULT */
+
+  if (err)
+   SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR()");
+
+#ifdef DEBUG
+  printf("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",fpr,pr_addr(FGR[fpr]),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return;
+}
+
+int
+NaN(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  int boolean = 0;
+  switch (fmt) {
+   case fmt_single:
+   case fmt_word:
+    {
+      sim_fpu wop;
+      sim_fpu_32to (&wop, op);
+      boolean = sim_fpu_is_nan (&wop);
+      break;
+    }
+   case fmt_double:
+   case fmt_long:
+    {
+      sim_fpu wop;
+      sim_fpu_64to (&wop, op);
+      boolean = sim_fpu_is_nan (&wop);
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+printf("DBG: NaN: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(boolean);
+}
+
+int
+Infinity(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  int boolean = 0;
+
+#ifdef DEBUG
+  printf("DBG: Infinity: format %s 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop;
+      sim_fpu_32to (&wop, op);
+      boolean = sim_fpu_is_infinity (&wop);
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop;
+      sim_fpu_64to (&wop, op);
+      boolean = sim_fpu_is_infinity (&wop);
+      break;
+    }
+   default:
+    printf("DBG: TODO: unrecognised format (%s) for Infinity check\n",DOFMT(fmt));
+    break;
+  }
+
+#ifdef DEBUG
+  printf("DBG: Infinity: returning %d for 0x%s (format = %s)\n",boolean,pr_addr(op),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(boolean);
+}
+
+int
+Less(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  int boolean = 0;
+
+  /* Argument checking already performed by the FPCOMPARE code */
+
+#ifdef DEBUG
+  printf("DBG: Less: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      boolean = sim_fpu_is_lt (&wop1, &wop2);
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      boolean = sim_fpu_is_lt (&wop1, &wop2);
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Less: returning %d (format = %s)\n",boolean,DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(boolean);
+}
+
+int
+Equal(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  int boolean = 0;
+
+  /* Argument checking already performed by the FPCOMPARE code */
+
+#ifdef DEBUG
+  printf("DBG: Equal: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      boolean = sim_fpu_is_eq (&wop1, &wop2);
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      boolean = sim_fpu_is_eq (&wop1, &wop2);
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Equal: returning %d (format = %s)\n",boolean,DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(boolean);
+}
+
+uword64
+AbsoluteValue(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: AbsoluteValue: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop;
+      unsigned32 ans;
+      sim_fpu_32to (&wop, op);
+      sim_fpu_abs (&wop, &wop);
+      sim_fpu_to32 (&ans, &wop);
+      result = ans;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop;
+      unsigned64 ans;
+      sim_fpu_64to (&wop, op);
+      sim_fpu_abs (&wop, &wop);
+      sim_fpu_to64 (&ans, &wop);
+      result = ans;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+  return(result);
+}
+
+uword64
+Negate(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Negate: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop;
+      unsigned32 ans;
+      sim_fpu_32to (&wop, op);
+      sim_fpu_neg (&wop, &wop);
+      sim_fpu_to32 (&ans, &wop);
+      result = ans;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop;
+      unsigned64 ans;
+      sim_fpu_64to (&wop, op);
+      sim_fpu_neg (&wop, &wop);
+      sim_fpu_to64 (&ans, &wop);
+      result = ans;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+  return(result);
+}
+
+uword64
+Add(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Add: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      sim_fpu_add (&ans, &wop1, &wop2);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      sim_fpu_add (&ans, &wop1, &wop2);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Add: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64
+Sub(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Sub: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      sim_fpu_sub (&ans, &wop1, &wop2);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+    }
+    break;
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      sim_fpu_sub (&ans, &wop1, &wop2);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+    }
+    break;
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Sub: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64
+Multiply(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Multiply: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      sim_fpu_mul (&ans, &wop1, &wop2);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      sim_fpu_mul (&ans, &wop1, &wop2);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Multiply: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64
+Divide(op1,op2,fmt)
+     uword64 op1;
+     uword64 op2;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Divide: %s: op1 = 0x%s : op2 = 0x%s\n",DOFMT(fmt),pr_addr(op1),pr_addr(op2));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop1, op1);
+      sim_fpu_32to (&wop2, op2);
+      sim_fpu_div (&ans, &wop1, &wop2);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop1;
+      sim_fpu wop2;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop1, op1);
+      sim_fpu_64to (&wop2, op2);
+      sim_fpu_div (&ans, &wop1, &wop2);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Divide: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64 UNUSED
+Recip(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: Recip: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop, op);
+      sim_fpu_inv (&ans, &wop);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop, op);
+      sim_fpu_inv (&ans, &wop);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: Recip: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64
+SquareRoot(op,fmt)
+     uword64 op;
+     FP_formats fmt; 
+{
+  uword64 result = 0;
+
+#ifdef DEBUG
+  printf("DBG: SquareRoot: %s: op = 0x%s\n",DOFMT(fmt),pr_addr(op));
+#endif /* DEBUG */
+
+  /* The registers must specify FPRs valid for operands of type
+     "fmt". If they are not valid, the result is undefined. */
+
+  /* The format type should already have been checked: */
+  switch (fmt) {
+   case fmt_single:
+    {
+      sim_fpu wop;
+      sim_fpu ans;
+      unsigned32 res;
+      sim_fpu_32to (&wop, op);
+      sim_fpu_sqrt (&ans, &wop);
+      sim_fpu_to32 (&res, &ans);
+      result = res;
+      break;
+    }
+   case fmt_double:
+    {
+      sim_fpu wop;
+      sim_fpu ans;
+      unsigned64 res;
+      sim_fpu_64to (&wop, op);
+      sim_fpu_sqrt (&ans, &wop);
+      sim_fpu_to64 (&res, &ans);
+      result = res;
+      break;
+    }
+   default:
+    fprintf (stderr, "Bad switch\n");
+    abort ();
+  }
+
+#ifdef DEBUG
+  printf("DBG: SquareRoot: returning 0x%s (format = %s)\n",pr_addr(result),DOFMT(fmt));
+#endif /* DEBUG */
+
+  return(result);
+}
+
+uword64
+convert(sd,cia,rm,op,from,to)
+     SIM_DESC sd;
+     address_word cia;
+     int rm;
+     uword64 op;
+     FP_formats from; 
+     FP_formats to; 
+{
+  sim_fpu wop;
+  sim_fpu_round round;
+  unsigned32 result32;
+  unsigned64 result64;
+
+#ifdef DEBUG
+  printf("DBG: Convert: mode %s : op 0x%s : from %s : to %s : (PC = 0x%s)\n",RMMODE(rm),pr_addr(op),DOFMT(from),DOFMT(to),pr_addr(IPC));
+#endif /* DEBUG */
+
+  switch (rm)
+    {
+    case FP_RM_NEAREST:
+      /* Round result to nearest representable value. When two
+        representable values are equally near, round to the value
+        that has a least significant bit of zero (i.e. is even). */
+      round = sim_fpu_round_near;
+      break;
+    case FP_RM_TOZERO:
+      /* Round result to the value closest to, and not greater in
+        magnitude than, the result. */
+      round = sim_fpu_round_zero;
+      break;
+    case FP_RM_TOPINF:
+      /* Round result to the value closest to, and not less than,
+        the result. */
+      round = sim_fpu_round_up;
+      break;
+      
+    case FP_RM_TOMINF:
+      /* Round result to the value closest to, and not greater than,
+        the result. */
+      round = sim_fpu_round_down;
+      break;
+    default:
+      round = 0;
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+  
+  /* Convert the input to sim_fpu internal format */
+  switch (from)
+    {
+    case fmt_double:
+      sim_fpu_64to (&wop, op);
+      break;
+    case fmt_single:
+      sim_fpu_32to (&wop, op);
+      break;
+    case fmt_word:
+      sim_fpu_i32to (&wop, op, round);
+      break;
+    case fmt_long:
+      sim_fpu_i64to (&wop, op, round);
+      break;
+    default:
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+
+  /* Convert sim_fpu format into the output */
+  /* The value WOP is converted to the destination format, rounding
+     using mode RM. When the destination is a fixed-point format, then
+     a source value of Infinity, NaN or one which would round to an
+     integer outside the fixed point range then an IEEE Invalid
+     Operation condition is raised. */
+  switch (to)
+    {
+    case fmt_single:
+      sim_fpu_round_32 (&wop, round, 0);
+      sim_fpu_to32 (&result32, &wop);
+      result64 = result32;
+      break;
+    case fmt_double:
+      sim_fpu_round_64 (&wop, round, 0);
+      sim_fpu_to64 (&result64, &wop);
+      break;
+    case fmt_word:
+      sim_fpu_to32i (&result32, &wop, round);
+      result64 = result32;
+      break;
+    case fmt_long:
+      sim_fpu_to64i (&result64, &wop, round);
+      break;
+    default:
+      result64 = 0;
+      fprintf (stderr, "Bad switch\n");
+      abort ();
+    }
+#ifdef DEBUG
+  printf("DBG: Convert: returning 0x%s (to format = %s)\n",pr_addr(result64),DOFMT(to));
+#endif /* DEBUG */
+
+  return(result64);
+}
+#endif /* HASFPU */
+
+
+/*-- co-processor support routines ------------------------------------------*/
+
+static int UNUSED
+CoProcPresent(coproc_number)
+     unsigned int coproc_number;
+{
+  /* Return TRUE if simulator provides a model for the given co-processor number */
+  return(0);
+}
+
+void
+cop_lw(sd,cia,coproc_num,coproc_reg,memword)
+     SIM_DESC sd;
+     address_word cia;
+     int coproc_num, coproc_reg;
+     unsigned int memword;
+{
+  switch (coproc_num) {
+#if defined(HASFPU)
+    case 1:
+#ifdef DEBUG
+    printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
+#endif
+     StoreFPR(coproc_reg,fmt_word,(uword64)memword);
+     FPR_STATE[coproc_reg] = fmt_uninterpreted;
+     break;
+#endif /* HASFPU */
+
+    default:
+#if 0 /* this should be controlled by a configuration option */
+     sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
+#endif
+     break;
+  }
+
+  return;
+}
+
+void
+cop_ld(sd,cia,coproc_num,coproc_reg,memword)
+     SIM_DESC sd;
+     address_word cia;
+     int coproc_num, coproc_reg;
+     uword64 memword;
+{
+  switch (coproc_num) {
+#if defined(HASFPU)
+    case 1:
+     StoreFPR(coproc_reg,fmt_uninterpreted,memword);
+     break;
+#endif /* HASFPU */
+
+    default:
+#if 0 /* this message should be controlled by a configuration option */
+     sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
+#endif
+     break;
+  }
+
+  return;
+}
+
+unsigned int
+cop_sw(sd,cia,coproc_num,coproc_reg)
+     SIM_DESC sd;
+     address_word cia;
+     int coproc_num, coproc_reg;
+{
+  unsigned int value = 0;
+
+  switch (coproc_num) {
+#if defined(HASFPU)
+    case 1:
+#if 1
+      {
+        FP_formats hold;
+        hold = FPR_STATE[coproc_reg];
+        FPR_STATE[coproc_reg] = fmt_word;
+        value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted);
+        FPR_STATE[coproc_reg] = hold;
+      }
+#else
+#if 1
+     value = (unsigned int)ValueFPR(coproc_reg,FPR_STATE[coproc_reg]);
+#else
+#ifdef DEBUG
+     printf("DBG: COP_SW: reg in format %s (will be accessing as single)\n",DOFMT(FPR_STATE[coproc_reg])); 
+#endif /* DEBUG */
+     value = (unsigned int)ValueFPR(coproc_reg,fmt_single);
+#endif
+#endif
+     break;
+#endif /* HASFPU */
+
+    default:
+#if 0 /* should be controlled by configuration option */
+     sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
+#endif
+     break;
+  }
+
+  return(value);
+}
+
+uword64
+cop_sd(sd,cia,coproc_num,coproc_reg)
+     SIM_DESC sd;
+     address_word cia;
+     int coproc_num, coproc_reg;
+{
+  uword64 value = 0;
+  switch (coproc_num) {
+#if defined(HASFPU)
+    case 1:
+#if 1
+     value = ValueFPR(coproc_reg,fmt_uninterpreted);
+#else
+#if 1
+     value = ValueFPR(coproc_reg,FPR_STATE[coproc_reg]);
+#else
+#ifdef DEBUG
+     printf("DBG: COP_SD: reg in format %s (will be accessing as double)\n",DOFMT(FPR_STATE[coproc_reg]));
+#endif /* DEBUG */
+     value = ValueFPR(coproc_reg,fmt_double);
+#endif
+#endif
+     break;
+#endif /* HASFPU */
+
+    default:
+#if 0 /* should be controlled by configuration option */
+     sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
+#endif
+     break;
+  }
+
+  return(value);
+}
+
+void
+decode_coproc(sd,cia,instruction)
+     SIM_DESC sd;
+     address_word cia;
+     unsigned int instruction;
+{
+  int coprocnum = ((instruction >> 26) & 3);
+
+  switch (coprocnum)
+    {
+    case 0: /* standard CPU control and cache registers */
+      {
+        int code = ((instruction >> 21) & 0x1F);
+        /* R4000 Users Manual (second edition) lists the following CP0
+           instructions:
+          DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
+          DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
+          MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
+          MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
+          TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
+          TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
+          TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
+          TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
+          CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
+          ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
+          */
+        if (((code == 0x00) || (code == 0x04)) && ((instruction & 0x7FF) == 0))
+         {
+           int rt = ((instruction >> 16) & 0x1F);
+           int rd = ((instruction >> 11) & 0x1F);
+           
+           switch (rd)  /* NOTEs: Standard CP0 registers */
+             {
+               /* 0 = Index               R4000   VR4100  VR4300 */
+               /* 1 = Random              R4000   VR4100  VR4300 */
+               /* 2 = EntryLo0            R4000   VR4100  VR4300 */
+               /* 3 = EntryLo1            R4000   VR4100  VR4300 */
+               /* 4 = Context             R4000   VR4100  VR4300 */
+               /* 5 = PageMask            R4000   VR4100  VR4300 */
+               /* 6 = Wired               R4000   VR4100  VR4300 */
+               /* 8 = BadVAddr            R4000   VR4100  VR4300 */
+               /* 9 = Count               R4000   VR4100  VR4300 */
+               /* 10 = EntryHi            R4000   VR4100  VR4300 */
+               /* 11 = Compare            R4000   VR4100  VR4300 */
+               /* 12 = SR                 R4000   VR4100  VR4300 */
+             case 12:
+               if (code == 0x00)
+                 GPR[rt] = SR;
+               else
+                 SR = GPR[rt];
+               break;
+               /* 13 = Cause              R4000   VR4100  VR4300 */
+             case 13:
+               if (code == 0x00)
+                 GPR[rt] = CAUSE;
+               else
+                 CAUSE = GPR[rt];
+               break;
+               /* 14 = EPC                R4000   VR4100  VR4300 */
+               /* 15 = PRId               R4000   VR4100  VR4300 */
+#ifdef SUBTARGET_R3900
+                /* 16 = Debug */
+              case 16:
+                if (code == 0x00)
+                  GPR[rt] = Debug;
+                else
+                  Debug = GPR[rt];
+                break;
+#else
+               /* 16 = Config             R4000   VR4100  VR4300 */
+              case 16:
+                if (code == 0x00)
+                  GPR[rt] = C0_CONFIG;
+                else
+                  C0_CONFIG = GPR[rt];
+                break;
+#endif
+#ifdef SUBTARGET_R3900
+                /* 17 = Debug */
+              case 17:
+                if (code == 0x00)
+                  GPR[rt] = DEPC;
+                else
+                  DEPC = GPR[rt];
+                break;
+#else
+               /* 17 = LLAddr             R4000   VR4100  VR4300 */
+#endif
+               /* 18 = WatchLo            R4000   VR4100  VR4300 */
+               /* 19 = WatchHi            R4000   VR4100  VR4300 */
+               /* 20 = XContext           R4000   VR4100  VR4300 */
+               /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
+               /* 27 = CacheErr           R4000   VR4100 */
+               /* 28 = TagLo              R4000   VR4100  VR4300 */
+               /* 29 = TagHi              R4000   VR4100  VR4300 */
+               /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
+               GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
+               /* CPR[0,rd] = GPR[rt]; */
+             default:
+               if (code == 0x00)
+                 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored (architecture specific)\n",rt,rd);
+               else
+                 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored (architecture specific)\n",rt,rd);
+             }
+         }
+       else if (code == 0x10 && (instruction & 0x3f) == 0x18)
+         {
+           /* ERET */
+           if (SR & status_ERL)
+             {
+               /* Oops, not yet available */
+               sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
+               PC = EPC;
+               SR &= ~status_ERL;
+             }
+           else
+             {
+               PC = EPC;
+               SR &= ~status_EXL;
+             }
+         }
+        else if (code == 0x10 && (instruction & 0x3f) == 0x10)
+          {
+            /* RFE */
+          }
+        else if (code == 0x10 && (instruction & 0x3f) == 0x1F)
+          {
+            /* DERET */
+            Debug &= ~Debug_DM;
+            DELAYSLOT();
+            DSPC = DEPC;
+          }
+       else
+         sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
+        /* TODO: When executing an ERET or RFE instruction we should
+           clear LLBIT, to ensure that any out-standing atomic
+           read/modify/write sequence fails. */
+      }
+    break;
+    
+    case 2: /* undefined co-processor */
+      sim_io_eprintf(sd,"COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
+      break;
+      
+    case 1: /* should not occur (FPU co-processor) */
+    case 3: /* should not occur (FPU co-processor) */
+      SignalException(ReservedInstruction,instruction);
+      break;
+    }
+  
+  return;
+}
+
+/*-- instruction simulation -------------------------------------------------*/
+
+/* When the IGEN simulator is being built, the function below is be
+   replaced by a generated version.  However, WITH_IGEN == 2 indicates
+   that the fubction below should be compiled but under a different
+   name (to allow backward compatibility) */
+
+#if (WITH_IGEN != 1)
+#if (WITH_IGEN > 1)
+void old_engine_run PARAMS ((SIM_DESC sd, int next_cpu_nr, int siggnal));
+void
+old_engine_run (sd, next_cpu_nr, siggnal)
+#else
+void
+sim_engine_run (sd, next_cpu_nr, siggnal)
+#endif
+     SIM_DESC sd;
+     int next_cpu_nr; /* ignore */
+     int siggnal; /* ignore */
+{
+#if !defined(FASTSIM)
+  unsigned int pipeline_count = 1;
+#endif
+
+#ifdef DEBUG
+  if (STATE_MEMORY (sd) == NULL) {
+    printf("DBG: simulate() entered with no memory\n");
+    exit(1);
+  }
+#endif /* DEBUG */
+
+#if 0 /* Disabled to check that everything works OK */
+  /* The VR4300 seems to sign-extend the PC on its first
+     access. However, this may just be because it is currently
+     configured in 32bit mode. However... */
+  PC = SIGNEXTEND(PC,32);
+#endif
+
+  /* main controlling loop */
+  while (1) {
+    /* vaddr is slowly being replaced with cia - current instruction
+       address */
+    address_word cia = (uword64)PC;
+    address_word vaddr = cia;
+    address_word paddr;
+    int cca;
+    unsigned int instruction;  /* uword64? what's this used for?  FIXME! */
+
+#ifdef DEBUG
+    {
+      printf("DBG: state = 0x%08X :",state);
+      if (state & simHALTEX) printf(" simHALTEX");
+      if (state & simHALTIN) printf(" simHALTIN");
+      printf("\n");
+    }
+#endif /* DEBUG */
+
+    DSSTATE = (STATE & simDELAYSLOT);
+#ifdef DEBUG
+    if (dsstate)
+     sim_io_printf(sd,"DBG: DSPC = 0x%s\n",pr_addr(DSPC));
+#endif /* DEBUG */
+
+    /* Fetch the next instruction from the simulator memory: */
+    if (AddressTranslation(cia,isINSTRUCTION,isLOAD,&paddr,&cca,isTARGET,isREAL)) {
+      if ((vaddr & 1) == 0) {
+       /* Copy the action of the LW instruction */
+       unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 2) : 0);
+       unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 2) : 0);
+       uword64 value;
+       unsigned int byte;
+       paddr = ((paddr & ~LOADDRMASK) | ((paddr & LOADDRMASK) ^ (reverse << 2)));
+       LoadMemory(&value,NULL,cca,AccessLength_WORD,paddr,vaddr,isINSTRUCTION,isREAL);
+       byte = ((vaddr & LOADDRMASK) ^ (bigend << 2));
+       instruction = ((value >> (8 * byte)) & 0xFFFFFFFF);
+      } else {
+       /* Copy the action of the LH instruction */
+       unsigned int reverse = (ReverseEndian ? (LOADDRMASK >> 1) : 0);
+       unsigned int bigend = (BigEndianCPU ? (LOADDRMASK >> 1) : 0);
+       uword64 value;
+       unsigned int byte;
+       paddr = (((paddr & ~ (uword64) 1) & ~LOADDRMASK)
+                | (((paddr & ~ (uword64) 1) & LOADDRMASK) ^ (reverse << 1)));
+       LoadMemory(&value,NULL,cca, AccessLength_HALFWORD,
+                          paddr & ~ (uword64) 1,
+                          vaddr, isINSTRUCTION, isREAL);
+       byte = (((vaddr &~ (uword64) 1) & LOADDRMASK) ^ (bigend << 1));
+       instruction = ((value >> (8 * byte)) & 0xFFFF);
+      }
+    } else {
+      fprintf(stderr,"Cannot translate address for PC = 0x%s failed\n",pr_addr(PC));
+      exit(1);
+    }
+
+#ifdef DEBUG
+    sim_io_printf(sd,"DBG: fetched 0x%08X from PC = 0x%s\n",instruction,pr_addr(PC));
+#endif /* DEBUG */
+
+    /* This is required by exception processing, to ensure that we can
+       cope with exceptions in the delay slots of branches that may
+       already have changed the PC. */
+    if ((vaddr & 1) == 0)
+      PC += 4; /* increment ready for the next fetch */
+    else
+      PC += 2;
+    /* NOTE: If we perform a delay slot change to the PC, this
+       increment is not requuired. However, it would make the
+       simulator more complicated to try and avoid this small hit. */
+
+    /* Currently this code provides a simple model. For more
+       complicated models we could perform exception status checks at
+       this point, and set the simSTOP state as required. This could
+       also include processing any hardware interrupts raised by any
+       I/O model attached to the simulator context.
+
+       Support for "asynchronous" I/O events within the simulated world
+       could be providing by managing a counter, and calling a I/O
+       specific handler when a particular threshold is reached. On most
+       architectures a decrement and check for zero operation is
+       usually quicker than an increment and compare. However, the
+       process of managing a known value decrement to zero, is higher
+       than the cost of using an explicit value UINT_MAX into the
+       future. Which system is used will depend on how complicated the
+       I/O model is, and how much it is likely to affect the simulator
+       bandwidth.
+
+       If events need to be scheduled further in the future than
+       UINT_MAX event ticks, then the I/O model should just provide its
+       own counter, triggered from the event system. */
+
+    /* MIPS pipeline ticks. To allow for future support where the
+       pipeline hit of individual instructions is known, this control
+       loop manages a "pipeline_count" variable. It is initialised to
+       1 (one), and will only be changed by the simulator engine when
+       executing an instruction. If the engine does not have access to
+       pipeline cycle count information then all instructions will be
+       treated as using a single cycle. NOTE: A standard system is not
+       provided by the default simulator because different MIPS
+       architectures have different cycle counts for the same
+       instructions.
+
+       [NOTE: pipeline_count has been replaced the event queue] */
+
+    /* shuffle the floating point status pipeline state */
+    ENGINE_ISSUE_PREFIX_HOOK();
+
+/* NOTE: For multi-context simulation environments the "instruction"
+   variable should be local to this routine. */
+
+/* Shorthand accesses for engine. Note: If we wanted to use global
+   variables (and a single-threaded simulator engine), then we can
+   create the actual variables with these names. */
+
+    if (!(STATE & simSKIPNEXT)) {
+      /* Include the simulator engine */
+#include "oengine.c"
+#if ((GPRLEN == 64) && !PROCESSOR_64BIT) || ((GPRLEN == 32) && PROCESSOR_64BIT)
+#error "Mismatch between run-time simulator code and simulation engine"
+#endif
+#if (WITH_TARGET_WORD_BITSIZE != GPRLEN)
+#error "Mismatch between configure WITH_TARGET_WORD_BITSIZE and gencode GPRLEN"
+#endif
+#if ((WITH_FLOATING_POINT == HARD_FLOATING_POINT) != defined (HASFPU))
+#error "Mismatch between configure WITH_FLOATING_POINT and gencode HASFPU"
+#endif
+
+#if defined(WARN_LOHI)
+      /* Decrement the HI/LO validity ticks */
+      if (HIACCESS > 0)
+       HIACCESS--;
+      if (LOACCESS > 0)
+       LOACCESS--;
+      /* start-sanitize-r5900 */
+      if (HI1ACCESS > 0)
+       HI1ACCESS--;
+      if (LO1ACCESS > 0)
+       LO1ACCESS--;
+      /* end-sanitize-r5900 */
+#endif /* WARN_LOHI */
+
+      /* For certain MIPS architectures, GPR[0] is hardwired to zero. We
+         should check for it being changed. It is better doing it here,
+         than within the simulator, since it will help keep the simulator
+         small. */
+      if (ZERO != 0) {
+#if defined(WARN_ZERO)
+        sim_io_eprintf(sd,"The ZERO register has been updated with 0x%s (PC = 0x%s) (reset back to zero)\n",pr_addr(ZERO),pr_addr(cia));
+#endif /* WARN_ZERO */
+        ZERO = 0; /* reset back to zero before next instruction */
+      }
+    } else /* simSKIPNEXT check */
+     STATE &= ~simSKIPNEXT;
+
+    /* If the delay slot was active before the instruction is
+       executed, then update the PC to its new value: */
+    if (DSSTATE) {
+#ifdef DEBUG
+      printf("DBG: dsstate set before instruction execution - updating PC to 0x%s\n",pr_addr(DSPC));
+#endif /* DEBUG */
+      PC = DSPC;
+      CANCELDELAYSLOT();
+    }
+
+    if (MIPSISA < 4) { /* The following is only required on pre MIPS IV processors: */
+      /* Deal with pending register updates: */
+#ifdef DEBUG
+      printf("DBG: EMPTY BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total);
+#endif /* DEBUG */
+      if (PENDING_OUT != PENDING_IN) {
+        int loop;
+        int index = PENDING_OUT;
+        int total = PENDING_TOTAL;
+        if (PENDING_TOTAL == 0) {
+          fprintf(stderr,"FATAL: Mis-match on pending update pointers\n");
+          exit(1);
+        }
+        for (loop = 0; (loop < total); loop++) {
+#ifdef DEBUG
+          printf("DBG: BEFORE index = %d, loop = %d\n",index,loop);
+#endif /* DEBUG */
+          if (PENDING_SLOT_REG[index] != (LAST_EMBED_REGNUM + 1)) {
+#ifdef DEBUG
+            printf("pending_slot_count[%d] = %d\n",index,PENDING_SLOT_COUNT[index]);
+#endif /* DEBUG */
+            if (--(PENDING_SLOT_COUNT[index]) == 0) {
+#ifdef DEBUG
+              printf("pending_slot_reg[%d] = %d\n",index,PENDING_SLOT_REG[index]);
+              printf("pending_slot_value[%d] = 0x%s\n",index,pr_addr(PENDING_SLOT_VALUE[index]));
+#endif /* DEBUG */
+              if (PENDING_SLOT_REG[index] == COCIDX) {
+#if defined(HASFPU)
+                SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
+#else
+                ;
+#endif
+              } else {
+                REGISTERS[PENDING_SLOT_REG[index]] = PENDING_SLOT_VALUE[index];
+#if defined(HASFPU)
+                /* The only time we have PENDING updates to FPU
+                   registers, is when performing binary transfers. This
+                   means we should update the register type field.  */
+                if ((PENDING_SLOT_REG[index] >= FGRIDX) && (PENDING_SLOT_REG[index] < (FGRIDX + 32)))
+                 FPR_STATE[PENDING_SLOT_REG[index] - FGRIDX] = fmt_uninterpreted;
+#endif /* HASFPU */
+              }
+#ifdef DEBUG
+              printf("registers[%d] = 0x%s\n",PENDING_SLOT_REG[index],pr_addr(REGISTERS[PENDING_SLOT_REG[index]]));
+#endif /* DEBUG */
+              PENDING_SLOT_REG[index] = (LAST_EMBED_REGNUM + 1);
+              PENDING_OUT++;
+              if (PENDING_OUT == PSLOTS)
+               PENDING_OUT = 0;
+              PENDING_TOTAL--;
+            }
+          }
+#ifdef DEBUG
+          printf("DBG: AFTER  index = %d, loop = %d\n",index,loop);
+#endif /* DEBUG */
+          index++;
+          if (index == PSLOTS)
+           index = 0;
+        }
+      }
+#ifdef DEBUG
+      printf("DBG: EMPTY AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL);
+#endif /* DEBUG */
+    }
+
+#if !defined(FASTSIM)
+    if (sim_events_tickn (sd, pipeline_count))
+      {
+       /* cpu->cia = cia; */
+       sim_events_process (sd);
+      }
+#else
+    if (sim_events_tick (sd))
+      {
+       /* cpu->cia = cia; */
+       sim_events_process (sd);
+      }
+#endif /* FASTSIM */
+  }
+}
+#endif
+
+
+/* This code copied from gdb's utils.c.  Would like to share this code,
+   but don't know of a common place where both could get to it. */
+
+/* Temporary storage using circular buffer */
+#define NUMCELLS 16
+#define CELLSIZE 32
+static char*
+get_cell()
+{
+  static char buf[NUMCELLS][CELLSIZE];
+  static int cell=0;
+  if (++cell>=NUMCELLS) cell=0;
+  return buf[cell];
+}     
+
+/* Print routines to handle variable size regs, etc */
+
+/* Eliminate warning from compiler on 32-bit systems */
+static int thirty_two = 32;    
+
+char* 
+pr_addr(addr)
+  SIM_ADDR addr;
+{
+  char *paddr_str=get_cell();
+  switch (sizeof(addr))
+    {
+      case 8:
+        sprintf(paddr_str,"%08lx%08lx",
+               (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
+       break;
+      case 4:
+        sprintf(paddr_str,"%08lx",(unsigned long)addr);
+       break;
+      case 2:
+        sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
+       break;
+      default:
+        sprintf(paddr_str,"%x",addr);
+    }
+  return paddr_str;
+}
+
+char* 
+pr_uword64(addr)
+  uword64 addr;
+{
+  char *paddr_str=get_cell();
+  sprintf(paddr_str,"%08lx%08lx",
+          (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
+  return paddr_str;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*> EOF interp.c <*/
diff --git a/sim/txvu/m16.igen b/sim/txvu/m16.igen
new file mode 100644 (file)
index 0000000..7496ce1
--- /dev/null
@@ -0,0 +1,2692 @@
+//
+// MIPS Architecture:
+//
+//        CPU Instruction Set (mips16)
+//
+
+// The instructions in this section are ordered according
+// to http://www.sgi.com/MIPS/arch/MIPS16/mips16.pdf.
+
+
+// FIXME: Instead of having the code for mips16 instructions here.
+// these instructions should instead call the corresponding 32bit
+// instruction (or a function implementing that instructions code).
+
+
+
+011101,26.INSTR_INDEX:NORMAL:32::JALX
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  unsigned_word op1 = (((instruction >> 0) & 0x03FFFFFF) << 2);
+  op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */
+  {
+    int destreg = 31;
+    GPR[destreg] = (PC + 4); /* NOTE: The PC is already 4 ahead within the simulator */
+    op1 ^= 1;
+    /* NOTE: ??? Gdb gets confused if the PC is sign-extended,
+       so we just truncate it to 32 bits here.  */
+    op1 = VL4_8(op1);
+    /* NOTE: The jump occurs AFTER the next instruction has been executed */
+    DELAY_SLOT (op1);
+    /* JALDELAYSLOT(); FIXME */
+  }
+}
+
+
+// Load and Store Instructions
+
+
+10000,xxx,ddd,55555:RRI:16::LB
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL);
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x000000FF),8));
+       }
+    }
+  }
+}
+
+
+10100,xxx,ddd,55555:RRI:16::LBU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL);
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         GPR[destreg] = (((memval >> (8 * byte)) & 0x000000FF));
+       }
+    }
+  }
+}
+
+
+10001,xxx,ddd,HHHHH:RRI:16::LH
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 1;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x0000FFFF),16));
+         }
+      }
+  }
+}
+
+
+10101,xxx,ddd,HHHHH:RRI:16::LHU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 1;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (((memval >> (8 * byte)) & 0x0000FFFF));
+         }
+      }
+  }
+}
+
+
+10011,xxx,ddd,WWWWW:RRI:16::LW
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+         }
+      }
+  }
+}
+
+
+10110,ddd,VVVVVVVV,P:RI:16::LWPC
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+         }
+      }
+  }
+}
+
+
+10010,ddd,VVVVVVVV,s:RI:16::LWSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+         }
+      }
+  }
+}
+
+
+10111,xxx,ddd,WWWWW:RRI:16::LWU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (((memval >> (8 * byte)) & 0xFFFFFFFF));
+         }
+      }
+  }
+}
+
+
+00111,xxx,ddd,DDDDD:RRI:16::LD
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 4;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+         }
+      }
+  }
+}
+
+
+11111100,ddd,5.RD,P:RI64:16::LDPC
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  signed_word op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 4;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+         }
+      }
+  }
+}
+
+
+11111000,ddd,5.RD,s:RI64:16::LDSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  signed_word op1 = 29;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 4;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+         }
+      }
+  }
+}
+
+
+11000,xxx,yyy,55555:RRI:16::SB
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         memval = ((unsigned64) op2 << (8 * byte));
+         {
+           StoreMemory(uncached,AccessLength_BYTE,memval,memval1,paddr,vaddr,isREAL);
+         }
+       }
+    }
+  }
+}
+
+
+11001,xxx,yyy,HHHHH:RRI:16::SH
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 1;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_HALFWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+11011,xxx,yyy,WWWWW:RRI:16::SW
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+11010,yyy,VVVVVVVV,s:RI:16::SWSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op2 = (instruction >> 8) & 0x7;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+01100010,VVVVVVVV,Q,s:I8:16::SWRASP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op2 = 31;
+  signed_word op1 = 29;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 2;
+    }
+  op2 = GPR[op2];
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+01111,xxx,yyy,DDDDD:RRI:16::SD
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = op2;
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+11111001,yyy,5.RD,s:RI64:16::SDSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int offset = (instruction >> 0) & 0x1f;
+  signed_word op1 = 29;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = op2;
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+11111010,CCCCCCCC,s,Q:I64:16::SDRASP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  signed_word op2 = 31;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      offset <<= 3;
+    }
+  op1 = GPR[op1];
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = op2;
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+// ALU Immediate Instructions
+
+
+01101,ddd,UUUUUUUU,Z:RI:16::LI
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  signed_word op1 = 0;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if (destreg != 0)
+      GPR[destreg] = (op1 | op2);
+  }
+}
+
+
+01000,xxx,ddd,04444:RRI_A:16::ADDIU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int op2 = (instruction >> 0) & 0xf;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0xf) << 11) | (extendval & 0x7f0);
+      if (op2 >= 0x4000)
+        op2 -= 0x8000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x8)
+        op2 -= 0x10;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+01001,www,kkkkkkkk:RI:16::ADDIU8
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg;
+  int op2 = (instruction >> 0) & 0xff;
+  if (op1 < 2)
+    op1 += 16;
+  destreg = op1;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x80)
+        op2 -= 0x100;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+01100011,KKKKKKKK,S:I8:16::ADJSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int op2 = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  int destreg;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x80)
+        op2 -= 0x100;
+      op2 <<= 3;
+    }
+  destreg = op1;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+00001,ddd,AAAAAAAA,P:RI:16::ADDIUPC
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  signed_word op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      op2 <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+00000,ddd,AAAAAAAA,s:RI:16::ADDIUSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      op2 <<= 2;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+01000,xxx,ddd,14444:RRI_A:16::DADDIU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = (instruction >> 5) & 0x7;
+  int op2 = (instruction >> 0) & 0xf;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0xf) << 11) | (extendval & 0x7f0);
+      if (op2 >= 0x4000)
+        op2 -= 0x8000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x8)
+        op2 -= 0x10;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11111101,www,jjjjj:RI64:16::DADDIU5
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 5) & 0x7;
+  int destreg;
+  int op2 = (instruction >> 0) & 0x1f;
+  if (op1 < 2)
+    op1 += 16;
+  destreg = op1;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x10)
+        op2 -= 0x20;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11111011,KKKKKKKK,S:I64:16::DADJSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int op2 = (instruction >> 0) & 0xff;
+  signed_word op1 = 29;
+  int destreg;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op2 >= 0x80)
+        op2 -= 0x100;
+      op2 <<= 3;
+    }
+  destreg = op1;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11111110,ddd,EEEEE,P:RI64:16::DADDIUPC
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 5) & 0x7;
+  int op2 = (instruction >> 0) & 0x1f;
+  signed_word op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      op2 <<= 2;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11111111,ddd,EEEEE,s:RI64:16::DADDIUSP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 5) & 0x7;
+  int op2 = (instruction >> 0) & 0x1f;
+  signed_word op1 = 29;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      op2 <<= 2;
+    }
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+01010,xxx,88888888,T:RI:16::SLTI
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if ((word64)op1 < (word64)op2)
+      GPR[destreg] = 1;
+    else
+      GPR[destreg] = 0;
+  }
+}
+
+
+01011,xxx,88888888,T:RI:16::SLTIU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (op2 >= 0x8000)
+        op2 -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if ((unsigned64)op1 < (unsigned64)op2)
+      GPR[destreg] = 1;
+    else
+      GPR[destreg] = 0;
+  }
+}
+
+
+11101,xxx,yyy,01010,T:RR:16::CMP
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = (op1 ^ op2);
+  }
+}
+
+
+01110,xxx,UUUUUUUU,T:RI:16::CMPI
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int op2 = (instruction >> 0) & 0xff;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      have_extendval = 0;
+    }
+  else
+    {
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = (op1 ^ op2);
+  }
+}
+
+
+// Two/Three Operand, Register-Type
+
+
+11100,xxx,yyy,ddd,01:RRR:16::ADDU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = (instruction >> 2) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 + op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+11100,xxx,yyy,ddd,11:RRR:16::SUBU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = (instruction >> 2) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 - op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+11100,xxx,yyy,ddd,00:RRR:16::DADDU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = (instruction >> 2) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 + op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11100,xxx,yyy,ddd,10:RRR:16::DSUBU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = (instruction >> 2) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 temp = (unsigned64)(op1 - op2);
+    word64 tempS = (word64)temp;
+    GPR[destreg] = (unsigned64)temp;
+  }
+}
+
+
+11101,xxx,yyy,00010,T:RR:16::SLT
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if ((word64)op1 < (word64)op2)
+      GPR[destreg] = 1;
+    else
+      GPR[destreg] = 0;
+  }
+}
+
+
+11101,xxx,yyy,00011,T:RR:16::SLTU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg = 24;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if ((unsigned64)op1 < (unsigned64)op2)
+      GPR[destreg] = 1;
+    else
+      GPR[destreg] = 0;
+  }
+}
+
+
+11101,ddd,yyy,01011,Z:RR:16::NEG
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  signed_word op1 = 0;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int temp = (unsigned int)(op1 - op2);
+    signed int tempS = (signed int)temp;
+    GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32);
+  }
+}
+
+
+11101,www,yyy,01100:RR:16::AND
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  destreg = op1;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = (op1 & op2);
+  }
+}
+
+
+11101,www,yyy,01101:RR:16::OR
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  destreg = op1;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if (destreg != 0)
+      GPR[destreg] = (op1 | op2);
+  }
+}
+
+
+11101,www,yyy,01110:RR:16::XOR
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  destreg = op1;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = (op1 ^ op2);
+  }
+}
+
+
+11101,ddd,yyy,01111,Z:RR:16::NOT
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  signed_word op1 = 0;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if (destreg != 0)
+      GPR[destreg] = ~(op1 | op2);
+  }
+}
+
+
+01100111,ddd,XXXXX,z:I8_MOVR32:16::MOVR32
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 5) & 0x7;
+  signed_word op1 = (instruction >> 0) & 0x1f;
+  signed_word op2 = 0;
+  if (destreg < 2)
+    destreg += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if (destreg != 0)
+      GPR[destreg] = (op1 | op2);
+  }
+}
+
+
+01100101,YYYYY,xxx,z:I8_MOV32R:16::MOV32R
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 3) & 0x1f;
+  signed_word op1 = (instruction >> 0) & 0x7;
+  signed_word op2 = 0;
+  destreg = (destreg >> 2) | ((destreg & 3) << 3);
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    if (destreg != 0)
+      GPR[destreg] = (op1 | op2);
+  }
+}
+
+
+00110,ddd,yyy,sss,00:ISHIFT:16::SLL
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int op1 = (instruction >> 2) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      op1 = (extendval >> 6) & 0x1f;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = ((unsigned64)op2 << op1);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+00110,ddd,yyy,sss,10:ISHIFT:16::SRL
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int op1 = (instruction >> 2) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      op1 = (extendval >> 6) & 0x1f;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+00110,ddd,yyy,sss,11:ISHIFT:16::SRA
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int op1 = (instruction >> 2) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      op1 = (extendval >> 6) & 0x1f;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int highbit = (unsigned int)1 << 31;
+    GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1);
+    GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned int)1 << op1) - 1) << (32 - op1)) : 0);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+11101,xxx,vvv,00100:RR:16::SLLV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    op1 &= 0x1F;
+    GPR[destreg] = ((unsigned64)op2 << op1);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+11101,xxx,vvv,00110:RR:16::SRLV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    op1 &= 0x1F;
+    GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+11101,xxx,vvv,00111:RR:16::SRAV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned int highbit = (unsigned int)1 << 31;
+    op1 &= 0x1F;
+    GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1);
+    GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned int)1 << op1) - 1) << (32 - op1)) : 0);
+    GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+  }
+}
+
+
+00110,ddd,yyy,[[[,01:ISHIFT:16::DSLL
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int op1 = (instruction >> 2) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    {
+      op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20);
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = ((unsigned64)op2 << op1);
+  }
+}
+  
+  
+11101,XXX,vvv,01000:RR:16::DSRL
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (have_extendval)
+    {
+      op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20);
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = ((unsigned64)(op2) >> op1);
+  }
+}
+
+
+11101,xxx,vvv,10011:RR:16::DSRA
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (have_extendval)
+    {
+      op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20);
+      have_extendval = 0;
+    }
+  else
+    {
+      if (op1 == 0)
+        op1 = 8;
+    }
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 highbit = (unsigned64)1 << 63;
+    GPR[destreg] = ((unsigned64)(op2) >> op1);
+    GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned64)1 << op1) - 1) << (64 - op1)) : 0);
+  }
+}
+
+
+11101,xxx,vvv,10100:RR:16::DSLLV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    op1 &= 0x3F;
+    GPR[destreg] = ((unsigned64)op2 << op1);
+  }
+}
+
+
+11101,xxx,vvv,10110:RR:16::DSRLV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    op1 &= 0x3F;
+    GPR[destreg] = ((unsigned64)(op2) >> op1);
+  }
+}
+
+
+11101,xxx,vvv,10111:RR:16::DSRAV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  int destreg;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  destreg = op2;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    unsigned64 highbit = (unsigned64)1 << 63;
+    op1 &= 0x3F;
+    GPR[destreg] = ((unsigned64)(op2) >> op1);
+    GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned64)1 << op1) - 1) << (64 - op1)) : 0);
+  }
+}
+
+
+// Multiply /Divide Instructions
+
+
+11101,xxx,yyy,11000:RR:16::MULT
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 temp = ((word64) op1 * (word64) op2);
+      LO = SIGNEXTEND((unsigned64)VL4_8(temp),32);
+      HI = SIGNEXTEND((unsigned64)VH4_8(temp),32);
+    }
+  }
+}
+
+
+11101,xxx,yyy,11001:RR:16::MULTU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 temp = ((unsigned64)(op1 & 0xffffffff) * (unsigned64)(op2 & 0xffffffff));
+      LO = SIGNEXTEND((unsigned64)VL4_8(temp),32);
+      HI = SIGNEXTEND((unsigned64)VH4_8(temp),32);
+    }
+  }
+}
+
+
+11101,xxx,yyy,11010:RR:16::DIV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Division");
+    {
+      int d1 = op1;
+      int d2 = op2;
+      if (d2 == 0)
+       {
+         LO = SIGNEXTEND(0x80000000,32);
+         HI = SIGNEXTEND(0,32);
+       }
+      else if (d2 == -1 && d1 == 0x80000000)
+       {
+         LO = SIGNEXTEND(0x80000000,32);
+         HI = SIGNEXTEND(0,32);
+       }
+      else
+       {
+         LO = SIGNEXTEND((d1 / d2),32);
+         HI = SIGNEXTEND((d1 % d2),32);
+       }
+    }
+  }
+}
+
+
+11101,xxx,yyy,11011:RR:16::DIVU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Division");
+    {
+      unsigned int d1 = op1;
+      unsigned int d2 = op2;
+      if (d2 == 0)
+       {
+         LO = SIGNEXTEND(0x80000000,32);
+         HI = SIGNEXTEND(0,32);
+       }
+      else if (d2 == -1 && d1 == 0x80000000)
+       {
+         LO = SIGNEXTEND(0x80000000,32);
+         HI = SIGNEXTEND(0,32);
+       }
+      else
+       {
+         LO = SIGNEXTEND((d1 / d2),32);
+         HI = SIGNEXTEND((d1 % d2),32);
+       }
+    }
+  }
+}
+
+
+11101,ddd,00010000:RR:16::MFHI
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = HI;
+    HIACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+
+11101,ddd,00010010:RR:16::MFLO
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = (instruction >> 8) & 0x7;
+  if (destreg < 2)
+    destreg += 16;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = LO;
+    LOACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+
+11101,xxx,yyy,11100:RR:16::DMULT
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 mid;
+      unsigned64 midhi;
+      unsigned64 temp;
+      int sign = 0;
+      if (op1 < 0) { op1 = - op1; ++sign; }
+      if (op2 < 0) { op2 = - op2; ++sign; }
+      LO = ((unsigned64)VL4_8(op1) * VL4_8(op2));
+      HI = ((unsigned64)VH4_8(op1) * VH4_8(op2));
+      mid = ((unsigned64)VH4_8(op1) * VL4_8(op2));
+      midhi = SET64HI(VL4_8(mid));
+      temp = (LO + midhi);
+      if ((temp == midhi) ? (LO != 0) : (temp < midhi))
+       HI += 1;
+      HI += VH4_8(mid);
+      mid = ((unsigned64)VL4_8(op1) * VH4_8(op2));
+      midhi = SET64HI(VL4_8(mid));
+      LO = (temp + midhi);
+      if ((LO == midhi) ? (temp != 0) : (LO < midhi))
+       HI += 1;
+      HI += VH4_8(mid);
+      if (sign & 1) { LO = - LO; HI = (LO == 0 ? 0 : -1) - HI; }
+    }
+  }
+}
+
+
+11101,xxx,yyy,11101:RR:16::DMULTU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 mid;
+      unsigned64 midhi;
+      unsigned64 temp;
+      LO = ((unsigned64)VL4_8(op1) * VL4_8(op2));
+      HI = ((unsigned64)VH4_8(op1) * VH4_8(op2));
+      mid = ((unsigned64)VH4_8(op1) * VL4_8(op2));
+      midhi = SET64HI(VL4_8(mid));
+      temp = (LO + midhi);
+      if ((temp == midhi) ? (LO != 0) : (temp < midhi))
+       HI += 1;
+      HI += VH4_8(mid);
+      mid = ((unsigned64)VL4_8(op1) * VH4_8(op2));
+      midhi = SET64HI(VL4_8(mid));
+      LO = (temp + midhi);
+      if ((LO == midhi) ? (temp != 0) : (LO < midhi))
+       HI += 1;
+      HI += VH4_8(mid);
+    }
+  }
+}
+
+
+11101,xxx,yyy,11110:RR:16::DDIV
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Division");
+    {
+      word64 d1 = op1;
+      word64 d2 = op2;
+      if (d2 == 0)
+       {
+         LO = SIGNED64 (0x8000000000000000);
+         HI = 0;
+       }
+      else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000))
+       {
+         LO = SIGNED64 (0x8000000000000000);
+         HI = 0;
+       }
+      else
+       {
+         LO = (d1 / d2);
+         HI = (d1 % d2);
+       }
+    }
+  }
+}
+
+
+11101,xxx,yyy,11111:RR:16::DDIVU
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  signed_word op2 = (instruction >> 5) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (op2 < 2)
+    op2 += 16;
+  op2 = GPR[op2];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    CHECKHILO("Division");
+    {
+      unsigned64 d1 = op1;
+      unsigned64 d2 = op2;
+      if (d2 == 0)
+       {
+         LO = SIGNED64 (0x8000000000000000);
+         HI = 0;
+       }
+      else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000))
+       {
+         LO = SIGNED64 (0x8000000000000000);
+         HI = 0;
+       }
+      else
+       {
+         LO = (d1 / d2);
+         HI = (d1 % d2);
+       }
+    }
+  }
+}
+
+
+// Jump and Branch Instructions
+
+
+// JALX
+// JAL
+00011,aaaaaaaaaaa:I:16::JAL
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  unsigned_word op1 = (instruction >> 0) & 0x7ff;
+  {
+    address_word paddr;
+    int uncached;
+    if (AddressTranslation (PC &~ (unsigned64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))
+      {
+        unsigned64 memval;
+        unsigned int reverse = (ReverseEndian ? 3 : 0);
+        unsigned int bigend = (BigEndianCPU ? 3 : 0);
+        unsigned int byte;
+        paddr = ((paddr & ~0x7) | ((paddr & 0x7) ^ (reverse << 1)));
+        LoadMemory (&memval,0,uncached, AccessLength_HALFWORD, paddr, PC, isINSTRUCTION, isREAL);
+        byte = (((PC &~ (unsigned64) 1) & 0x7) ^ (bigend << 1));
+        memval = (memval >> (8 * byte)) & 0xffff;
+        op1 = (((op1 & 0x1f) << 23)
+              | ((op1 & 0x3e0) << 13)
+              | (memval << 2));
+        if ((instruction & 0x400) == 0)
+          op1 |= 1;
+        PC += 2;
+      }
+  }
+  op1 |= PC & ~ (unsigned64) 0x0fffffff;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int destreg = 31;
+    GPR[destreg] = (PC + 2); /* NOTE: The PC is already 2 ahead within the simulator */
+    /* NOTE: ??? Gdb gets confused if the PC is sign-extended,
+       so we just truncate it to 32 bits here.  */
+    op1 = VL4_8(op1);
+    /* NOTE: The jump occurs AFTER the next instruction has been executed */
+    DELAY_SLOT op1;
+    JALDELAYSLOT();
+  }
+}
+
+
+11101,xxx,00000000:RR:16::JR
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    /* NOTE: ??? Gdb gets confused if the PC is sign-extended,
+       so we just truncate it to 32 bits here.  */
+    op1 = VL4_8(op1);
+    /* NOTE: The jump occurs AFTER the next instruction has been executed */
+    DELAY_SLOT op1;
+    DELAYSLOT();
+  }
+}
+
+
+1110100000100000,r:RR:16::JRRA
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = 31;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    /* NOTE: ??? Gdb gets confused if the PC is sign-extended,
+       so we just truncate it to 32 bits here.  */
+    op1 = VL4_8(op1);
+    /* NOTE: The jump occurs AFTER the next instruction has been executed */
+    DELAY_SLOT op1;
+    DELAYSLOT();
+  }
+}
+
+
+11101,xxx,01000000,R:RR:16::JALR
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int destreg = 31;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    GPR[destreg] = (PC + 2); /* NOTE: The PC is already 2 ahead within the simulator */
+    /* NOTE: ??? Gdb gets confused if the PC is sign-extended,
+       so we just truncate it to 32 bits here.  */
+    op1 = VL4_8(op1);
+    /* NOTE: The jump occurs AFTER the next instruction has been executed */
+    DELAY_SLOT op1;
+    DELAYSLOT();
+  }
+}
+
+
+00100,xxx,pppppppp,z:RI:16::BEQZ
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op2 = 0;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (offset >= 0x80)
+        offset -= 0x100;
+    }
+  offset *= 2;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int condition = (op1 == op2);
+    if (condition)
+      PC = PC + offset;
+  }
+}
+
+
+00101,xxx,pppppppp,z:RI:16::BNEZ
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = (instruction >> 8) & 0x7;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op2 = 0;
+  if (op1 < 2)
+    op1 += 16;
+  op1 = GPR[op1];
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (offset >= 0x80)
+        offset -= 0x100;
+    }
+  offset *= 2;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int condition = (op1 != op2);
+    if (condition)
+      PC = PC + offset;
+  }
+}
+
+
+01100000,pppppppp,t,z:I8:16::BTEQZ
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = 24;
+  signed_word op2 = 0;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (offset >= 0x80)
+        offset -= 0x100;
+    }
+  offset *= 2;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int condition = (op1 == op2);
+    if (condition)
+      PC = PC + offset;
+  }
+}
+
+
+01100001,pppppppp,t,z:I8:16::BTNEZ
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int offset = (instruction >> 0) & 0xff;
+  signed_word op1 = 24;
+  signed_word op2 = 0;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (offset >= 0x80)
+        offset -= 0x100;
+    }
+  offset *= 2;
+  op1 = GPR[op1];
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int condition = (op1 != op2);
+    if (condition)
+      PC = PC + offset;
+  }
+}
+
+
+00010,qqqqqqqqqqq,z,Z:I:16::B
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int offset = (instruction >> 0) & 0x7ff;
+  signed_word op2 = 0;
+  signed_word op1 = 0;
+  if (have_extendval)
+    {
+      offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);
+      if (offset >= 0x8000)
+        offset -= 0x10000;
+      have_extendval = 0;
+    }
+  else
+    {
+      if (offset >= 0x400)
+        offset -= 0x800;
+    }
+  offset *= 2;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    int condition = (op1 == op2);
+    if (condition)
+      PC = PC + offset;
+  }
+}
+
+
+// Special Instructions
+
+
+// See the front of the mips16 doc
+11110,eeeeeeeeeee:I:16::EXTEND
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  int ext = (instruction >> 0) & 0x7ff;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    extendval = ext;
+    have_extendval = 1;
+  }
+}
+
+
+01100,******,00101:RR:16::BREAK
+*mips16:
+{
+  unsigned32 instruction = instruction_0;
+  if (have_extendval)
+    SignalException (ReservedInstruction, instruction);
+  {
+    SignalException(BreakPoint,instruction);
+  }
+}
+
diff --git a/sim/txvu/mdmx.igen b/sim/txvu/mdmx.igen
new file mode 100644 (file)
index 0000000..b77f5ee
--- /dev/null
@@ -0,0 +1,1298 @@
+// Media Instructions
+// ------------------
+
+// Ref: http://www.sgi.com/MIPS/arch/ISA5/MDMXspec.pdf
+
+// Note: For OB instructions, the sel field is deduced by special
+// handling of the "vt" operand.
+//         If vt is:
+//             of the form $vt[0],        then sel is 0000
+//             of the form $vt[1],        then sel is 0001
+//             of the form $vt[2],        then sel is 0010
+//             of the form $vt[3],        then sel is 0011
+//             of the form $vt[4],        then sel is 0100
+//             of the form $vt[5],        then sel is 0101
+//             of the form $vt[6],        then sel is 0110
+//             of the form $vt[7],        then sel is 0111
+//             Normal register specifier, then sel is 1011
+//             Constant,                  then sel is 1111
+//
+// VecAcc is the Vector Accumulator.
+//     This accumulator is organized as 8X24 bit (192 bit) register.
+//     This accumulator holds only signed values.
+
+
+// Verify that the instruction is valid for the curent Architecture
+// If valid, return the scale (log nr bits) of a vector element
+// as determined by SEL.
+
+:function:::int:get_scale:int sel
+{
+#if 0
+  switch (my_index X STATE_ARCHITECTURE)
+    {
+    }
+#endif
+  switch (sel & 0x7)
+    {
+    case 0:
+    case 2:  
+    case 4:
+    case 6:
+      /* octal byte - ssss0 */
+      return 0;
+    case 1:
+    case 5:
+      /* quad halfword - sss01 */
+      return 1;
+    case 3:
+      /* bi word - ss011 */
+      semantic_illegal (sd, cia);
+      return 2;
+    case 7:
+      /* long - ss111 */
+      semantic_illegal (sd, cia);
+      return 3;
+    default:
+      abort ();
+      return -1;
+    }
+}
+
+
+// Fetch/Store VALUE in ELEMENT of vector register FPR.
+// The the of the element determined by SCALE.
+
+:function:::signed:value_vr:int scale, int fpr, int el
+{
+  switch (FPR_STATE[fpr])
+    {
+    case fmt_uninterpreted:
+      FPR_STATE[fpr] = fmt_long;
+      break;
+    case fmt_long:
+    case fmt_unknown:
+      break;
+    default:
+      sim_io_eprintf(sd, "Vector %d format invalid (PC = 0x%08lx)\n",
+                    fpr, (long) cia);
+      FPR_STATE[fpr] = fmt_unknown;
+    }
+  switch (scale)
+    {
+    case 0:
+      {
+       signed8 value = *A1_8 (&FGR[fpr], 7 - el);
+       return value;
+      }
+    case 1:
+      {
+       signed16 value = *A2_8 (&FGR[fpr], 3 - el);
+       return value;
+      }
+    default:
+      abort;
+    }
+  return 0;
+}
+
+:function:::void:store_vr:int scale, int fpr, int element, signed value
+{
+  switch (FPR_STATE[fpr])
+    {
+    case fmt_uninterpreted:
+      FPR_STATE[fpr] = fmt_long;
+      break;
+    case fmt_long:
+    case fmt_unknown:
+      break;
+    default:
+      sim_io_eprintf(sd, "Vector %d format invalid (PC = 0x%08lx)\n",
+                    fpr, (long) cia);
+      FPR_STATE[fpr] = fmt_unknown;
+    }
+  switch (scale)
+    {
+    case 0:
+      {
+       *A1_8 (&FGR[fpr], 7 - element) = value;
+       break;
+      }
+    case 1:
+      {
+       *A2_8 (&FGR[fpr], 3 - element) = value;
+       break;
+      }
+    default:
+      abort ();
+    }
+}
+
+
+// Select a value from onr of FGR[VT][ELEMENT], VT and GFR[VT][CONST]
+// according to SEL
+
+:function:::unsigned:select_vr:int sel, int vt, int element
+{
+  switch (sel)
+    {
+      /* element select - 0xxxx */
+    case 0x00: /* 0 xxx 0 */
+    case 0x02:
+    case 0x04:
+    case 0x06:
+    case 0x08:
+    case 0x0a:
+    case 0x0c:
+    case 0x0e:
+      return value_vr (SD_, 0, vt, sel >> 1);
+    case 0x01: /* 0 xx 01 */
+    case 0x05:
+    case 0x09:
+    case 0x0d:
+      return value_vr (SD_, 1, vt, sel >> 2);
+    case 0x03: /* 0 x 011 */
+    case 0x0b:
+      return value_vr (SD_, 2, vt, sel >> 3);
+    case 0x07: /* 0 x 111 */
+    case 0x0f:
+      return value_vr (SD_, 3, vt, sel >> 4);
+
+      /* select vector - 10xxx */
+    case 0x16: /* 10 11 0 */
+      return value_vr (SD_, 0, vt, element);
+    case 0x15: /* 10 1 01 */
+      return value_vr (SD_, 1, vt, element);
+    case 0x13: /* 10  011 */
+      return value_vr (SD_, 2, vt, element);
+    case 0x17: /* 10  111 */
+      return value_vr (SD_, 3, vt, element);
+
+      /* select immediate - 11xxx */
+    case 0x1e: /* 11 11 0 */
+    case 0x1d: /* 11 1 01 */
+    case 0x1b: /* 11  011 */
+    case 0x1f: /* 11  111 */
+      return vt;
+
+    }
+  return 0;
+}
+
+
+// Saturate (clamp) the signed value to (8 << SCALE) bits.
+
+:function:::signed:Clamp:int scale, signed value
+{
+  switch (scale)
+    {
+    case 0:
+      {
+       if (value != (signed8) value)
+         {
+           if (value > 0)
+             return 0x7f;
+           else
+             return 0x80;
+         }
+       return value & 0xff;
+      }
+    case 1:
+      {
+       if (value != (signed16) value)
+         {
+           if (value > 0)
+              return 0x7fff;
+           else
+              return 0x8000;
+         }
+       return value & 0xffff;
+      }
+    default:
+      abort ();
+      return 0;
+    }
+}
+
+
+// Access a single bit of the floating point CC register.
+
+:function:::void:store_cc:int i, int value
+{
+  SETFCC (i, value);
+}
+
+:function:::int:value_cc:int i
+{
+  return GETFCC (i);
+}
+
+
+//  Read/write the accumulator
+
+:function:::signed64:value_acc:int scale, int element
+{
+  signed64 value = 0;
+  switch (scale)
+    {
+    case 0:
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
+      value |= (signed64) (signed8) CPU->acc [element * 3 + 2] << 16;
+      break;
+    case 1:
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 0];
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 1] << 8;
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 2] << 16;
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 3] << 24;
+      value |= (unsigned64) (unsigned8) CPU->acc [element * 3 + 4] << 32;
+      value |= (signed64) (signed8) CPU->acc [element * 3 + 5] << 40;
+      break;
+    }
+  return value;
+}
+
+:function:::void:store_acc:int scale, int element, signed64 value
+{
+  switch (scale)
+    {
+    case 0:
+      CPU->acc [element * 3 + 0] = value >> 0;
+      CPU->acc [element * 3 + 1] = value >> 8;
+      CPU->acc [element * 3 + 2] = value >> 16;
+      break;
+    case 1:
+      CPU->acc [element * 3 + 0] = value >> 0;
+      CPU->acc [element * 3 + 1] = value >> 8;
+      CPU->acc [element * 3 + 2] = value >> 16;
+      CPU->acc [element * 3 + 3] = value >> 24;
+      CPU->acc [element * 3 + 4] = value >> 32;
+      CPU->acc [element * 3 + 5] = value >> 40;
+      break;
+    }
+}
+
+
+// Formatting
+
+:%s::::VT:int sel, int vt
+{
+  static char buf[20];
+  if (sel < 8)
+    sprintf (buf, "v%d[%d]", vt, sel);
+  else if (sel == 0x13)
+    sprintf (buf, "v%d", vt);
+  else if (sel == 0x1f)
+    sprintf (buf, "%d", vt);
+  else
+    sprintf (buf, "(invalid)");
+  return buf;
+}
+
+:%s::::SEL:int sel
+{
+  switch (sel & 7)
+    {
+    case 0:
+    case 2:
+    case 4:
+    case 6:
+      return "ob";
+    case 1:
+    case 5:
+      return "qh";
+    case 3:
+      return "bw";
+    default:
+      return "l";
+    }
+}
+
+
+// Vector Add.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001011::::ADD.fmt
+"add.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             Clamp (SD_, scale,
+                    (value_vr (SD_, scale, VS, i)
+                     + select_vr (SD_, SEL, VT, i))));
+}
+
+
+// Accumulate Vector Add
+
+010010,5.SEL,5.VT,5.VS,1,0000,110111::::ADDA.fmt
+"adda.%s<SEL> v<VD>, v<VS>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              (value_acc (SD_, scale, i)
+               + (signed64) value_vr (SD_, scale, VS, i)
+               + (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+// Load Vector Add
+
+010010,5.SEL,5.VT,5.VS,0,0000,110111::::ADDA.fmt
+"addl.%s<SEL> v<VD>, v<VS>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              ((signed64) value_vr (SD_, scale, VS, i)
+               + (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector align, Constant Alignment
+
+:function:::void:ByteAlign:int vd, int imm, int vs, int vt
+{
+  int s = imm * 8;
+  unsigned64 rs = value_fpr (sd, cia, vs, fmt_long);
+  unsigned64 rt = value_fpr (sd, cia, vt, fmt_long);
+  unsigned64 rd;
+  if (BigEndianCPU)
+    {
+      /* (vs || vt) [127 - S .. 64 - S] */
+      if (s == 0)
+       rd = rs;
+      else
+       rd = (MOVED64 (rs, 64 - s, 0, 63, s)
+             | EXTRACTED64 (rt, 63, 64 - s));
+    }
+  else
+    {
+      /* (vs || vt) [63 + S .. S] */
+      if (s == 0)
+       rd = rt;
+      else
+       rd = (MOVED64 (rs, s, 0, 63, 64 - s)
+             | EXTRACTED64 (rt, 63, s));
+    }
+  store_fpr (sd, cia, vd, rd, fmt_long);
+}
+
+010010,00,3.IMM,5.VT,5.VS,5.VD,0110,X,0::::ALNI.fmt
+"alni.%s<FMT#X> v<VD>, v<VS>, v<VT>, <IMM>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  ByteAlign (SD_, VD, IMM, VS, VT);
+}
+
+
+
+// Vector align, Variable Alignment
+
+010010,5.RS,5.VT,5.VS,5.VD,0110,X,1::::ALNV.fmt
+"alnv.%s<FMT#X> v<VD>, v<VS>, v<VT>, r<RS>"
+*mdmx:
+{
+  ByteAlign (SD_, VD, GPR[RS], VS, VT);
+}
+
+
+
+// Vector And.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001100::::AND.fmt
+"and.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              & select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Compare Equal.
+
+
+010010,5.SEL,5.VT,5.VS,00000,000001::::C.EQ.fmt
+"c.EQ.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_cc (SD_, i,
+             (value_vr (SD_, scale, VS, i)
+              == select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Compare Less Than or Equal.
+
+010010,5.SEL,5.VT,5.VS,00000,000101::::C.LE.fmt
+"c.le.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_cc (SD_, i,
+             (value_vr (SD_, scale, VS, i)
+              <= select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Compare Less Than.
+
+010010,5.SEL,5.VT,5.VS,00000,000100::::C.LT.fmt
+"c.lt.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_cc (SD_, i,
+             (value_vr (SD_, scale, VS, i)
+              < select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Maximum.
+
+:function:::signed:Max:int scale, signed l, signed r
+{
+  if (l < r)
+    return r;
+  else
+    return l;
+}
+
+010010,5.SEL,5.VT,5.VS,5.VD,000111::::MAX.fmt
+"max.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             Max (SD_, scale,
+                  value_vr (SD_, scale, VS, i),
+                  select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Minimum.
+
+:function:::signed:Min:int scale, signed l, signed r
+{
+  if (l < r)
+    return l;
+  else
+    return r;
+}
+
+010010,5.SEL,5.VT,5.VS,5.VD,000110::::MIN.fmt
+"min.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             Min (SD_, scale,
+                  value_vr (SD_, scale, VS, i),
+                  select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Sign.
+
+:function:::signed:Sign:int scale, signed l, signed r
+{
+  if (l >= 0)
+    return r;
+  else if (r >= 0)
+    return -r;
+  else
+    {
+      /* watch for overflow of MIN_INT */
+      switch (scale)
+       {
+       case 0:
+         if ((r & 0xff) == 0x80)
+           return 0x7ff;
+         else
+           return -r;
+       case 1:
+         if ((r & 0xffff) == 0x8000)
+           return 0x7ffff;
+         else
+           return -r;
+       default:
+         abort ();
+       }
+      return -r;
+    }
+}
+
+010010,5.SEL,5.VT,5.VS,5.VD,000110::::MSGN.fmt
+"msgn.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  if ((SEL & 1) != 1)
+    /* only QH allowed */
+    semantic_illegal (sd, cia);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             Sign (SD_, scale,
+                   value_vr (SD_, scale, VS, i),
+                   select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Multiply.
+
+010010,5.SEL,5.VT,5.VS,5.VD,110000::::MUL.fmt
+"mul.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             Clamp (SD_, scale,
+                    (value_vr (SD_, scale, VS, i)
+                     * select_vr (SD_, SEL, VT, i))));
+}
+
+
+
+// Accumulate Vector Multiply
+
+010010,5.SEL,5.VT,5.VS,00000,110011::::MULA.fmt
+"mula.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              (value_acc (SD_, scale, i)
+               + ((signed64) value_vr (SD_, scale, VS, i)
+                  * (signed64) select_vr (SD_, SEL, VT, i))));
+}
+
+
+
+// Add Vector Multiply to Accumulator.
+
+010010,5.SEL,5.VT,5.VS,10000,110011::::MULL.fmt
+"mull.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              ((signed64) value_vr (SD_, scale, VS, i)
+               * (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Subtract Vector Multiply from Accumulator
+
+010010,5.SEL,5.VT,5.VS,00000,110010::::MULS.fmt
+"muls.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              (value_acc (SD_, scale, i)
+               - ((signed64) value_vr (SD_, scale, VS, i)
+                  * (signed64) select_vr (SD_, SEL, VT, i))));
+}
+
+
+
+// Load Negative Vector Multiply
+
+010010,5.SEL,5.VT,5.VS,10000,110010::::MULSL.fmt
+"mulsl.%s<SEL> v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              - ((signed64) value_vr (SD_, scale, VS, i)
+                 * (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Nor.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001111::::NOR.fmt
+"nor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             ~(value_vr (SD_, scale, VS, i)
+               | select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Or.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001110::::OR.fmt
+"or.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              | select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Select Vector Elements - False
+
+010010,5.SEL,5.VT,5.VS,5.VD,000010::::PICKF.fmt
+"pickf.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_cc (SD_, i) == 0
+              ? value_vr (SD_, scale, VS, i)
+              : select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Select Vector Elements - True
+
+010010,5.SEL,5.VT,5.VS,5.VD,000011::::PICKT.fmt
+"pickt.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_cc (SD_, i) != 0
+              ? value_vr (SD_, scale, VS, i)
+              : select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Scale, Round and Clamp Accumulator
+
+:%s::::RND:int rnd
+{
+  switch (rnd)
+    {
+    case 0:
+      return "zu";
+    case 1:
+      return "nau";
+    case 2:
+      return "neu";
+    case 4:
+      return "rzs";
+    case 5:
+      return "nas";
+    case 6:
+      return "nes";
+    default:
+      return "(invalid)";
+    }
+}
+
+:function:::signed:ScaleRoundClamp:int scale, int rnd, signed val, signed shift
+{
+  int halfway = (1 << (shift - 1));
+  /* must be positive */
+  if (shift < 0)
+    return 0;
+  /* too much shift? */
+  switch (scale)
+    {
+    case 0:
+      if (shift >= 24)
+       return 0;
+      break;
+    case 1:
+      if (shift >= 48)
+       return 0;
+      break;
+    default:
+      abort ();
+    }
+  /* round */
+  switch (rnd & 3)
+    {
+    case 0: /* round towards zero */
+      break;
+    case 1: /* nearest, halfaway rounds away from zero */
+      if (val >= 0)
+       val += halfway;
+      else
+       val -= halfway;
+      break;
+    case 2: /* nearest, halfway rounds to even! */
+      if (val >= 0)
+       {
+         if (val & (halfway << 1))
+           val += halfway;
+         else
+           val += (halfway - 1);
+       }
+      else
+       {
+         if (val & (halfway << 1))
+           val -= halfway;
+         else
+           val -= (halfway - 1);
+       }
+    default:
+      abort ();
+    }
+  /* shift */
+  val >>= shift;
+  /* clamp */
+  switch (rnd & 4)
+    {
+    case 0:
+      /* unsigned clamp */
+      if (val < 0)
+       val = 0;
+      else
+       switch (scale)
+         {
+         case 0:
+           if (val > 0xff)
+             val = 0xff;
+           break;
+         case 1:
+           if (val > 0xffff)
+             val = 0xffff;
+           break;
+         }
+      break;
+    case 8:
+      /* normal signed clamp */
+      val = Clamp (_SD, scale, val);
+      break;
+    }
+  return val;
+}
+
+010010,5.SEL,5.VT,00000,5.VD,100,3.RND::::Rx.fmt
+"r%s<RND>.%s<SEL> v<VD>, v<VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             ScaleRoundClamp (SD_, scale, RND,
+                              value_acc (SD_, scale, i),
+                              select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Vector Read  Accumulator Low.
+
+010010,0000,1.SEL,00000,00000,5.VD,111111::::RACL.fmt
+"racl.%s<SEL> v<VD>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             EXTRACTED (value_acc (SD_, scale, i),
+                        (8 << scale) - 1,
+                        0));
+}
+
+
+
+// Vector Read  Accumulator Middle.
+
+010010,0100,1.SEL,00000,00000,5.VD,111111::::RACM.fmt
+"racm.%s<SEL> v<VD>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             EXTRACTED (value_acc (SD_, scale, i),
+                        (16 << scale) - 1,
+                        (8 << scale) - 0));
+}
+
+
+
+// Vector Read  Accumulator High.
+
+010010,1000,1.SEL,00000,00000,5.VD,111111::::RACH.fmt
+"rach.%s<SEL> v<VD>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             EXTRACTED (value_acc (SD_, scale, i),
+                        (24 << scale) - 1,
+                        (16 << scale) - 0));
+}
+
+
+
+// Vector Element Shuffle.
+
+010010,0000,0,5.VT,5.VS,5.VD,011111::::SHFL.UPUH.fmt
+"shfl.upuh.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < 4; i++)
+    {
+      store_vr (SD_, 1, VD, i,
+               value_vr (SD_, 0, VS, i + 4) & 0xff);
+    }
+}
+
+010010,0001,0,5.VT,5.VS,5.VD,011111::::SHFL.UPUL.fmt
+"shfl.upul.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  int i;
+  for (i = 0; i < 4; i++)
+    {
+      store_vr (SD_, 1, VD, i,
+               value_vr (SD_, 0, VS, i) & 0xff);
+    }
+}
+
+010010,0000,0,5.VT,5.VS,5.VD,011111::::SHFL.UPSH.fmt
+"shfl.upsh.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < 4; i++)
+    {
+      store_vr (SD_, 1, VD, i,
+               value_vr (SD_, 0, VS, i + 4));
+    }
+}
+
+010010,0001,0,5.VT,5.VS,5.VD,011111::::SHFL.UPSL.fmt
+"shfl.upsl.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  int i;
+  for (i = 0; i < 4; i++)
+    {
+      store_vr (SD_, 1, VD, i,
+               value_vr (SD_, 0, VS, i));
+    }
+}
+
+010010,0100,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.PACH.fmt
+"shfl.pach.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (4 >> scale); i++)
+    {
+      store_vr (SD_, scale, VD, i,
+               value_vr (SD_, scale, VT, i * 2 + 1));
+      store_vr (SD_, scale, VD, 1 + (4 >> scale),
+               value_vr (SD_, scale, VS, i * 2 + 1));
+    }
+}
+
+010010,0101,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.PACL.fmt
+"shfl.pacl.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (4 >> scale); i++)
+    {
+      store_vr (SD_, scale, VD, i,
+               value_vr (SD_, scale, VT, i * 2));
+      store_vr (SD_, scale, VD, 1 + (4 >> scale),
+               value_vr (SD_, scale, VS, i * 2));
+    }
+}
+
+010010,0110,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.MIXH.fmt
+"shfl.mixh.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (4 >> scale); i++)
+    {
+      store_vr (SD_, scale, VD, i * 2,
+               value_vr (SD_, scale, VT, i + (4 >> scale)));
+      store_vr (SD_, scale, VD, i * 2 + 1,
+               value_vr (SD_, scale, VS, i + (4 >> scale)));
+    }
+}
+
+010010,0111,1.SEL,5.VT,5.VS,5.VD,011111::::SHFL.MIXL.fmt
+"shfl.mixl.%s<SEL> v<VD>, v<VS>, <VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (4 >> scale); i++)
+    {
+      store_vr (SD_, scale, VD, i * 2,
+               value_vr (SD_, scale, VT, i));
+      store_vr (SD_, scale, VD, i * 2 + 1,
+               value_vr (SD_, scale, VS, i));
+    }
+}
+
+010010,100,01,5.VT,5.VS,5.VD,011111::::SHFL.BFLA.fmt
+"shfl.bfla.qh v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  store_vr (SD_, 1, VD, 0,
+           value_vr (SD_, 1, VT, 1));
+  store_vr (SD_, 1, VD, 1,
+           value_vr (SD_, 1, VS, 0));
+  store_vr (SD_, 1, VD, 2,
+           value_vr (SD_, 1, VT, 3));
+  store_vr (SD_, 1, VD, 3,
+           value_vr (SD_, 1, VS, 2));
+}
+
+010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.BFLB.fmt
+"shfl.bflb.qh v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  store_vr (SD_, 1, VD, 0,
+           value_vr (SD_, 1, VT, 3));
+  store_vr (SD_, 1, VD, 1,
+           value_vr (SD_, 1, VS, 2));
+  store_vr (SD_, 1, VD, 2,
+           value_vr (SD_, 1, VT, 1));
+  store_vr (SD_, 1, VD, 3,
+           value_vr (SD_, 1, VS, 0));
+}
+
+010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.REPA.fmt
+"shfl.repa.qh v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  store_vr (SD_, 1, VD, 0,
+           value_vr (SD_, 1, VT, 2));
+  store_vr (SD_, 1, VD, 1,
+           value_vr (SD_, 1, VT, 3));
+  store_vr (SD_, 1, VD, 2,
+           value_vr (SD_, 1, VS, 2));
+  store_vr (SD_, 1, VD, 3,
+           value_vr (SD_, 1, VS, 3));
+}
+
+010010,101,01,5.VT,5.VS,5.VD,011111::::SHFL.REPB.fmt
+"shfl.repb.qh v<VD>, v<VS>, <VT>"
+*mdmx:
+{
+  store_vr (SD_, 1, VD, 0,
+           value_vr (SD_, 1, VT, 0));
+  store_vr (SD_, 1, VD, 1,
+           value_vr (SD_, 1, VT, 1));
+  store_vr (SD_, 1, VD, 2,
+           value_vr (SD_, 1, VS, 0));
+  store_vr (SD_, 1, VD, 3,
+           value_vr (SD_, 1, VS, 1));
+}
+
+
+
+// Vector Shift Left Logical
+
+010010,5.SEL,5.VT,5.VS,5.VD,010000::::SLL.fmt
+"sll.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  int mask = (4 << scale) - 1;
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              << (select_vr (SD_, SEL, VT, i) & mask)));
+}
+
+
+
+// Vector Shift Right Arithmetic
+
+010010,5.SEL,5.VT,5.VS,5.VD,010011::::SRA.fmt
+"sra.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+{
+  int i;
+  int mask = (4 << scale) - 1;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              >> (select_vr (SD_, SEL, VT, i) & mask)));
+}
+
+
+
+// Vector Shift Right Logical.
+
+010010,5.SEL,5.VT,5.VS,5.VD,010010::::SRL.fmt
+"srl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  int mask = (4 << scale) - 1;
+  int zeros = (1 << (8 << scale)) - 1;
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             ((value_vr (SD_, scale, VS, i) & zeros)
+              >> (select_vr (SD_, SEL, VT, i) & mask)));
+}
+
+
+
+// Vector Subtract.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001010::::SUB.fmt
+"sub.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              - select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Accumulate Vector Difference
+
+010010,5.SEL,5.VT,5.VS,0,0000,110110::::SUBA.fmt
+"suba.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, VD, i,
+              (value_acc (SD, scale, i)
+               + (signed64) value_vr (SD_, scale, VS, i)
+               - (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Load Vector Difference
+
+010010,5.SEL,5.VT,5.VS,1,0000,110110::::SUBL.fmt
+"subl.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, VD, i,
+              ((signed64) value_vr (SD_, scale, VS, i)
+               - (signed64) select_vr (SD_, SEL, VT, i)));
+}
+
+
+
+// Write Accumulator High.
+
+010010,1000,1.SEL,00000,5.VS,00000,111110::::WACH.fmt
+"wach.%s<SEL> v<VS>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
+               | MASKED (value_acc (SD_, scale, i), (16 << scale) - 1, 0)));
+}
+
+
+
+// Vector Write Accumulator Low.
+
+010010,0000,1.SEL,5.VT,5.VS,00000,111110::::WACL.fmt
+"wacl.%s<SEL> v<VS>, <VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_acc (SD_, scale, i,
+              (((signed64) value_vr (SD_, scale, VS, i) << (16 << scale))
+               | MASKED (value_vr (SD_, scale, VT, i),
+                         (16 << scale) - 1, 0)));
+}
+
+
+
+// Vector Xor.
+
+010010,5.SEL,5.VT,5.VS,5.VD,001101::::XOR.fmt
+"xor.%s<SEL> v<VD>, v<VS>, %s<VT#SEL,VT>"
+*mdmx:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  int i;
+  int scale = get_scale (SD_, SEL);
+  for (i = 0; i < (8 >> scale); i++)
+    store_vr (SD_, scale, VD, i,
+             (value_vr (SD_, scale, VS, i)
+              ^ select_vr (SD_, SEL, VT, i)));
+}
diff --git a/sim/txvu/mips.dc b/sim/txvu/mips.dc
new file mode 100644 (file)
index 0000000..98da024
--- /dev/null
@@ -0,0 +1,16 @@
+# most instructions
+# ------ options ------ : Fst : Lst : ff : fl : fe : word : --- fmt --- : model ...
+# { : mask : value : word }
+
+# Top level - create a very big switch statement.
+
+  padded-switch,combine :  31 :  26 :    :    :    :      :             :
+
+  switch,combine        :   5 :   0 :    :    :    :      :             :
+
+  switch,combine        :  20 :  16 :    :    :    :      :             :
+
+  switch,combine        :  25 :  21 :    :    :    :      :             :
+
+  switch,combine        :  10 :   6 :    :    :    :      :             :
+
diff --git a/sim/txvu/mips.igen b/sim/txvu/mips.igen
new file mode 100644 (file)
index 0000000..bfe9430
--- /dev/null
@@ -0,0 +1,5209 @@
+//    <insn> ::=
+//        <insn-word> { "+" <insn-word> }
+//        ":" <format-name>
+//        ":" <filter-flags>
+//        ":" <options>
+//        ":" <name>
+//        <nl>
+//        { <insn-model> }
+//        { <insn-mnemonic> }
+//        <code-block>
+//
+
+
+// IGEN config - mips16
+:option:16::insn-bit-size:16
+:option:16::hi-bit-nr:15
+:option:16::insn-specifying-widths:true
+:option:16::gen-delayed-branch:false
+
+// IGEN config - mips32/64..
+:option:32::insn-bit-size:32
+:option:32::hi-bit-nr:31
+:option:32::insn-specifying-widths:true
+:option:32::gen-delayed-branch:false
+
+
+// Generate separate simulators for each target
+// :option:::multi-sim:true
+
+
+// Models known by this simulator
+:model:::mipsI:mipsI:
+:model:::mipsII:mipsII:
+:model:::mipsIII:mipsIII:
+:model:::mipsIV:mipsIV:
+:model:::mips16:mips16:
+// start-sanitize-r5900
+:model:::r5900:r5900:
+// end-sanitize-r5900
+:model:::r3900:r3900:
+// start-sanitize-tx19
+:model:::tx19:tx19:
+// end-sanitize-tx19
+// start-sanitize-vr5400
+:model:::vr5400:vr5400:
+:model:::mdmx:mdmx:
+// end-sanitize-vr5400
+:model:::vr5000:vr5000:
+
+
+
+// Pseudo instructions known by IGEN
+:internal::::illegal:
+{
+  SignalException (ReservedInstruction, 0);
+}
+
+
+// Pseudo instructions known by interp.c
+// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
+000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD
+"rsvd <OP>"
+{
+  SignalException (ReservedInstruction, instruction_0);
+}
+
+
+
+//
+// Mips Architecture:
+//
+//        CPU Instruction Set (mipsI - mipsIV)
+//
+
+
+000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD
+"add r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU32_BEGIN (GPR[RS]);
+  ALU32_ADD (GPR[RT]);
+  ALU32_END (GPR[RD]);
+}
+
+
+001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI
+"addi r<RT>, r<RS>, IMMEDIATE"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU32_BEGIN (GPR[RS]);
+  ALU32_ADD (EXTEND16 (IMMEDIATE));
+  ALU32_END (GPR[RT]);
+}
+
+
+001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU
+"add r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  signed32 temp = GPR[RS] + EXTEND16 (IMMEDIATE);
+  GPR[RT] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  signed32 temp = GPR[RS] + GPR[RT];
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND
+"and r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = GPR[RS] & GPR[RT];
+}
+
+
+001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI
+"and r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = GPR[RS] & IMMEDIATE;
+}
+
+
+000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ
+"beq r<RS>, r<RT>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+    DELAY_SLOT (NIA + offset);
+}
+
+
+010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL
+"beql r<RS>, r<RT>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ
+"bgez r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] >= 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL
+"bgezal r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  RA = (CIA + 8);
+  if ((signed_word) GPR[RS] >= 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL
+"bgezall r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  RA = (CIA + 8);
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] >= 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL
+"bgezl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] >= 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ
+"bgtz r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] > 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL
+"bgtzl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] > 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ
+"blez r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] <= 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL
+"bgezl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] <= 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ
+"bltz r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] < 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL
+"bltzal r<RS>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  RA = (CIA + 8);
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] < 0)
+    DELAY_SLOT (NIA + offset);
+}
+
+
+000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL
+"bltzall r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  RA = (CIA + 8);
+  if ((signed_word) GPR[RS] < 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL
+"bltzl r<RS>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  /* NOTE: The branch occurs AFTER the next instruction has been
+     executed */
+  if ((signed_word) GPR[RS] < 0)
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE
+"bne r<RS>, r<RT>, <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+    DELAY_SLOT (NIA + offset);
+}
+
+
+010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL
+"bnel r<RS>, r<RT>, <OFFSET>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word offset = EXTEND16 (OFFSET) << 2;
+  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+    DELAY_SLOT (NIA + offset);
+  else
+    NULLIFY_NEXT_INSTRUCTION ();
+}
+
+
+000000,20.CODE,001101:SPECIAL:32::BREAK
+"break"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  SignalException(BreakPoint, instruction_0);
+}
+
+
+0100,ZZ!0!1!3,26.COP_FUN:NORMAL:32::COPz
+"cop<ZZ> <COP_FUN>"
+*mipsI,mipsII,mipsIII,mipsIV:
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  DecodeCoproc (instruction_0);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD
+"dadd r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU64_BEGIN (GPR[RS]);
+  ALU64_ADD (GPR[RT]);
+  ALU64_END (GPR[RT]);
+}
+
+
+011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI
+"daddi r<RT>, r<RS>, <IMMEDIATE>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU64_BEGIN (GPR[RS]);
+  ALU64_ADD (EXTEND16 (IMMEDIATE));
+  ALU64_END (GPR[RT]);
+}
+
+
+011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU
+"daddu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = GPR[RS] + EXTEND16 (IMMEDIATE);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU
+"daddu r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = GPR[RS] + GPR[RT];
+}
+
+
+000000,5.RS,5.RT,0000000000011110:SPECIAL:64::DDIV
+"ddiv r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  CHECKHILO ("Division");
+  {
+    signed64 n = GPR[RS];
+    signed64 d = GPR[RT];
+    if (d == 0)
+      {
+       LO = SIGNED64 (0x8000000000000000);
+       HI = 0;
+      }
+    else if (d == -1 && n == SIGNED64 (0x8000000000000000))
+      {
+       LO = SIGNED64 (0x8000000000000000);
+       HI = 0;
+      }
+    else
+      {
+       LO = (n / d);
+       HI = (n % d);
+      }
+  }
+}
+
+
+
+000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU
+"ddivu r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*r3900:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  CHECKHILO ("Division");
+  {
+    unsigned64 n = GPR[RS];
+    unsigned64 d = GPR[RT];
+    if (d == 0)
+      {
+       LO = SIGNED64 (0x8000000000000000);
+       HI = 0;
+      }
+    else
+      {
+       LO = (n / d);
+       HI = (n % d);
+      }
+  }
+}
+
+
+000000,5.RS,5.RT,0000000000011010:SPECIAL:32::DIV
+"div r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  CHECKHILO("Division");
+  {
+    signed32 n = GPR[RS];
+    signed32 d = GPR[RT];
+    if (d == 0)
+      {
+       LO = EXTEND32 (0x80000000);
+       HI = EXTEND32 (0);
+      }
+    else if (d == -1 && d == 0x80000000)
+      {
+       LO = EXTEND32 (0x80000000);
+       HI = EXTEND32 (0);
+      }
+    else
+      {
+       LO = EXTEND32 (n / d);
+       HI = EXTEND32 (n % d);
+      }
+  }
+}
+
+
+000000,5.RS,5.RT,0000000000011011:SPECIAL:32::DIVU
+"divu r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  CHECKHILO ("Division");
+  {
+    unsigned32 n = GPR[RS];
+    unsigned32 d = GPR[RT];
+    if (d == 0)
+      {
+       LO = EXTEND32 (0x80000000);
+       HI = EXTEND32 (0);
+      }
+   else
+     {
+       LO = EXTEND32 (n / d);
+       HI = EXTEND32 (n % d);
+     }
+  }
+}
+
+
+:function:::void:do_dmult:int rs, int rt, int rd, int signed_p
+{
+  unsigned64 lo;
+  unsigned64 hi;
+  unsigned64 m00;
+  unsigned64 m01;
+  unsigned64 m10;
+  unsigned64 m11;
+  unsigned64 mid;
+  int sign;
+  unsigned64 op1 = GPR[rs];
+  unsigned64 op2 = GPR[rt];
+  CHECKHILO ("Multiplication");
+  /* make signed multiply unsigned */ 
+  sign = 0;
+  if (signed_p)
+    {
+      if (op1 < 0)
+       {
+         op1 = - op1;
+         ++sign;
+       }
+      if (op2 < 0)
+       {
+         op2 = - op2;
+         ++sign;
+       }
+    }
+  /* multuply out the 4 sub products */
+  m00 = ((unsigned64) VL4_8 (op1) * (unsigned64) VL4_8 (op2));
+  m10 = ((unsigned64) VH4_8 (op1) * (unsigned64) VL4_8 (op2));
+  m01 = ((unsigned64) VL4_8 (op1) * (unsigned64) VH4_8 (op2));
+  m11 = ((unsigned64) VH4_8 (op1) * (unsigned64) VH4_8 (op2));
+  /* add the products */
+  mid = ((unsigned64) VH4_8 (m00)
+        + (unsigned64) VL4_8 (m10)
+        + (unsigned64) VL4_8 (m01));
+  lo = U8_4 (mid, m00);
+  hi = (m11
+       + (unsigned64) VH4_8 (mid)
+       + (unsigned64) VH4_8 (m01)
+       + (unsigned64) VH4_8 (m10));
+  /* fix the sign */
+  if (sign & 1)
+    {
+      lo = -lo;
+      if (lo == 0)
+       hi = -hi;
+      else
+       hi = -hi - 1;
+    }
+  /* save the result HI/LO (and a gpr) */
+  LO = lo;
+  HI = hi;
+  if (rd != 0)
+    GPR[rd] = lo;
+}
+
+
+000000,5.RS,5.RT,0000000000011100:SPECIAL:64::DMULT
+"dmult r<RS>, r<RT>"
+*mipsIII,mipsIV:
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  do_dmult (SD_, RS, RT, 0, 1);
+}
+
+000000,5.RS,5.RT,5.RD,00000011100:SPECIAL:64::DMULT
+"dmult r<RS>, r<RT>":RD == 0
+"dmult r<RD>, r<RS>, r<RT>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  do_dmult (SD_, RS, RT, RD, 1);
+}
+
+
+
+000000,5.RS,5.RT,0000000000011101:SPECIAL:64::DMULTU
+"dmultu r<RS>, r<RT>"
+*mipsIII,mipsIV:
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  do_dmult (SD_, RS, RT, 0, 0);
+}
+
+000000,5.RS,5.RT,5.RD,00000011101:SPECIAL:64::DMULTU
+"dmultu r<RD>, r<RS>, r<RT>":RD == 0
+"dmultu r<RS>, r<RT>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  do_dmult (SD_, RS, RT, RD, 0);
+}
+
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111000:SPECIAL:64::DSLL
+"dsll r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  GPR[RD] = GPR[RT] << s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111100:SPECIAL:64::DSLL32
+"dsll32 r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = 32 + SHIFT;
+  GPR[RD] = GPR[RT] << s;
+}
+
+
+000000,5.RS,5.RT,5.RD,00000010100:SPECIAL:64::DSLLV
+"dsllv r<RD>, r<RT>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED64 (GPR[RS], 5, 0);
+  GPR[RD] = GPR[RT] << s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111011:SPECIAL:64::DSRA
+"dsra r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  GPR[RD] = ((signed64) GPR[RT]) >> s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111111:SPECIAL:64::DSRA32
+"dsra32 r<RT>, r<RD>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = 32 + SHIFT;
+  GPR[RD] = ((signed64) GPR[RT]) >> s;
+}
+
+
+000000,5.RS,5.RT,5.RD,00000010111:SPECIAL:64::DSRAV
+"dsra32 r<RT>, r<RD>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED64 (GPR[RS], 5, 0);
+  GPR[RD] = ((signed64) GPR[RT]) >> s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111010:SPECIAL:64::DSRL
+"dsrav r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  GPR[RD] = (unsigned64) GPR[RT] >> s;
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,111110:SPECIAL:64::DSRL32
+"dsrl32 r<RD>, r<RT>, <SHIFT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = 32 + SHIFT;
+  GPR[RD] = (unsigned64) GPR[RT] >> s;
+}
+
+
+000000,5.RS,5.RT,5.RD,00000010110:SPECIAL:64::DSRLV
+"dsrl32 r<RD>, r<RT>, r<RS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED64 (GPR[RS], 5, 0);
+  GPR[RD] = (unsigned64) GPR[RT] >> s;
+}
+
+
+000000,5.RS,5.RT,5.RD,00000101110:SPECIAL:64::DSUB
+"dsub r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU64_BEGIN (GPR[RS]);
+  ALU64_SUB (GPR[RT]);
+  ALU64_END (GPR[RD]);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000101111:SPECIAL:64::DSUBU
+"dsubu r<RD>, r<RS>, r<RT>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = GPR[RS] - GPR[RT];
+}
+
+
+000010,26.INSTR_INDEX:NORMAL:32::J
+"j <INSTR_INDEX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  /* NOTE: The region used is that of the delay slot NIA and NOT the
+     current instruction */
+  address_word region = (NIA & MASK (63, 28));
+  DELAY_SLOT (region | (INSTR_INDEX << 2));
+}
+
+
+000011,26.INSTR_INDEX:NORMAL:32::JAL
+"jal <INSTR_INDEX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  /* NOTE: The region used is that of the delay slot and NOT the
+     current instruction */
+  address_word region = (NIA & MASK (63, 28));
+  GPR[31] = CIA + 8;
+  DELAY_SLOT (region | (INSTR_INDEX << 2));
+}
+
+
+000000,5.RS,00000,5.RD,00000001001:SPECIAL:32::JALR
+"jalr r<RS>":RD == 31
+"jalr r<RD>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word temp = GPR[RS];
+  GPR[RD] = CIA + 8;
+  DELAY_SLOT (temp);
+}
+
+
+000000,5.RS,000000000000000001000:SPECIAL:32::JR
+"jr r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  DELAY_SLOT (GPR[RS]);
+}
+
+
+100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB
+"lb r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((uword64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         uword64 memval = 0;
+         uword64 memval1 = 0;
+         uword64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL);
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x000000FF),8));
+       }
+    }
+  }
+}
+
+
+100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU
+"lbu r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL);
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         GPR[destreg] = (((memval >> (8 * byte)) & 0x000000FF));
+       }
+    }
+  }
+}
+
+
+110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD
+"ld r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+         }
+      }
+  }
+}
+
+
+1101,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz
+"ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           COP_LD(((instruction >> 26) & 0x3),destreg,memval);;
+         }
+      }
+  }
+}
+
+
+011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL
+"ldl r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 7;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (!BigEndianMem)
+           paddr &= ~mask;
+         LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL);
+         GPR[destreg] = ((memval << ((7 - byte) * 8)) | (GPR[destreg] & (((unsigned64)1 << ((7 - byte) * 8)) - 1)));
+       }
+    }
+  }
+}
+
+
+011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR
+"ldr r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 7;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (BigEndianMem)
+           paddr &= ~mask;
+         LoadMemory(&memval,&memval1,uncached,(7 - byte),paddr,vaddr,isDATA,isREAL);
+         {
+           unsigned64 srcmask;
+           if (byte == 0)
+             srcmask = 0;
+           else
+             srcmask = ((unsigned64)-1 << (8 * (8 - byte)));
+           GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));
+         }
+       }
+    }
+  }
+}
+
+
+100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH
+"lh r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x0000FFFF),16));
+         }
+      }
+  }
+}
+
+
+100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU
+"lhu r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (((memval >> (8 * byte)) & 0x0000FFFF));
+         }
+      }
+  }
+}
+
+
+110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL
+"ll r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+           LLBIT = 1;
+         }
+      }
+  }
+}
+
+
+110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD
+"lld r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+           LLBIT = 1;
+         }
+      }
+  }
+}
+
+
+001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI
+"lui r<RT>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = EXTEND32 (IMMEDIATE << 16);
+}
+
+
+100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW
+"lw r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32));
+         }
+      }
+  }
+}
+
+
+1100,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz
+"lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)((memval >> (8 * byte)) & 0xFFFFFFFF));
+         }
+      }
+  }
+}
+
+
+100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL
+"lwl r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 3;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (!BigEndianMem)
+           paddr &= ~mask;
+         LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL);
+         if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {
+           memval >>= 32;
+         }
+         GPR[destreg] = ((memval << ((3 - byte) * 8)) | (GPR[destreg] & (((unsigned64)1 << ((3 - byte) * 8)) - 1)));
+         GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+       }
+    }
+  }
+}
+
+
+100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR
+"lwr r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 3;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (BigEndianMem)
+           paddr &= ~mask;
+         LoadMemory(&memval,&memval1,uncached,(3 - byte),paddr,vaddr,isDATA,isREAL);
+         if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {
+           memval >>= 32;
+         }
+         {
+           unsigned64 srcmask;
+           if (byte == 0)
+             srcmask = 0;
+           else
+             srcmask = ((unsigned64)-1 << (8 * (4 - byte)));
+           GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));
+         }
+         GPR[destreg] = SIGNEXTEND(GPR[destreg],32);
+       }
+    }
+  }
+}
+
+
+100111,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWU
+"lwu r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           GPR[destreg] = (((memval >> (8 * byte)) & 0xFFFFFFFF));
+         }
+      }
+  }
+}
+
+
+000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI
+"mfhi r<RD>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = HI;
+#if 0
+  HIACCESS = 3;
+#endif
+}
+
+
+000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO
+"mflo r<RD>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = LO;
+#if 0
+  LOACCESS = 3; /* 3rd instruction will be safe */
+#endif
+}
+
+
+000000,5.RS,5.RT,5.RD,00000001011:SPECIAL:32::MOVN
+"movn r<RD>, r<RS>, r<RT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  if (GPR[RT] != 0)
+    GPR[RD] = GPR[RS];
+}
+
+
+000000,5.RS,5.RT,5.RD,00000001010:SPECIAL:32::MOVZ
+"movz r<RD>, r<RS>, r<RT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  if (GPR[RT] == 0)
+    GPR[RD] = GPR[RS];
+}
+
+
+000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI
+"mthi r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+#if 0
+  if (HIACCESS != 0)
+    sim_io_eprintf (sd, "MT (move-to) over-writing HI register value\n");
+#endif
+  HI = GPR[RS];
+#if 0
+  HIACCESS = 3; /* 3rd instruction will be safe */
+#endif
+}
+
+
+000000,5.RS,000000000000000010011:SPECIAL:32::MTLO
+"mtlo r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+#if 0
+  if (LOACCESS != 0)
+    sim_io_eprintf (sd, "MT (move-to) over-writing LO register value\n");
+#endif
+  LO = GPR[RS];
+#if 0
+  LOACCESS = 3; /* 3rd instruction will be safe */
+#endif
+}
+
+
+000000,5.RS,5.RT,00000,00000011000:SPECIAL:32::MULT
+"mult r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+{
+  signed64 prod;
+  CHECKHILO ("Multiplication");
+  prod = (((signed64)(signed32) GPR[RS])
+         * ((signed64)(signed32) GPR[RT]));
+  LO = EXTEND32 (VL4_8 (prod));
+  HI = EXTEND32 (VH4_8 (prod));
+}
+000000,5.RS,5.RT,5.RD,00000011000:SPECIAL:32::MULT
+"mult r<RD>, r<RS>, r<RT>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  signed64 prod;
+  CHECKHILO ("Multiplication");
+  prod = (((signed64)(signed32) GPR[RS])
+         * ((signed64)(signed32) GPR[RT]));
+  LO = EXTEND32 (VL4_8 (prod));
+  HI = EXTEND32 (VH4_8 (prod));
+  if (RD != 0)
+    GPR[RD] = LO;
+}
+
+
+000000,5.RS,5.RT,00000,00000011001:SPECIAL:32::MULTU
+"multu r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+{
+  unsigned64 prod;
+  CHECKHILO ("Multiplication");
+  prod = (((unsigned64)(unsigned32) GPR[RS])
+         * ((unsigned64)(unsigned32) GPR[RT]));
+  LO = EXTEND32 (VL4_8 (prod));
+  HI = EXTEND32 (VH4_8 (prod));
+}
+000000,5.RS,5.RT,5.RD,00000011001:SPECIAL:32::MULTU
+"multu r<RD>, r<RS>, r<RT>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned64 prod;
+  CHECKHILO ("Multiplication");
+  prod = (((unsigned64)(unsigned32) GPR[RS])
+         * ((unsigned64)(unsigned32) GPR[RT]));
+  LO = EXTEND32 (VL4_8 (prod));
+  HI = EXTEND32 (VH4_8 (prod));
+  if (RD != 0)
+    GPR[RD] = LO;
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR
+"nor r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = ~ (GPR[RS] | GPR[RT]);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR
+"or r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = (GPR[RS] | GPR[RT]);
+}
+
+
+001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI
+"ori r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = (GPR[RS] | IMMEDIATE);
+}
+
+
+110011,5.RS,nnnnn,16.OFFSET:NORMAL:32::PREF
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int hint = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+       Prefetch(uncached,paddr,vaddr,isDATA,hint);
+    }
+  }
+}
+
+101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB
+"sb r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 0x7;
+         unsigned int shift = 0;
+         unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+         unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+         unsigned int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+         byte = ((vaddr & mask) ^ (bigend << shift));
+         memval = ((unsigned64) op2 << (8 * byte));
+         {
+           StoreMemory(uncached,AccessLength_BYTE,memval,memval1,paddr,vaddr,isREAL);
+         }
+       }
+    }
+  }
+}
+
+
+111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC
+"sc r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = ((unsigned64) op2 << (8 * byte));
+           if (LLBIT)
+             {
+               StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+             }
+           GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
+         }
+      }
+  }
+}
+
+
+111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD
+"scd r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = op2;
+           if (LLBIT)
+             {
+               StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+             }
+           GPR[(instruction >> 16) & 0x0000001F] = LLBIT;
+         }
+      }
+  }
+}
+
+
+111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD
+"sd r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = op2;
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+1111,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz
+"sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = (unsigned64)COP_SD(((instruction >> 26) & 0x3),destreg);
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL
+"sdl r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 7;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (!BigEndianMem)
+           paddr &= ~mask;
+         memval = (op2 >> (8 * (7 - byte)));
+         StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL);
+       }
+    }
+  }
+}
+
+
+101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR
+"sdr r<RT>, <OFFSET>(r<BASE>)"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word paddr;
+  int uncached;
+  unsigned64 memval;
+  unsigned64 mask = 7;
+  unsigned int reverse = (ReverseEndian ? mask : 0);
+  unsigned int bigend = (BigEndianCPU ? mask : 0);
+  int byte;
+  address_word vaddr = (GPR[BASE] + EXTEND16 (OFFSET));
+  AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL);
+  paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+  if (BigEndianMem)
+    paddr &= ~mask;
+  byte = ((vaddr & mask) ^ bigend);
+  memval = (GPR[RT] << (byte * 8));
+  StoreMemory(uncached,(AccessLength_DOUBLEWORD - byte),memval,0,paddr,vaddr,isREAL);
+}
+
+
+101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH
+"sh r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 1) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 1;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_HALFWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+00000000000,5.RT,5.RD,5.SHIFT,000000:SPECIAL:32::SLL
+"sll r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  unsigned32 temp = (GPR[RT] << s);
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000000100:SPECIAL:32::SLLV
+"sllv r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED (GPR[RS], 4, 0);
+  unsigned32 temp = (GPR[RT] << s);
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000101010:SPECIAL:32::SLT
+"slt r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = ((signed_word) GPR[RS] < (signed_word) GPR[RT]);
+}
+
+
+001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI
+"slti r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE));
+}
+
+
+001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU
+"sltiu r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE));
+}
+
+000000,5.RS,5.RT,5.RD,00000101011:SPECIAL:32::SLTU
+"sltu r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT]);
+}
+
+
+000000,00000,5.RT,5.RD,5.SHIFT,000011:SPECIAL:32::SRA
+"sra r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  signed32 temp = (signed32) GPR[RT] >> s;
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000000111:SPECIAL:32::SRAV
+"srav r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED (GPR[RS], 4, 0);
+  signed32 temp = (signed32) GPR[RT] >> s;
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,00000,5.RT,5.RD,5.SHIFT,000010:SPECIAL:32::SRL
+"srl r<RD>, r<RT>, <SHIFT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = SHIFT;
+  unsigned32 temp = (unsigned32) GPR[RT] >> s;
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000000110:SPECIAL:32::SRLV
+"srlv r<RD>, r<RT>, r<RS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  int s = MASKED (GPR[RS], 4, 0);
+  unsigned32 temp = (unsigned32) GPR[RT] >> s;
+  GPR[RD] = EXTEND32 (temp);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000100010:SPECIAL:32::SUB
+"sub r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  ALU32_BEGIN (GPR[RS]);
+  ALU32_SUB (GPR[RT]);
+  ALU32_END (GPR[RD]);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000100011:SPECIAL:32::SUBU
+"subu r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = EXTEND32 (GPR[RS] - GPR[RT]);
+}
+
+
+101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW
+"sw r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = ((unsigned64) op2 << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+1110,ZZ!0!1!3,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWCz
+"swc<ZZ> r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = (((unsigned64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL
+"swl r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+       {
+         unsigned64 memval = 0;
+         unsigned64 memval1 = 0;
+         unsigned64 mask = 3;
+         unsigned int reverse = (ReverseEndian ? mask : 0);
+         unsigned int bigend = (BigEndianCPU ? mask : 0);
+         int byte;
+         paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+         byte = ((vaddr & mask) ^ bigend);
+         if (!BigEndianMem)
+           paddr &= ~mask;
+         memval = (op2 >> (8 * (3 - byte)));
+         if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {
+           memval <<= 32;
+         }
+         StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL);
+       }
+    }
+  }
+}
+
+
+101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR
+"swr r<RT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned64 memval = 0;
+  unsigned64 mask = 3;
+  unsigned int reverse = (ReverseEndian ? mask : 0);
+  unsigned int bigend = (BigEndianCPU ? mask : 0);
+  int byte;
+  address_word paddr;
+  int uncached;
+  address_word vaddr = (GPR[BASE] + EXTEND16 (OFFSET));
+  AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL);
+  paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));
+  if (BigEndianMem)
+    paddr &= ~mask;
+  byte = ((vaddr & mask) ^ bigend);
+  memval = (GPR[RT] << (byte * 8));
+  if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2))
+    memval <<= 32;
+  StoreMemory(uncached,(AccessLength_WORD - byte),memval,0,paddr,vaddr,isREAL);
+}
+
+
+000000000000000000000,5.STYPE,001111:SPECIAL:32::SYNC
+"sync":STYPE == 0
+"sync <STYPE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  SyncOperation (STYPE);
+}
+
+
+000000,20.CODE,001100:SPECIAL:32::SYSCALL
+"syscall <CODE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  SignalException(SystemCall, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ
+"teq r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] == (signed_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI
+"teqi r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] == (signed_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE
+"tge r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI
+"tgei r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] >= (signed_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU
+"tgeiu r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((unsigned_word) GPR[RS] >= (unsigned_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU
+"tgeu r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((unsigned_word) GPR[RS] >= (unsigned_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT
+"tlt r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI
+"tlti r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] < (signed_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU
+"tltiu r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((unsigned_word) GPR[RS] < (unsigned_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU
+"tltu r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE
+"tne r<RS>, r<RT>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] != (signed_word) GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+
+000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI
+"tne r<RS>, <IMMEDIATE>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if ((signed_word) GPR[RS] != (signed_word) EXTEND16 (IMMEDIATE))
+    SignalException(Trap, instruction_0);
+}
+
+
+000000,5.RS,5.RT,5.RD,00000100110:SPECIAL:32::XOR
+"xor r<RD>, r<RS>, r<RT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RD] = GPR[RS] ^ GPR[RT];
+}
+
+
+001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI
+"xori r<RT>, r<RS>, <IMMEDIATE>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  GPR[RT] = GPR[RS] ^ IMMEDIATE;
+}
+
+\f
+//
+// MIPS Architecture:
+//
+//        FPU Instruction Set (COP1 & COP1X)
+//
+
+
+:%s::::FMT:int fmt
+{
+  switch (fmt)
+    {
+    case fmt_single: return "s";
+    case fmt_double: return "d";
+    case fmt_word: return "w";
+    case fmt_long: return "l";
+    default: return "?";
+    }
+}
+
+:%s::::X:int x
+{
+  switch (x)
+    {
+    case 0: return "f";
+    case 1: return "t";
+    default: return "?";
+    }
+}
+
+:%s::::TF:int tf
+{
+  if (tf)
+    return "t";
+  else
+    return "f";
+}
+
+:%s::::ND:int nd
+{
+  if (nd)
+    return "l";
+  else
+    return "";
+}
+
+:%s::::COND:int cond
+{
+  switch (cond)
+    {
+    case 00: return "f";
+    case 01: return "un";
+    case 02: return "eq";
+    case 03: return "ueq";
+    case 04: return "olt";
+    case 05: return "ult";
+    case 06: return "ole";
+    case 07: return "ule";
+    case 010: return "sf";
+    case 011: return "ngle";
+    case 012: return "seq";
+    case 013: return "ngl";
+    case 014: return "lt";
+    case 015: return "nge";
+    case 016: return "le";
+    case 017: return "ngt";
+    default: return "?";
+    }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt
+"abs.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));
+  }
+}
+
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000000:COP1:32,f::ADD
+"add.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction, instruction);
+    else
+      StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));
+  }
+}
+
+
+
+// BC1F
+// BC1FL
+// BC1T
+// BC1TL
+
+010001,01000,3.0,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1
+"bc1%s<TF>%s<ND> <OFFSET>"
+*mipsI,mipsII,mipsIII:
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  if (PREVCOC1() == TF)
+    {
+      DELAY_SLOT (NIA + (EXTEND16 (OFFSET) << 2));
+    }
+  else if (ND)
+    {
+      NULLIFY_NEXT_INSTRUCTION ();
+    }
+}
+
+010001,01000,3.CC,1.ND,1.TF,16.OFFSET:COP1S:32,f::BC1
+"bc1%s<TF>%s<ND> <OFFSET>":CC == 0
+"bc1%s<TF>%s<ND> <CC>, <OFFSET>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if (GETFCC(CC) == TF)
+    {
+      DELAY_SLOT (NIA + (EXTEND16 (OFFSET) << 2));
+    }
+  else if (ND)
+    {
+      NULLIFY_NEXT_INSTRUCTION ();
+    }
+}
+
+
+
+// C.EQ.S
+// C.EQ.D
+// ...
+
+:function:::void:do_c_cond_fmt:int fmt, int ft, int fs, int cc, int cond, instruction_word insn
+{
+  if ((fmt != fmt_single) && (fmt != fmt_double))
+    SignalException (ReservedInstruction, insn);
+  else
+    {
+      int less;
+      int equal;
+      int unordered;
+      int condition;
+      unsigned64 ofs = ValueFPR (fs, fmt);
+      unsigned64 oft = ValueFPR (ft, fmt);
+      if (NaN (ofs, fmt) || NaN (oft, fmt))
+       {
+         if (FCSR & FP_ENABLE (IO))
+           {
+             FCSR |= FP_CAUSE (IO);
+             SignalExceptionFPE ();
+           }
+         less = 0;
+         equal = 0;
+         unordered = 1;
+       }
+      else
+       {
+         less = Less (ofs, oft, fmt);
+         equal = Equal (ofs, oft, fmt);
+         unordered = 0;
+       }
+      condition = (((cond & (1 << 2)) && less)
+                  || ((cond & (1 << 1)) && equal)
+                  || ((cond & (1 << 0)) && unordered));
+      SETFCC (cc, condition);
+    }
+}
+
+010001,10,3.FMT,5.FT,5.FS,3.0,00,11,4.COND:COP1:32::C.cond.fmt
+*mipsI,mipsII,mipsIII:
+"c.%s<COND>.%s<FMT> f<FS>, f<FT>":
+{
+  do_c_cond_fmt (SD_, FMT, FT, FS, 0, COND, instruction_0);
+}
+
+010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32::C.cond.fmt
+"c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0
+"c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  do_c_cond_fmt (SD_, FMT, FT, FS, CC, COND, instruction_0);
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64::CEIL.L.fmt
+"ceil.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32::CEIL.W
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word));
+  }
+}
+
+
+// CFC1
+// CTC1
+010001,00,X,10,5.RT,5.FS,00000000000:COP1S:32::CxC1
+"c%s<X>c1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{
+  if (X)
+    {
+      if (FS == 0)
+       PENDING_FILL((FS + FCR0IDX),VL4_8(GPR[RT]));
+      else if (FS == 31)
+       PENDING_FILL((FS + FCR31IDX),VL4_8(GPR[RT]));
+      /* else NOP */
+      PENDING_FILL(COCIDX,0); /* special case */
+    }
+  else
+    { /* control from */
+      if (FS == 0)
+       PENDING_FILL(RT,SIGNEXTEND(FCR0,32));
+      else if (FS == 31)
+       PENDING_FILL(RT,SIGNEXTEND(FCR31,32));
+      /* else NOP */
+    }
+}
+010001,00,X,10,5.RT,5.FS,00000000000:COP1S:32::CxC1
+"c%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if (X)
+    {
+      if (FS == 0)
+       FCR0 = VL4_8(GPR[RT]);
+      else if (FS == 31)
+       FCR31 = VL4_8(GPR[RT]);
+      /* else NOP */
+      SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0));
+    }
+  else
+    { /* control from */
+      if (FS == 0)
+       GPR[RT] = SIGNEXTEND (FCR0, 32);
+      else if (FS == 31)
+       GPR[RT] = SIGNEXTEND (FCR31, 32);
+      /* else NOP */
+    }
+}
+
+
+//
+// FIXME: Does not correctly differentiate between mips*
+//
+010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32::CVT.D.fmt
+"cvt.d.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format == fmt_double) | 0)
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64::CVT.L.fmt
+"cvt.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word)))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long));
+  }
+}
+
+
+//
+// FIXME: Does not correctly differentiate between mips*
+//
+010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32::CVT.S.fmt
+"cvt.s.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format == fmt_single) | 0)
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32::CVT.W.fmt
+"cvt.w.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word)))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word));
+  }
+}
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32::DIV.fmt
+"div.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));
+  }
+}
+
+
+// DMFC1
+// DMTC1
+010001,00,X,01,5.RT,5.FS,00000000000:COP1S:64::DMxC1
+"dm%s<X>c1 r<RT>, f<FS>"
+*mipsIII:
+{
+  if (X)
+    {
+      if (SizeFGR() == 64)
+       PENDING_FILL((FS + FGRIDX),GPR[RT]);
+      else if ((FS & 0x1) == 0)
+       {
+         PENDING_FILL(((FS + 1) + FGRIDX),VH4_8(GPR[RT]));
+         PENDING_FILL((FS + FGRIDX),VL4_8(GPR[RT]));
+       }
+    }
+  else
+    {
+      if (SizeFGR() == 64)
+       PENDING_FILL(RT,FGR[FS]);
+      else if ((FS & 0x1) == 0)
+       PENDING_FILL(RT,(SET64HI(FGR[FS+1]) | FGR[FS]));
+      else
+       PENDING_FILL(RT,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);
+    }
+}
+010001,00,X,01,5.RT,5.FS,00000000000:COP1S:64::DMxC1
+"dm%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if (X)
+    {
+      if (SizeFGR() == 64)
+       StoreFPR (FS, fmt_uninterpreted_64, GPR[RT]);
+      else if ((FS & 0x1) == 0)
+       StoreFPR (FS, fmt_uninterpreted_64, SET64HI (FGR[FS+1]) | FGR[FS]);
+    }
+  else
+    {
+      if (SizeFGR() == 64)
+       GPR[RT] = FGR[FS];
+      else if ((FS & 0x1) == 0)
+       GPR[RT] = SET64HI (FGR[FS+1]) | FGR[FS];
+      else
+       GPR[RT] = SET64HI (0xDEADC0DE) | 0xBAD0BAD0;
+    }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64::FLOOR.L.fmt
+"floor.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32::FLOOR.W.fmt
+"floor.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word));
+  }
+}
+
+
+110101,5.BASE,5.FT,16.OFFSET:COP1:64::LDC1
+"ldc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word vaddr = GPR[BASE] + EXTEND16 (OFFSET);
+  address_word paddr;
+  int uncached;
+  if ((vaddr & 7) != 0)
+    SignalExceptionAddressLoad();
+  else
+    {
+      unsigned64 memval;
+      AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL);
+      LoadMemory(&memval,0,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+      COP_LD(((instruction_0 >> 26) & 0x3),FT,memval);;
+    }
+}
+
+
+010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64::LDXC1
+"ldxc1 f<FD>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + op2);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL);
+           COP_LD(1,destreg,memval);;
+         }
+      }
+  }
+}
+
+
+
+110001,5.BASE,5.FT,16.OFFSET:COP1:32::LWC1 
+"lwc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = EXTEND16 (OFFSET);
+  int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((uword64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           uword64 memval = 0;
+           uword64 memval1 = 0;
+           uword64 mask = 0x7;
+           unsigned int shift = 2;
+           unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte UNUSED;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+           LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+           byte = ((vaddr & mask) ^ (bigend << shift));
+           COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)((memval >> (8 * byte)) & 0xFFFFFFFF));
+         }
+      }
+  }
+}
+
+
+010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32::LWXC1
+"lwxc1 f<FD>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+   address_word vaddr = ((unsigned64)op1 + op2);
+   address_word paddr;
+   int uncached;
+   if ((vaddr & 3) != 0)
+    SignalExceptionAddressLoad();
+   else
+   {
+    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+    {
+     unsigned64 memval = 0;
+     unsigned64 memval1 = 0;
+     unsigned64 mask = 0x7;
+     unsigned int shift = 2;
+     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+     unsigned int byte;
+     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));
+     LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL);
+     byte = ((vaddr & mask) ^ (bigend << shift));
+     COP_LW(1,destreg,(unsigned int)((memval >> (8 * byte)) & 0xFFFFFFFF));
+    }
+   }
+  }
+}
+
+
+
+//
+// FIXME: Not correct for mips*
+//
+010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32::MADD.D
+"madd.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+    StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
+  }
+}
+
+
+010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32::MADD.S
+"madd.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+    StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
+  }
+}
+
+
+// MFC1
+// MTC1
+010001,00,X,00,5.RT,5.FS,00000000000:COP1S:32::MxC1
+"m%s<X>c1 r<RT>, f<FS>"
+*mipsI:
+*mipsII:
+*mipsIII:
+{
+  if (X)
+    { /*MTC1*/
+      if (SizeFGR() == 64)
+       PENDING_FILL ((FS + FGRIDX), (SET64HI(0xDEADC0DE) | VL4_8(GPR[RT])));
+      else
+       PENDING_FILL ((FS + FGRIDX), VL4_8(GPR[RT]));
+    }
+  else /*MFC1*/
+    PENDING_FILL (RT, SIGNEXTEND(FGR[FS],32));
+}
+010001,00,X,00,5.RT,5.FS,00000000000:COP1S:32::MxC1
+"m%s<X>c1 r<RT>, f<FS>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  if (X)
+    /*MTC1*/
+    StoreFPR (FS, fmt_uninterpreted_32, VL4_8 (GPR[RT]));
+  else /*MFC1*/
+    GPR[RT] = SIGNEXTEND(FGR[FS],32);
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32::MOV.fmt
+"mov.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    StoreFPR(destreg,format,ValueFPR(fs,format));
+  }
+}
+
+
+// MOVF
+000000,5.RS,3.CC,0,1.TF,5.RD,00000000001:SPECIAL:32::MOVtf
+"mov%s<TF> r<RD>, r<RS>, <CC>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  if (GETFCC(CC) == TF)
+    GPR[RD] = GPR[RS];
+}
+
+
+// MOVF.fmt
+010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32::MOVtf.fmt
+"mov%s<TF>.%s<FMT> f<FD>, f<FS>, <CC>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+   if (GETFCC(CC) == TF)
+     StoreFPR (FD, format, ValueFPR (FS, format));
+   else
+     StoreFPR (FD, format, ValueFPR (FD, format));
+  }
+}
+
+
+010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32::MOVN.fmt
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    StoreFPR(destreg,format,ValueFPR(fs,format));
+  }
+}
+
+
+// MOVT see MOVtf
+
+
+// MOVT.fmt see MOVtf.fmt
+
+
+
+010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32::MOVZ.fmt
+"movz.%s<FMT> f<FD>, f<FS>, r<RT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+   StoreFPR(destreg,format,ValueFPR(fs,format));
+  }
+}
+
+
+// MSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32::MSUB.D
+"msub.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+    StoreFPR(destreg,fmt_double,Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double));
+  }
+}
+
+
+// MSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,101000:COP1X:32::MSUB.S
+"msub.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+   StoreFPR(destreg,fmt_single,Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single));
+  }
+}
+
+
+// MTC1 see MxC1
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32::MUL.fmt
+"mul.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32::NEG.fmt
+"neg.%s<FMT> f<FD>, f<FS>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));
+  }
+}
+
+
+// NMADD.fmt
+010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32::NMADD.D
+"nmadd.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+   StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
+  }
+}
+
+
+// NMADD.fmt
+010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32::NMADD.S
+"nmadd.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+   StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
+  }
+}
+
+
+// NMSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,111001:COP1X:32::NMSUB.D
+"nmsub.d f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+   StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double));
+  }
+}
+
+
+// NMSUB.fmt
+010011,5.FR,5.FT,5.FS,5.FD,111000:COP1X:32::NMSUB.S
+"nmsub.s f<FD>, f<FR>, f<FS>, f<FT>"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int fr = ((instruction >> 21) & 0x0000001F);
+  {
+    StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single));
+  }
+}
+
+
+010011,5.BASE,5.INDEX,5.HINT,00000001111:COP1X:32::PREFX
+"prefx <HINT>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int fs = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + (unsigned64)op2);
+    address_word paddr;
+    int uncached;
+    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+      Prefetch(uncached,paddr,vaddr,isDATA,fs);
+  }
+}
+
+010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32::RECIP.fmt
+*mipsIV:
+"recip.%s<FMT> f<FD>, f<FS>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64::ROUND.L.fmt
+"round.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32::ROUND.W.fmt
+"round.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32::RSQRT.fmt
+*mipsIV:
+"rsqrt.%s<FMT> f<FD>, f<FS>"
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format),format));
+  }
+}
+
+
+111101,5.BASE,5.FT,16.OFFSET:COP1:64::SDC1
+"sdc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  address_word vaddr = GPR[BASE] + EXTEND16 (OFFSET);
+  int uncached;
+  if ((vaddr & 7) != 0)
+    SignalExceptionAddressStore();
+  else
+    {
+      address_word paddr;
+      unsigned64 memval;
+      AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL);
+      memval = (unsigned64) COP_SD(((instruction_0 >> 26) & 0x3),FT);
+      StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,0,paddr,vaddr,isREAL);
+    }
+}
+
+
+
+010011,5.RS,5.RT,vvvvv,00000001001:COP1X:64::SDXC1
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int fs = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + op2);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval = (unsigned64)COP_SD(1,fs);
+           {
+             StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32::SQRT.fmt
+"sqrt.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format)));
+  }
+}
+
+
+010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32::SUB.fmt
+"sub.%s<FMT> f<FD>, f<FS>, f<FT>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int ft = ((instruction >> 16) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+    if ((format != fmt_single) && (format != fmt_double))
+      SignalException(ReservedInstruction,instruction);
+    else
+      StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));
+  }
+}
+
+
+
+111001,5.BASE,5.FT,16.OFFSET:COP1:32::SWC1
+"swc1 f<FT>, <OFFSET>(r<BASE>)"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = EXTEND16 (OFFSET);
+  int destreg UNUSED = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((uword64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           uword64 memval = 0;
+           uword64 memval1 = 0;
+           uword64 mask = 0x7;
+           unsigned int byte;
+           paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+           byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+           memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte));
+           {
+             StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+
+010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32::SWXC1
+"swxc1 f<FS>, r<INDEX>(r<BASE>)"
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+{
+  unsigned32 instruction = instruction_0;
+  int fs = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+   address_word vaddr = ((unsigned64)op1 + op2);
+   address_word paddr;
+   int uncached;
+   if ((vaddr & 3) != 0)
+    SignalExceptionAddressStore();
+   else
+   {
+    if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+    {
+     unsigned64 memval = 0;
+     unsigned64 memval1 = 0;
+     unsigned64 mask = 0x7;
+     unsigned int byte;
+     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));
+     byte = ((vaddr & mask) ^ (BigEndianCPU << 2));
+     memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte));
+      {
+       StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL);
+      }
+    }
+   }
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64::TRUNC.L.fmt
+"trunc.l.%s<FMT> f<FD>, f<FS>"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long));
+  }
+}
+
+
+010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32::TRUNC.W
+"trunc.w.%s<FMT> f<FD>, f<FS>"
+*mipsII:
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 6) & 0x0000001F);
+  int fs = ((instruction >> 11) & 0x0000001F);
+  int format = ((instruction >> 21) & 0x00000007);
+  {
+  if ((format != fmt_single) && (format != fmt_double))
+   SignalException(ReservedInstruction,instruction);
+  else
+   StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word));
+  }
+}
+
+\f
+//
+// MIPS Architecture:
+//
+//        System Control Instruction Set (COP0)
+//
+
+
+010000,01000,00000,16.OFFSET:COP0:32::BC0F
+"bc0f <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,01000,00010,16.OFFSET:COP0:32::BC0FL
+"bc0fl <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,01000,00001,16.OFFSET:COP0:32::BC0T
+"bc0t <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+
+010000,01000,00011,16.OFFSET:COP0:32::BC0TL
+"bc0tl <OFFSET>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+*r3900:
+// start-sanitize-tx19
+*tx19:
+// end-sanitize-tx19
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int hint = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = (op1 + offset);
+    address_word paddr;
+    int uncached;
+    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+      CacheOp(hint,vaddr,paddr,instruction);
+  }
+}
+
+
+010000,10000,000000000000000,111001:COP0:32::DI
+"di"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,10000,000000000000000,111000:COP0:32::EI
+"ei"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,10000,000000000000000,011000:COP0:32::ERET
+"eret"
+*mipsIII:
+*mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,00000,5.RT,5.RD,00000,6.REGX:COP0:32::MFC0
+"mfc0 r<RT>, r<RD> # <REGX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  DecodeCoproc (instruction_0);
+}
+
+010000,00100,5.RT,5.RD,00000,6.REGX:COP0:32::MTC0
+"mtc0 r<RT>, r<RD> # <REGX>"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+{
+  DecodeCoproc (instruction_0);
+}
+
+
+010000,10000,000000000000000,001000:COP0:32::TLBP
+"tlbp"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,10000,000000000000000,000001:COP0:32::TLBR
+"tlbr"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,10000,000000000000000,000010:COP0:32::TLBWI
+"tlbwi"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+
+010000,10000,000000000000000,000110:COP0:32::TLBWR
+"tlbwr"
+*mipsI,mipsII,mipsIII,mipsIV:
+*vr5000:
+// start-sanitize-vr5400
+*vr5400:
+// end-sanitize-vr5400
+// start-sanitize-r5900
+*r5900:
+// end-sanitize-r5900
+
+\f
+:include:::m16.igen
+// start-sanitize-vr5400
+:include::vr5400:vr5400.igen
+:include:::mdmx.igen
+// end-sanitize-vr5400
+// start-sanitize-r5900
+:include::r5900:r5900.igen
+// end-sanitize-r5900
+\f
+// start-sanitize-cygnus-never
+
+// // FIXME FIXME FIXME What is this instruction?
+// 111011,5.RS,5.RT,16.OFFSET:NORMAL:32::<INT>
+// *mipsI:
+// *mipsII:
+// *mipsIII:
+// *mipsIV:
+// // start-sanitize-r5900
+// *r5900:
+// // end-sanitize-r5900
+// *r3900:
+// // start-sanitize-tx19
+// *tx19:
+// // end-sanitize-tx19
+// {
+//   unsigned32 instruction = instruction_0;
+//   signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+//   signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+//   signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+//   {
+//     if (CoProcPresent(3))
+//       SignalException(CoProcessorUnusable);
+//     else
+//       SignalException(ReservedInstruction,instruction);
+//   }
+// }
+
+// end-sanitize-cygnus-never
+// start-sanitize-cygnus-never
+
+// // FIXME FIXME FIXME What is this?
+// 11100,******,00001:RR:16::SDBBP
+// *mips16:
+// {
+//   unsigned32 instruction = instruction_0;
+//   if (have_extendval)
+//     SignalException (ReservedInstruction, instruction);
+//   {
+//     SignalException(DebugBreakPoint,instruction);
+//   }
+// }
+
+// end-sanitize-cygnus-never
+// start-sanitize-cygnus-never
+
+// // FIXME FIXME FIXME What is this?
+// 000000,********************,001110:SPECIAL:32::SDBBP
+// *r3900:
+// {
+//   unsigned32 instruction = instruction_0;
+//   {
+//     SignalException(DebugBreakPoint,instruction);
+//   }
+// }
+
+// end-sanitize-cygnus-never
+// start-sanitize-cygnus-never
+
+// // FIXME FIXME FIXME This apparently belongs to the vr4100 which
+// // isn't yet reconized by this simulator.
+// 000000,5.RS,5.RT,0000000000101000:SPECIAL:32::MADD16
+// *vr4100:
+// {
+//   unsigned32 instruction = instruction_0;
+//   signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+//   signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+//   {
+//     CHECKHILO("Multiply-Add");
+//     {
+//       unsigned64 temp = (op1 * op2);
+//       temp += (SET64HI(VL4_8(HI)) | VL4_8(LO));
+//       LO = SIGNEXTEND((unsigned64)VL4_8(temp),32);
+//       HI = SIGNEXTEND((unsigned64)VH4_8(temp),32);
+//     }
+//   }
+// }
+
+// end-sanitize-cygnus-never
+// start-sanitize-cygnus-never
+
+// // FIXME FIXME FIXME This apparently belongs to the vr4100 which
+// // isn't yet reconized by this simulator.
+// 000000,5.RS,5.RT,0000000000101001:SPECIAL:64::DMADD16
+// *vr4100:
+// {
+//   unsigned32 instruction = instruction_0;
+//   signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+//   signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+//   {
+//     CHECKHILO("Multiply-Add");
+//     {
+//       unsigned64 temp = (op1 * op2);
+//       LO = LO + temp;
+//     }
+//   }
+// }
+
+// end-sanitize-cygnus-never
diff --git a/sim/txvu/pke0.c b/sim/txvu/pke0.c
new file mode 100644 (file)
index 0000000..be48cff
--- /dev/null
@@ -0,0 +1,56 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "pke0.h"
+
+int
+pke0_io_read_buffer(device *me,
+                    void *dest,
+                    int space,
+                    address_word addr,
+                    unsigned nr_bytes,
+                    sim_cpu *processor,
+                    sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+       return nr_bytes;
+}
+
+int
+pke0_io_write_buffer(device *me,
+                     const void *source,
+                     int space,
+                     address_word addr,
+                     unsigned nr_bytes,
+                     sim_cpu *processor,
+                     sim_cia cia)
+{ 
+       printf("%s: Write!\n", me->name);
+       return nr_bytes;
+}
+
+device pke0_device = 
+  { 
+    "pke0", 
+    &pke0_io_read_buffer,
+    &pke0_io_write_buffer 
+  };
+
+void 
+pke0_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   PKE0_REGISTER_WINDOW_START,
+                   PKE0_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &pke0_device,
+                   NULL /*buffer*/);
+}
diff --git a/sim/txvu/pke0.h b/sim/txvu/pke0.h
new file mode 100644 (file)
index 0000000..633ac47
--- /dev/null
@@ -0,0 +1,17 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef PKE0_H_
+#define PKE0_H_
+
+#include "sim-main.h"
+
+void pke0_attach(SIM_DESC sd);
+
+#define PKE0_REGISTER_WINDOW_START 0x10000800
+#define PKE0_REGISTER_WINDOW_END   0x10000980
+
+#define PKE0_REGISTER_WINDOW_SIZE (PKE0_REGISTER_WINDOW_END - PKE0_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/txvu/pke1.c b/sim/txvu/pke1.c
new file mode 100644 (file)
index 0000000..62492f9
--- /dev/null
@@ -0,0 +1,56 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "pke1.h"
+
+int
+pke1_io_read_buffer(device *me,
+                      void *dest,
+                      int space,
+                      address_word addr,
+                      unsigned nr_bytes,
+                      sim_cpu *processor,
+                      sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+       return nr_bytes;
+}
+
+int
+pke1_io_write_buffer(device *me,
+                    const void *source,
+                    int space,
+                    address_word addr,
+                    unsigned nr_bytes,
+                    sim_cpu *processor,
+                    sim_cia cia)
+{
+       printf("%s: Write!\n", me->name);
+       return nr_bytes;
+}
+
+device pke1_device = 
+  {
+    "pke1", 
+    &pke1_io_read_buffer,
+    &pke1_io_write_buffer 
+  };
+
+void 
+pke1_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   PKE1_REGISTER_WINDOW_START,
+                   PKE1_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &pke1_device,
+                   NULL /*buffer*/);
+}
diff --git a/sim/txvu/pke1.h b/sim/txvu/pke1.h
new file mode 100644 (file)
index 0000000..04bd883
--- /dev/null
@@ -0,0 +1,17 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef PKE1_H_
+#define PKE1_H_
+
+#include "sim-main.h"
+
+void pke1_attach(SIM_DESC sd);
+
+#define PKE1_REGISTER_WINDOW_START 0x10000a00
+#define PKE1_REGISTER_WINDOW_END   0x10000b80
+
+#define PKE1_REGISTER_WINDOW_SIZE (PKE1_REGISTER_WINDOW_END - PKE1_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/txvu/r5900.igen b/sim/txvu/r5900.igen
new file mode 100644 (file)
index 0000000..a10d5d0
--- /dev/null
@@ -0,0 +1,2463 @@
+// start-sanitize-r5900
+
+// FIXME: The instructions below which are typically r5900 specific
+//        need to be merged back into the above.
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,0000000000011010:MMINORM:32::DIV1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    CHECKHILO("Division");
+    {
+      int d1 = op1;
+      int d2 = op2;
+      if (d2 == 0)
+       {
+         LO1 = SIGNEXTEND(0x80000000,32);
+         HI1 = SIGNEXTEND(0,32);
+       }
+      else if (d2 == -1 && d1 == 0x80000000)
+       {
+         LO1 = SIGNEXTEND(0x80000000,32);
+         HI1 = SIGNEXTEND(0,32);
+       }
+      else
+       {
+         LO1 = SIGNEXTEND((d1 / d2),32);
+         HI1 = SIGNEXTEND((d1 % d2),32);
+       }
+    }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,0000000000011011:MMINORM:32::DIVU1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    CHECKHILO("Division");
+    {
+      unsigned int d1 = op1;
+      unsigned int d2 = op2;
+      if (d2 == 0)
+       {
+         LO1 = SIGNEXTEND(0x80000000,32);
+         HI1 = SIGNEXTEND(0,32);
+       }
+      else if (d2 == -1 && d1 == 0x80000000)
+       {
+         LO1 = SIGNEXTEND(0x80000000,32);
+         HI1 = SIGNEXTEND(0,32);
+       }
+      else
+       {
+         LO1 = SIGNEXTEND((d1 / d2),32);
+         HI1 = SIGNEXTEND((d1 % d2),32);
+       }
+    }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011110,5.RS,5.RT,16.OFFSET:NORMAL:128::LQ
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  int destreg = ((instruction >> 16) & 0x0000001F);
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 15) != 0)
+      SignalExceptionAddressLoad();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           unsigned64 mask = 0x7;
+           unsigned int shift = 8;
+           unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);
+           unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);
+           unsigned int byte;
+           LoadMemory(&memval,&memval1,uncached,AccessLength_QUADWORD,paddr,vaddr,isDATA,isREAL);
+           GPR[destreg] = memval;
+           GPR1[destreg] = memval1;
+         }
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000000000:MMINORM:32::MADD
+*r5900:
+*r3900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    word64 prod = (word64)WORD64(VL4_8(HI),VL4_8(LO)) + ((word64)SIGNEXTEND(op1,32) * (word64)SIGNEXTEND(op2,32));
+    LO = SIGNEXTEND(prod,32);
+    HI = SIGNEXTEND( VH4_8(prod), 32);
+    if( destreg != 0 ) GPR[destreg] = LO;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000000001:MMINORM:32::MADDU
+*r5900:
+*r3900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    unsigned64 prod = (unsigned64)WORD64(VL4_8(HI),VL4_8(LO)) + ((unsigned64)VL4_8(op1) * (unsigned64)VL4_8(op2));
+    LO = SIGNEXTEND(prod,32);
+    HI = SIGNEXTEND( VH4_8(prod), 32);
+    if( destreg != 0 ) GPR[destreg] = LO;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000100000:MMINORM:32::MADD1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    word64 prod = (word64)WORD64(VL4_8(HI1),VL4_8(LO1)) + ((word64)SIGNEXTEND(op1,32) * (word64)SIGNEXTEND(op2,32));
+    LO1 = SIGNEXTEND(prod,32);
+    HI1 = SIGNEXTEND( VH4_8(prod), 32);
+    if( destreg != 0 ) GPR[destreg] = LO1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000100001:MMINORM:32::MADDU1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    unsigned64 prod = (unsigned64)WORD64(VL4_8(HI1),VL4_8(LO1)) + ((unsigned64)VL4_8(op1) * (unsigned64)VL4_8(op2));
+    LO1 = SIGNEXTEND(prod,32);
+    HI1 = SIGNEXTEND( VH4_8(prod), 32);
+    if( destreg != 0 ) GPR[destreg] = LO1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0111000000000000,5.RD,00000010000:MMINORM:32::MFHI1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    GPR[destreg] = HI1;
+    HI1ACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0111000000000000,5.RD,00000010010:MMINORM:32::MFLO1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    GPR[destreg] = LO1;
+    LO1ACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0000000000000000,5.RD,00000101000:SPECIAL:32::MFSA
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    GPR[destreg] = SA;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,000000000000000010001:MMINORM:32::MTHI1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    if (HI1ACCESS != 0)
+      sim_io_error(sd,"MT (move-to) over-writing HI register value\n");
+    HI1 = op1;
+    HI1ACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,000000000000000010011:MMINORM:32::MTLO1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    if (LO1ACCESS != 0)
+      sim_io_error(sd,"MT (move-to) over-writing LO register value");
+    LO1 = op1;
+    LO1ACCESS = 3; /* 3rd instruction will be safe */
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+000000,5.RS,000000000000000101001:SPECIAL:32::MTSA
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    SA = op1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+000001,5.RS,11000,16.IMMEDIATE:REGIMM:32::MTSAB
+*r5900:
+{
+  SA = ((GPR[RA] & 0xF) ^ (IMMEDIATE & 0xF)) * 8;
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+000001,5.RS,11001,16.IMMEDIATE:REGIMM:32::MTSAH
+*r5900:
+{
+  SA = ((GPR[RS] & 0x7) ^ (IMMEDIATE & 0x7)) * 16;
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000011000:MMINORM:32::MULT1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 temp = ((word64) op1 * (word64) op2);
+      LO1 = SIGNEXTEND((unsigned64)VL4_8(temp),32);
+      HI1 = SIGNEXTEND((unsigned64)VH4_8(temp),32);
+      if ( destreg != 0 )
+       GPR[destreg] = LO1;
+    }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000011001:MMINORM:32::MULTU1
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word op2 = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  {
+    CHECKHILO("Multiplication");
+    {
+      unsigned64 temp = ((unsigned64)(op1 & 0xffffffff) * (unsigned64)(op2 & 0xffffffff));
+      LO1 = SIGNEXTEND((unsigned64)VL4_8(temp),32);
+      HI1 = SIGNEXTEND((unsigned64)VH4_8(temp),32);
+      if ( destreg != 0 )
+       GPR[destreg] = LO1;
+    }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,00101101000:MMI1:32::PABSH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      {
+       if (RT_SH(i) >= 0)
+         GPR_SH(destreg,i) =  RT_SH(i);
+       else if (RT_SH(i) == -32768)
+         GPR_SH(destreg,i) = 32767;
+       else
+         GPR_SH(destreg,i) = -RT_SH(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,00001101000:MMI1:32::PABSW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       if (RT_SW(i) >= 0)
+         GPR_SW(destreg,i) =  RT_SW(i);
+       else if (RT_SW(i) == (int)0x80000000)
+         GPR_SW(destreg,i) = (int)0x7FFFFFFF;
+       else
+         GPR_SW(destreg,i) = -RT_SW(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01000001000:MMI0:32::PADDB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       int s = RS_SB(i);
+       int t = RT_SB(i);
+       int r = s + t;
+       GPR_SB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00100001000:MMI0:32::PADDH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       int s = RS_SH(i);
+       int t = RT_SH(i);
+       int r = s + t;
+       GPR_SH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000001000:MMI0:32::PADDW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       signed64 s = RS_SW(i);
+       signed64 t = RT_SW(i);
+       signed64 r = s + t;
+       GPR_SW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11000001000:MMI0:32::PADDSB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       int s = RS_SB(i);
+       int t = RT_SB(i);
+       int r = s + t;
+       if (r > 127)
+         GPR_SB(destreg,i) = 127;
+       else if (r < -128)
+         GPR_SB(destreg,i) = -128;
+       else
+         GPR_SB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10100001000:MMI0:32::PADDSH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       int s = RS_SH(i);
+       int t = RT_SH(i);
+       int r = s + t;
+       if (r > 32767)
+         GPR_SH(destreg,i) = 32767;
+       else if (r < -32768)
+         GPR_SH(destreg,i) = -32768;
+       else
+         GPR_SH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10000001000:MMI0:32::PADDSW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       signed64 s = RS_SW(i);
+       signed64 t = RT_SW(i);
+       signed64 r = s + t;
+       if (r > (int)0x7FFFFFFF)
+         GPR_SW(destreg,i) = (int)0x7FFFFFFF;
+       else if (r < (int)0x80000000)
+         GPR_SW(destreg,i) = (int)0x80000000;
+       else
+         GPR_SW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11000101000:MMI1:32::PADDUB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       unsigned int s = RS_UB(i);
+       unsigned int t = RT_UB(i);
+       unsigned int r = s + t;
+       if (r > 0xFF)
+         GPR_UB(destreg,i) = 0xFF;
+       else
+         GPR_UB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10100101000:MMI1:32::PADDUH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       unsigned int s = RS_UH(i);
+       unsigned int t = RT_UH(i);
+       unsigned int r = s + t;
+       if (r > 0xFFFF)
+         GPR_UH(destreg,i) = 0xFFFF;
+       else
+         GPR_UH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10000101000:MMI1:32::PADDUW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       unsigned64 s = RS_UW(i);
+       unsigned64 t = RT_UW(i);
+       unsigned64 r = s + t;
+       if (r > 0xFFFFFFFF)
+         GPR_UW(destreg,i) = 0xFFFFFFFF;
+       else
+         GPR_UW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00100101000:MMI1:32::PADSBH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS/2;i++)
+      GPR_SH(destreg,i) = RS_SH(i) - RT_SH(i);
+    for(;i<HALFWORDS_IN_MMI_REGS;i++)
+      GPR_SH(destreg,i) = RS_SH(i) + RT_SH(i);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10010001001:MMI2:32::PAND
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = (RS_UW(i) & RT_UW(i));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01010101000:MMI1:32::PCEQB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<BYTES_IN_MMI_REGS;i++)
+      {
+       if (RS_SB(i) == RT_SB(i)) GPR_SB(destreg,i) = 0xFF;
+       else                        GPR_SB(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00110101000:MMI1:32::PCEQH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SH(i) == RT_SH(i)) GPR_SH(destreg,i) = 0xFFFF;
+       else                        GPR_SH(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00010101000:MMI1:32::PCEQW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SW(i) == RT_SW(i)) GPR_SW(destreg,i) = 0xFFFFFFFF;
+       else                        GPR_SW(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01010001000:MMI0:32::PCGTB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<BYTES_IN_MMI_REGS;i++)
+      {
+       if (RS_SB(i) > RT_SB(i)) GPR_SB(destreg,i) = 0xFF;
+       else                        GPR_SB(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00110001000:MMI0:32::PCGTH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SH(i) > RT_SH(i)) GPR_SH(destreg,i) = 0xFFFF;
+       else                        GPR_SH(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00010001000:MMI0:32::PCGTW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SW(i) > RT_SW(i)) GPR_SW(destreg,i) = 0xFFFFFFFF;
+       else                        GPR_SW(destreg,i) = 0;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11011101001:MMI3:32::PCPYH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,7) = GPR_UH(destreg,6) = GPR_UH(destreg,5) = GPR_UH(destreg,4) = RT_UH(4);
+    GPR_UH(destreg,3) = GPR_UH(destreg,2) = GPR_UH(destreg,1) = GPR_UH(destreg,0) = RT_UH(0);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01110001001:MMI2:32::PCPYLD
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UD(destreg,0) = RT_UD(0);
+    GPR_UD(destreg,1) = RS_UD(0);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01110101001:MMI3:32::PCPYUD
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UD(destreg,0) = RS_UD(1);
+    GPR_UD(destreg,1) = RT_UD(1);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,0000011101001001:MMI2:32::PDIVBW
+*r5900:
+{
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    signed32 devisor = RT_SH(0);
+    if (devisor == -1)
+      {
+       LO_SW(0) = -RS_SW(0);
+       HI_SW(0) = 0;
+       LO_SW(1) = -RS_SW(1);
+       HI_SW(1) = 0;
+       LO_SW(2) = -RS_SW(2);
+       HI_SW(2) = 0;
+       LO_SW(3) = -RS_SW(3);
+       HI_SW(3) = 0;
+      }
+    else if (devisor != 0)
+      {
+       LO_SW(0) = RS_SW(0) / devisor;
+       HI_SW(0) = SIGNEXTEND( (RS_SW(0) % devisor), 16 );
+       LO_SW(1) = RS_SW(1) / devisor;
+       HI_SW(1) = SIGNEXTEND( (RS_SW(1) % devisor), 16 );
+       LO_SW(2) = RS_SW(2) / devisor;
+       HI_SW(2) = SIGNEXTEND( (RS_SW(2) % devisor), 16 );
+       LO_SW(3) = RS_SW(3) / devisor;
+       HI_SW(3) = SIGNEXTEND( (RS_SW(3) % devisor), 16 );
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,0000001101101001:MMI3:32::PDIVUW
+*r5900:
+{
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    if (RT_UW(0) != 0)
+      {
+       LO  = (signed32)(RS_UW(0) / RT_UW(0));
+       HI  = (signed32)(RS_UW(0) % RT_UW(0));
+      }
+    if (RT_UW(2) != 0)
+      {
+       LO1 = (signed32)(RS_UW(2) / RT_UW(2));
+       HI1 = (signed32)(RS_UW(2) % RT_UW(2));
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,0000001101001001:MMI2:32::PDIVW
+*r5900:
+{
+  signed_word rs_reg = GPR[RS];
+  signed_word rs_reg1 = GPR1[RS];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    if (RT_SW(0) == -1)
+      {
+       LO  = -RS_SW(0);
+       HI  = 0;
+      }
+    else if (RT_UW(0) != 0)
+      {
+       LO  = (signed32)(RS_SW(0) / RT_SW(0));
+       HI  = (signed32)(RS_SW(0) % RT_SW(0));
+      }
+    if (RT_SW(2) == -1)
+      {
+       LO1 = -RS_SW(2);
+       HI1 = 0;
+      }
+    else if (RT_UW(2) != 0)
+      {
+       LO1 = (signed32)(RS_SW(2) / RT_SW(2));
+       HI1 = (signed32)(RS_SW(2) % RT_SW(2));
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11010101001:MMI3:32::PEXCH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0) = RT_UH(0);
+    GPR_UH(destreg,1) = RT_UH(2);
+    GPR_UH(destreg,2) = RT_UH(1);
+    GPR_UH(destreg,3) = RT_UH(3);
+    GPR_UH(destreg,4) = RT_UH(4);
+    GPR_UH(destreg,5) = RT_UH(6);
+    GPR_UH(destreg,6) = RT_UH(5);
+    GPR_UH(destreg,7) = RT_UH(7);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11110101001:MMI3:32::PEXCW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0) = RT_UW(0);
+    GPR_UW(destreg,1) = RT_UW(2);
+    GPR_UW(destreg,2) = RT_UW(1);
+    GPR_UW(destreg,3) = RT_UW(3);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11010001001:MMI2:32::PEXOH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0) = RT_UH(2);
+    GPR_UH(destreg,1) = RT_UH(1);
+    GPR_UH(destreg,2) = RT_UH(0);
+    GPR_UH(destreg,3) = RT_UH(3);
+    GPR_UH(destreg,4) = RT_UH(6);
+    GPR_UH(destreg,5) = RT_UH(5);
+    GPR_UH(destreg,6) = RT_UH(4);
+    GPR_UH(destreg,7) = RT_UH(7);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11110001001:MMI2:32::PEXOW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0) = RT_UW(2);
+    GPR_UW(destreg,1) = RT_UW(1);
+    GPR_UW(destreg,2) = RT_UW(0);
+    GPR_UW(destreg,3) = RT_UW(3);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11110001000:MMI0:32::PEXT5
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       unsigned32 x = RT_UW(i);
+       GPR_UW(destreg,i) = ((x & (1  << 15)) << (31 - 15))  
+         | ((x & (31 << 10)) << (19 - 10))  
+         | ((x & (31 << 5))  << (11 - 5))   
+         | ((x & (31 << 0))  << (3  - 0));  
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11010001000:MMI0:32::PEXTLB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UB(destreg,0)  = RT_UB(0);
+    GPR_UB(destreg,1)  = RS_UB(0);
+    GPR_UB(destreg,2)  = RT_UB(1);
+    GPR_UB(destreg,3)  = RS_UB(1);
+    GPR_UB(destreg,4)  = RT_UB(2);
+    GPR_UB(destreg,5)  = RS_UB(2);
+    GPR_UB(destreg,6)  = RT_UB(3);
+    GPR_UB(destreg,7)  = RS_UB(3);
+    GPR_UB(destreg,8)  = RT_UB(4);
+    GPR_UB(destreg,9)  = RS_UB(4);
+    GPR_UB(destreg,10) = RT_UB(5);
+    GPR_UB(destreg,11) = RS_UB(5);
+    GPR_UB(destreg,12) = RT_UB(6);
+    GPR_UB(destreg,13) = RS_UB(6);
+    GPR_UB(destreg,14) = RT_UB(7);
+    GPR_UB(destreg,15) = RS_UB(7);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10110001000:MMI0:32::PEXTLH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0)  = RT_UH(0);
+    GPR_UH(destreg,1)  = RS_UH(0);
+    GPR_UH(destreg,2)  = RT_UH(1);
+    GPR_UH(destreg,3)  = RS_UH(1);
+    GPR_UH(destreg,4)  = RT_UH(2);
+    GPR_UH(destreg,5)  = RS_UH(2);
+    GPR_UH(destreg,6)  = RT_UH(3);
+    GPR_UH(destreg,7)  = RS_UH(3);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10010001000:MMI0:32::PEXTLW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0)  = RT_UW(0);
+    GPR_UW(destreg,1)  = RS_UW(0);
+    GPR_UW(destreg,2)  = RT_UW(1);
+    GPR_UW(destreg,3)  = RS_UW(1);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11010101000:MMI1:32::PEXTUB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UB(destreg,0)  = RT_UB(8);
+    GPR_UB(destreg,1)  = RS_UB(8);
+    GPR_UB(destreg,2)  = RT_UB(9);
+    GPR_UB(destreg,3)  = RS_UB(9);
+    GPR_UB(destreg,4)  = RT_UB(10);
+    GPR_UB(destreg,5)  = RS_UB(10);
+    GPR_UB(destreg,6)  = RT_UB(11);
+    GPR_UB(destreg,7)  = RS_UB(11);
+    GPR_UB(destreg,8)  = RT_UB(12);
+    GPR_UB(destreg,9)  = RS_UB(12);
+    GPR_UB(destreg,10) = RT_UB(13);
+    GPR_UB(destreg,11) = RS_UB(13);
+    GPR_UB(destreg,12) = RT_UB(14);
+    GPR_UB(destreg,13) = RS_UB(14);
+    GPR_UB(destreg,14) = RT_UB(15);
+    GPR_UB(destreg,15) = RS_UB(15);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10110101000:MMI1:32::PEXTUH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0)  = RT_UH(4);
+    GPR_UH(destreg,1)  = RS_UH(4);
+    GPR_UH(destreg,2)  = RT_UH(5);
+    GPR_UH(destreg,3)  = RS_UH(5);
+    GPR_UH(destreg,4)  = RT_UH(6);
+    GPR_UH(destreg,5)  = RS_UH(6);
+    GPR_UH(destreg,6)  = RT_UH(7);
+    GPR_UH(destreg,7)  = RS_UH(7);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10010101000:MMI1:32::PEXTUW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0)  = RT_UW(2);
+    GPR_UW(destreg,1)  = RS_UW(2);
+    GPR_UW(destreg,2)  = RT_UW(3);
+    GPR_UW(destreg,3)  = RS_UW(3);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10001001001:MMI2:32::PHMADDH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) + (RS_SH(0) * RT_SH(0));
+    GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) + (RS_SH(2) * RT_SH(2));
+    GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) + (RS_SH(4) * RT_SH(4));
+    GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) + (RS_SH(6) * RT_SH(6));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10101001001:MMI2:32::PHMSUBH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) - (RS_SH(0) * RT_SH(0));
+    GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) - (RS_SH(2) * RT_SH(2));
+    GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) - (RS_SH(4) * RT_SH(4));
+    GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) - (RS_SH(6) * RT_SH(6));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01010001001:MMI2:32::PINTH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0)  = RT_UH(0);
+    GPR_UH(destreg,1)  = RS_UH(4);
+    GPR_UH(destreg,2)  = RT_UH(1);
+    GPR_UH(destreg,3)  = RS_UH(5);
+    GPR_UH(destreg,4)  = RT_UH(2);
+    GPR_UH(destreg,5)  = RS_UH(6);
+    GPR_UH(destreg,6)  = RT_UH(3);
+    GPR_UH(destreg,7)  = RS_UH(7);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01010101001:MMI3:32::PINTOH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0) = RT_UH(0);
+    GPR_UH(destreg,1) = RS_UH(0);
+    GPR_UH(destreg,2) = RT_UH(2);
+    GPR_UH(destreg,3) = RS_UH(2);
+    GPR_UH(destreg,4) = RT_UH(4);
+    GPR_UH(destreg,5) = RS_UH(4);
+    GPR_UH(destreg,6) = RT_UH(6);
+    GPR_UH(destreg,7) = RS_UH(6);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,00000,5.RD,00000000100:MMINORM:32::PLZCW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  {
+    unsigned long value;
+    int test;
+    int count;
+    int i;
+    value = RS_UW(0);
+    count = 0;
+    test = !!(value & (1 << 31));
+    for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)
+      count++;
+    GPR_UW(destreg,0) = count;
+    value = RS_UW(1);
+    count = 0;
+    test = !!(value & (1 << 31));
+    for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)
+      count++;
+    GPR_UW(destreg,1) = count;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10000001001:MMI2:32::PMADDH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SW(destreg,0) = LO_SW(0) += (RS_SH(0) * RT_SH(0));
+    LO_SW(1) += (RS_SH(1) * RT_SH(1));
+    GPR_SW(destreg,1) = HI_SW(0) += (RS_SH(2) * RT_SH(2));
+    HI_SW(1) += (RS_SH(3) * RT_SH(3));
+    GPR_SW(destreg,2) = LO_SW(2) += (RS_SH(4) * RT_SH(4));
+    LO_SW(3) += (RS_SH(5) * RT_SH(5));
+    GPR_SW(destreg,3) = HI_SW(2) += (RS_SH(6) * RT_SH(6));
+    HI_SW(3) += (RS_SH(7) * RT_SH(7));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000101001:MMI3:32::PMADDUW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    unsigned64 sum0 = U8_4 (HI_SW(0), LO_SW(0));
+    unsigned64 sum1 = U8_4 (HI_SW(2), LO_SW(2));
+    unsigned64 prod0 = (unsigned64)RS_UW(0) * (unsigned64)RT_UW(0);
+    unsigned64 prod1 = (unsigned64)RS_UW(2) * (unsigned64)RT_UW(2);
+    sum0 += prod0;
+    sum1 += prod1;
+    GPR_UD(destreg,0) = sum0;
+    GPR_UD(destreg,1) = sum1;
+    LO  = SIGNEXTEND( sum0, 32 );
+    HI  = SIGNEXTEND( VH4_8(sum0), 32 );
+    LO1 = SIGNEXTEND( sum1, 32 );
+    HI1 = SIGNEXTEND( VH4_8(sum1), 32 );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00000001001:MMI2:32::PMADDW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    signed64 sum0 = WORD64( HI_SW(0), LO_SW(0) );
+    signed64 sum1 = WORD64( HI_SW(2), LO_SW(2) );
+    signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0);
+    signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2);
+    sum0 += prod0;
+    sum1 += prod1;
+    GPR_SD(destreg,0) = sum0;
+    GPR_SD(destreg,1) = sum1;
+    LO  = SIGNEXTEND( sum0, 32 );
+    HI  = SIGNEXTEND( VH4_8(sum0), 32 );
+    LO1 = SIGNEXTEND( sum1, 32 );
+    HI1 = SIGNEXTEND( VH4_8(sum1), 32 );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00111001000:MMI0:32::PMAXH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SH(i) > RT_SH(i)) GPR_SH(destreg,i) = RS_SH(i);
+       else                        GPR_SH(destreg,i) = RT_SH(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00011001000:MMI0:32::PMAXW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SW(i) > RT_SW(i)) GPR_SW(destreg,i) = RS_SW(i);
+       else                        GPR_SW(destreg,i) = RT_SW(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0111000000000000,5.RD,01000001001:MMI2:32::PMFHI
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    GPR_SD(destreg,0) = HI;
+    GPR_SD(destreg,1) = HI1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0111000000000000,5.RD,01001001001:MMI2:32::PMFLO
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    GPR_SD(destreg,0) = LO;
+    GPR_SD(destreg,1) = LO1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+0111000000000000,5.RD,5.SHIFT,110000:MMINORM:32::PMFHL
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  {
+    if (op1 == 0)
+      {
+       GPR_UW(destreg,0) = LO_UW(0);
+       GPR_UW(destreg,1) = HI_UW(0);
+       GPR_UW(destreg,2) = LO_UW(2);
+       GPR_UW(destreg,3) = HI_UW(2);
+      }
+    else if (op1 == 1)
+      {
+       GPR_UW(destreg,0) = LO_UW(1);
+       GPR_UW(destreg,1) = HI_UW(1);
+       GPR_UW(destreg,2) = LO_UW(3);
+       GPR_UW(destreg,3) = HI_UW(3);
+      }
+    else if (op1 == 2)
+      {
+       /* NOTE: This code implements a saturate according to the
+           figure on page B-115 and not according to the
+           definition on page B-113 */
+       signed64 t = ((unsigned64)HI_UW(0) << 32) | (unsigned64)LO_UW(0);
+       signed64 u = ((unsigned64)HI_UW(2) << 32) | (unsigned64)LO_UW(2);
+       if ( t > SIGNED64 (0x000000007FFFFFFF) )
+         GPR_SD(destreg,0) = SIGNED64 (0x000000007FFFFFFF);
+       else if ( t < - SIGNED64 (0x0000000080000000) )
+         GPR_SD(destreg,0) = - SIGNED64 (0x0000000080000000);
+       else
+         GPR_SD(destreg,0) = t;
+       if ( u > SIGNED64 (0x000000007FFFFFFF) )
+         GPR_SD(destreg,1) = SIGNED64 (0x000000007FFFFFFF);
+       else if ( u < - SIGNED64 (0x0000000080000000) )
+         GPR_SD(destreg,1) = - SIGNED64 (0x0000000080000000);
+       else
+         GPR_SD(destreg,1) = u;
+      }
+    else if (op1 == 3)
+      {
+       GPR_UH(destreg,0) = LO_UH(0);
+       GPR_UH(destreg,1) = LO_UH(2);
+       GPR_UH(destreg,2) = HI_UH(0);
+       GPR_UH(destreg,3) = HI_UH(2);
+       GPR_UH(destreg,4) = LO_UH(4);
+       GPR_UH(destreg,5) = LO_UH(6);
+       GPR_UH(destreg,6) = HI_UH(4);
+       GPR_UH(destreg,7) = HI_UH(6);
+      }
+    else if (op1 == 4)
+      {
+       if (LO_SW(0) > 0x7FFF)
+         GPR_UH(destreg,0) = 0x7FFF;
+       else if (LO_SW(0) < -0x8000)
+         GPR_UH(destreg,0) = 0x8000;
+       else
+         GPR_UH(destreg,0) = LO_UH(0);
+       if (LO_SW(1) > 0x7FFF)
+         GPR_UH(destreg,1) = 0x7FFF;
+       else if (LO_SW(1) < -0x8000)
+         GPR_UH(destreg,1) = 0x8000;
+       else
+         GPR_UH(destreg,1) = LO_UH(2);
+       if (HI_SW(0) > 0x7FFF)
+         GPR_UH(destreg,2) = 0x7FFF;
+       else if (HI_SW(0) < -0x8000)
+         GPR_UH(destreg,2) = 0x8000;
+       else
+         GPR_UH(destreg,2) = HI_UH(0);
+       if (HI_SW(1) > 0x7FFF)
+         GPR_UH(destreg,3) = 0x7FFF;
+       else if (HI_SW(1) < -0x8000)
+         GPR_UH(destreg,3) = 0x8000;
+       else
+         GPR_UH(destreg,3) = HI_UH(2);
+       if (LO_SW(2) > 0x7FFF)
+         GPR_UH(destreg,4) = 0x7FFF;
+       else if (LO_SW(2) < -0x8000)
+         GPR_UH(destreg,4) = 0x8000;
+       else
+         GPR_UH(destreg,4) = LO_UH(4);
+       if (LO_SW(3) > 0x7FFF)
+         GPR_UH(destreg,5) = 0x7FFF;
+       else if (LO_SW(3) < -0x8000)
+         GPR_UH(destreg,5) = 0x8000;
+       else
+         GPR_UH(destreg,5) = LO_UH(6);
+       if (HI_SW(2) > 0x7FFF)
+         GPR_UH(destreg,6) = 0x7FFF;
+       else if (HI_SW(2) < -0x8000)
+         GPR_UH(destreg,6) = 0x8000;
+       else
+         GPR_UH(destreg,6) = HI_UH(4);
+       if (HI_SW(3) > 0x7FFF)
+         GPR_UH(destreg,7) = 0x7FFF;
+       else if (HI_SW(3) < -0x8000)
+         GPR_UH(destreg,7) = 0x8000;
+       else
+         GPR_UH(destreg,7) = HI_UH(6);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00111101000:MMI1:32::PMINH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SH(i) < RT_SH(i)) GPR_SH(destreg,i) = RS_SH(i);
+       else                        GPR_SH(destreg,i) = RT_SH(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00011101000:MMI1:32::PMINW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       if (RS_SW(i) < RT_SW(i)) GPR_SW(destreg,i) = RS_SW(i);
+       else                        GPR_SW(destreg,i) = RT_SW(i);
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10100001001:MMI2:32::PMSUBH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SW(destreg,0) = LO_SW(0) -= (RS_SH(0) * RT_SH(0));
+    LO_SW(1) -= (RS_SH(1) * RT_SH(1));
+    GPR_SW(destreg,1) = HI_SW(0) -= (RS_SH(2) * RT_SH(2));
+    HI_SW(1) -= (RS_SH(3) * RT_SH(3));
+    GPR_SW(destreg,2) = LO_SW(2) -= (RS_SH(4) * RT_SH(4));
+    LO_SW(3) -= (RS_SH(5) * RT_SH(5));
+    GPR_SW(destreg,3) = HI_SW(2) -= (RS_SH(6) * RT_SH(6));
+    HI_SW(3) -= (RS_SH(7) * RT_SH(7));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00100001001:MMI2:32::PMSUBW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    signed64 sum0 = WORD64( HI_SW(0), LO_SW(0) );
+    signed64 sum1 = WORD64( HI_SW(2), LO_SW(2) );
+    signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0);
+    signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2);
+    sum0 -= prod0;
+    sum1 -= prod1;
+    GPR_SD(destreg,0) = sum0;
+    GPR_SD(destreg,1) = sum1;
+    LO  = SIGNEXTEND( sum0, 32 );
+    HI  = SIGNEXTEND( VH4_8(sum0), 32 );
+    LO1 = SIGNEXTEND( sum1, 32 );
+    HI1 = SIGNEXTEND( VH4_8(sum1), 32 );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,000000000001000101001:MMI3:32::PMTHI
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  {
+    HI  = RS_SD(0);
+    HI1 = RS_SD(1);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,000000000001001101001:MMI3:32::PMTLO
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  {
+    LO  = RS_SD(0);
+    LO1 = RS_SD(1);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,000000000000000110001:MMINORM:32::PMTHL.LW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  {
+    LO_UW(0) = RS_UW(0);
+    HI_UW(0) = RS_UW(1);
+    LO_UW(2) = RS_UW(2);
+    HI_UW(2) = RS_UW(3);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11100001001:MMI2:32::PMULTH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(0) * RT_SH(0));
+    LO_SW(1) = (RS_SH(1) * RT_SH(1));
+    GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(2) * RT_SH(2));
+    HI_SW(1) = (RS_SH(3) * RT_SH(3));
+    GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(4) * RT_SH(4));
+    LO_SW(3) = (RS_SH(5) * RT_SH(5));
+    GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(6) * RT_SH(6));
+    HI_SW(3) = (RS_SH(7) * RT_SH(7));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01100101001:MMI3:32::PMULTUW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    unsigned64 sum0 = 0;
+    unsigned64 sum1 = 0;
+    unsigned64 prod0 = (unsigned64)RS_UW(0) * (unsigned64)RT_UW(0);
+    unsigned64 prod1 = (unsigned64)RS_UW(2) * (unsigned64)RT_UW(2);
+    sum0 = prod0;
+    sum1 = prod1;
+    GPR_UD(destreg,0) = sum0;
+    GPR_UD(destreg,1) = sum1;
+    LO  = SIGNEXTEND( sum0, 32 );
+    HI  = SIGNEXTEND( VH4_8(sum0), 32 );
+    LO1 = SIGNEXTEND( sum1, 32 );
+    HI1 = SIGNEXTEND( VH4_8(sum1), 32 );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01100001001:MMI2:32::PMULTW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    signed64 sum0 = 0;
+    signed64 sum1 = 0;
+    signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0);
+    signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2);
+    sum0 = prod0;
+    sum1 = prod1;
+    GPR_SD(destreg,0) = sum0;
+    GPR_SD(destreg,1) = sum1;
+    LO  = SIGNEXTEND( sum0, 32 );
+    HI  = SIGNEXTEND( VH4_8(sum0), 32 );
+    LO1 = SIGNEXTEND( sum1, 32 );
+    HI1 = SIGNEXTEND( VH4_8(sum1), 32 );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10011101001:MMI3:32::PNOR
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = ~(RS_UW(i) | RT_UW(i));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10010101001:MMI3:32::POR
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = (RS_UW(i) | RT_UW(i));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11111001000:MMI0:32::PPAC5
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      {
+       unsigned32 x = RT_UW(i);
+       GPR_UW(destreg,i) = ((x & (1  << 31)) >> (31 - 15))  
+         | ((x & (31 << 19)) >> (19 - 10))  
+         | ((x & (31 << 11)) >> (11 - 5))   
+         | ((x & (31 <<  3)) >> (3  - 0));  
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11011001000:MMI0:32::PPACB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UB(destreg,0)  = RT_UB(0);
+    GPR_UB(destreg,1)  = RT_UB(2);
+    GPR_UB(destreg,2)  = RT_UB(4);
+    GPR_UB(destreg,3)  = RT_UB(6);
+    GPR_UB(destreg,4)  = RT_UB(8);
+    GPR_UB(destreg,5)  = RT_UB(10);
+    GPR_UB(destreg,6)  = RT_UB(12);
+    GPR_UB(destreg,7)  = RT_UB(14);
+    GPR_UB(destreg,8)  = RS_UB(0);
+    GPR_UB(destreg,9)  = RS_UB(2);
+    GPR_UB(destreg,10) = RS_UB(4);
+    GPR_UB(destreg,11) = RS_UB(6);
+    GPR_UB(destreg,12) = RS_UB(8);
+    GPR_UB(destreg,13) = RS_UB(10);
+    GPR_UB(destreg,14) = RS_UB(12);
+    GPR_UB(destreg,15) = RS_UB(14);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10111001000:MMI0:32::PPACH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0)  = RT_UH(0);
+    GPR_UH(destreg,1)  = RT_UH(2);
+    GPR_UH(destreg,2)  = RT_UH(4);
+    GPR_UH(destreg,3)  = RT_UH(6);
+    GPR_UH(destreg,4)  = RS_UH(0);
+    GPR_UH(destreg,5)  = RS_UH(2);
+    GPR_UH(destreg,6)  = RS_UH(4);
+    GPR_UH(destreg,7)  = RS_UH(6);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10011001000:MMI0:32::PPACW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0)  = RT_UW(0);
+    GPR_UW(destreg,1)  = RT_UW(2);
+    GPR_UW(destreg,2)  = RS_UW(0);
+    GPR_UW(destreg,3)  = RS_UW(2);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11011001001:MMI2:32::PREVH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UH(destreg,0)  = RT_UH(3);
+    GPR_UH(destreg,1)  = RT_UH(2);
+    GPR_UH(destreg,2)  = RT_UH(1);
+    GPR_UH(destreg,3)  = RT_UH(0);
+    GPR_UH(destreg,4)  = RT_UH(7);
+    GPR_UH(destreg,5)  = RT_UH(6);
+    GPR_UH(destreg,6)  = RT_UH(5);
+    GPR_UH(destreg,7)  = RT_UH(4);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,11111001001:MMI2:32::PROT3W
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UW(destreg,0)  = RT_UW(0);
+    GPR_UW(destreg,1)  = RT_UW(3);
+    GPR_UW(destreg,2)  = RT_UW(1);
+    GPR_UW(destreg,3)  = RT_UW(2);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,110100:MMINORM:32::PSLLH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (16-1);
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      GPR_UH(destreg,i) = (RT_UH(i) << shift_by);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00010001001:MMI2:32::PSLLVW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int s0 = (RS_UB(0) & 0x1F);
+    int s1 = (RS_UB(8) & 0x1F);
+    signed32 temp0 = RT_UW(0) << s0;
+    signed32 temp1 = RT_UW(2) << s1;
+    GPR_SD(destreg,0) = (signed64)temp0;
+    GPR_SD(destreg,1) = (signed64)temp1;
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,111100:MMINORM:32::PSLLW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (32-1);
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = (RT_UW(i) << shift_by);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,110111:MMINORM:32::PSRAH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (16-1);
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      GPR_SH(destreg,i) = SIGNEXTEND( (RT_SH(i) >> shift_by), (16-shift_by) );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00011101001:MMI3:32::PSRAVW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_SD(destreg,0) = SIGNEXTEND( (RT_SW (0) >> (RS_UB(0) & 0x1F)), 32-(RS_UB(0) & 0x1F) );
+    GPR_SD(destreg,1) = SIGNEXTEND( (RT_SW (2) >> (RS_UB(8) & 0x1F)), 32-(RS_UB(8) & 0x1F) );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,111111:MMINORM:32::PSRAW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (32-1);
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_SW(destreg,i) = SIGNEXTEND( (RT_SW(i) >> shift_by), (32-shift_by) );
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,110110:MMINORM:32::PSRLH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (16-1);
+    int i;
+    for(i=0;i<HALFWORDS_IN_MMI_REGS;i++)
+      GPR_UH(destreg,i) = (RT_UH(i) >> shift_by);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00011001001:MMI2:32::PSRLVW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    GPR_UD(destreg,0) = SIGNEXTEND ( RT_UW(0) >> (RS_UB(0) & 0x1F), 31);
+    GPR_UD(destreg,1) = SIGNEXTEND ( RT_UW(2) >> (RS_UB(8) & 0x1F), 31);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+01110000000,5.RT,5.RD,5.SHIFT,111110:MMINORM:32::PSRLW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int op1 = ((instruction >> 6) & 0x0000001F);
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int shift_by = op1 & (32-1);
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = (RT_UW(i) >> shift_by);
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,01001001000:MMI0:32::PSUBB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       int s = RS_SB(i);
+       int t = RT_SB(i);
+       int r = s - t;
+       GPR_SB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00101001000:MMI0:32::PSUBH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       int s = RS_SH(i);
+       int t = RT_SH(i);
+       int r = s - t;
+       GPR_SH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11001001000:MMI0:32::PSUBSB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       int s = RS_SB(i);
+       int t = RT_SB(i);
+       int r = s - t;
+       if (r > 127)
+         GPR_SB(destreg,i) = 127;
+       else if (r < -128)
+         GPR_SB(destreg,i) = -128;
+       else
+         GPR_SB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10101001000:MMI0:32::PSUBSH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       int s = RS_SH(i);
+       int t = RT_SH(i);
+       int r = s - t;
+       if (r > 32767)
+         GPR_SH(destreg,i) = 32767;
+       else if (r < -32768)
+         GPR_SH(destreg,i) = -32768;
+       else
+         GPR_SH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10001001000:MMI0:32::PSUBSW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       signed64 s = RS_SW(i);
+       signed64 t = RT_SW(i);
+       signed64 r = s - t;
+       if (r > (int)0x7FFFFFFF)
+         GPR_SW(destreg,i) = (int)0x7FFFFFFF;
+       else if (r < (int)0x80000000)
+         GPR_SW(destreg,i) = (int)0x80000000;
+       else
+         GPR_SW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11001101000:MMI1:32::PSUBUB
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < BYTES_IN_MMI_REGS; i++)
+      {
+       unsigned int s = RS_UB(i);
+       unsigned int t = RT_UB(i);
+       unsigned int r = s - t;
+       if (r > 0xFF)
+         GPR_UB(destreg,i) = 0;
+       else
+         GPR_UB(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10101101000:MMI1:32::PSUBUH
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < HALFWORDS_IN_MMI_REGS; i++)
+      {
+       unsigned int s = RS_UH(i);
+       unsigned int t = RT_UH(i);
+       unsigned int r = s - t;
+       if (r > 0xFFFF)
+         GPR_UH(destreg,i) = 0;
+       else
+         GPR_UH(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10001101000:MMI1:32::PSUBUW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       unsigned64 s = RS_UW(i);
+       unsigned64 t = RT_UW(i);
+       unsigned64 r = s - t;
+       if (r > 0xFFFFFFFF)
+         GPR_UW(destreg,i) = 0;
+       else
+         GPR_UW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,00001001000:MMI0:32::PSUBW
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for (i=0; i < WORDS_IN_MMI_REGS; i++)
+      {
+       signed64 s = RS_SW(i);
+       signed64 t = RT_SW(i);
+       signed64 r = s - t;
+       GPR_SW(destreg,i) = r;
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,10011001001:MMI2:32::PXOR
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int i;
+    for(i=0;i<WORDS_IN_MMI_REGS;i++)
+      GPR_UW(destreg,i) = (RS_UW(i) ^ RT_UW(i));
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011100,5.RS,5.RT,5.RD,11011101000:MMI1:32::QFSRV
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  int destreg = ((instruction >> 11) & 0x0000001F);
+  signed_word rs_reg = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    int bytes = (SA / 8) % 16;
+    if (SA % 8)
+      SignalException(ReservedInstruction,instruction);
+    else
+      {
+       int i;
+       for(i=0;i<(16-bytes);i++)
+         GPR_SB(destreg,i) = RT_SB(bytes+i);
+       for(;i<16;i++)
+         GPR_SB(destreg,i) = RS_SB(i-(16-bytes));
+      }
+  }
+}
+
+// end-sanitize-r5900
+// start-sanitize-r5900
+
+011111,5.RS,5.RT,16.OFFSET:NORMAL:128::SQ
+*r5900:
+{
+  unsigned32 instruction = instruction_0;
+  signed_word offset = SIGNEXTEND((signed_word)((instruction >> 0) & 0x0000FFFF),16);
+  signed_word rsigned_word = GPR[((instruction >> 16) & 0x0000001F)];
+  signed_word rsigned_word1 = GPR1[((instruction >> 16) & 0x0000001F)];
+  signed_word op1 = GPR[((instruction >> 21) & 0x0000001F)];
+  signed_word rt_reg = GPR[RT];
+  signed_word rt_reg1 = GPR1[RT];
+  {
+    address_word vaddr = ((unsigned64)op1 + offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 15) != 0)
+      SignalExceptionAddressStore();
+    else
+      {
+       if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL))
+         {
+           unsigned64 memval = 0;
+           unsigned64 memval1 = 0;
+           memval  = rsigned_word;
+           memval1 = rsigned_word1;
+           {
+             StoreMemory(uncached,AccessLength_QUADWORD,memval,memval1,paddr,vaddr,isREAL);
+           }
+         }
+      }
+  }
+}
+
+// end-sanitize-r5900
diff --git a/sim/txvu/sim-main.h b/sim/txvu/sim-main.h
new file mode 100644 (file)
index 0000000..aa0928a
--- /dev/null
@@ -0,0 +1,734 @@
+/* MIPS Simulator definition.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef SIM_MAIN_H
+#define SIM_MAIN_H
+
+/* This simulator doesn't cache the Current Instruction Address */
+/* #define SIM_ENGINE_HALT_HOOK(SD, LAST_CPU, CIA) */
+/* #define SIM_ENGINE_RESUME_HOOK(SD, LAST_CPU, CIA) */
+
+#define SIM_HAVE_BIENDIAN
+
+
+/* hobble some common features for moment */
+#define WITH_WATCHPOINTS 1
+#define WITH_MODULO_MEMORY 1
+
+/* For device support.  FIXME: revisit.  */
+#define WITH_DEVICES 1
+
+#include "sim-basics.h"
+
+typedef address_word sim_cia;
+
+#if (WITH_IGEN)
+/* Get the number of instructions.  FIXME: must be a more elegant way
+   of doing this.  */
+#include "itable.h"
+#define MAX_INSNS (nr_itable_entries)
+#define INSN_NAME(i) itable[(i)].name
+#endif
+
+#include "sim-base.h"
+
+
+/* Depreciated macros and types for manipulating 64bit values.  Use
+   ../common/sim-bits.h and ../common/sim-endian.h macros instead. */
+
+typedef signed64 word64;
+typedef unsigned64 uword64;
+
+#define WORD64LO(t)     (unsigned int)((t)&0xFFFFFFFF)
+#define WORD64HI(t)     (unsigned int)(((uword64)(t))>>32)
+#define SET64LO(t)      (((uword64)(t))&0xFFFFFFFF)
+#define SET64HI(t)     (((uword64)(t))<<32)
+#define WORD64(h,l)     ((word64)((SET64HI(h)|SET64LO(l))))
+#define UWORD64(h,l)     (SET64HI(h)|SET64LO(l))
+
+/* Sign-extend the given value (e) as a value (b) bits long. We cannot
+   assume the HI32bits of the operand are zero, so we must perform a
+   mask to ensure we can use the simple subtraction to sign-extend. */
+#define SIGNEXTEND(e,b) \
+ ((unsigned_word) \
+  (((e) & ((uword64) 1 << ((b) - 1))) \
+   ? (((e) & (((uword64) 1 << (b)) - 1)) - ((uword64)1 << (b))) \
+   : ((e) & (((((uword64) 1 << ((b) - 1)) - 1) << 1) | 1))))
+
+/* Check if a value will fit within a halfword: */
+#define NOTHALFWORDVALUE(v) ((((((uword64)(v)>>16) == 0) && !((v) & ((unsigned)1 << 15))) || (((((uword64)(v)>>32) == 0xFFFFFFFF) && ((((uword64)(v)>>16) & 0xFFFF) == 0xFFFF)) && ((v) & ((unsigned)1 << 15)))) ? (1 == 0) : (1 == 1))
+
+
+
+/* Floating-point operations: */
+
+#include "sim-fpu.h"
+
+/* FPU registers must be one of the following types. All other values
+   are reserved (and undefined). */
+typedef enum {
+ fmt_single  = 0,
+ fmt_double  = 1,
+ fmt_word    = 4,
+ fmt_long    = 5,
+ /* The following are well outside the normal acceptable format
+    range, and are used in the register status vector. */
+ fmt_unknown       = 0x10000000,
+ fmt_uninterpreted = 0x20000000,
+ fmt_uninterpreted_32 = 0x40000000,
+ fmt_uninterpreted_64 = 0x80000000,
+} FP_formats;
+
+unsigned64 value_fpr PARAMS ((SIM_DESC sd, address_word cia, int fpr, FP_formats));
+#define ValueFPR(FPR,FMT) value_fpr (sd, cia, (FPR), (FMT))
+
+void store_fpr PARAMS ((SIM_DESC sd, address_word cia, int fpr, FP_formats fmt, unsigned64 value));
+#define StoreFPR(FPR,FMT,VALUE) store_fpr (sd, cia, (FPR), (FMT), (VALUE))
+
+int NaN PARAMS ((unsigned64 op, FP_formats fmt));
+int Infinity PARAMS ((unsigned64 op, FP_formats fmt));
+int Less PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+int Equal PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 AbsoluteValue PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Negate PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 Add PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Sub PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Multiply PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Divide PARAMS ((unsigned64 op1, unsigned64 op2, FP_formats fmt));
+unsigned64 Recip PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 SquareRoot PARAMS ((unsigned64 op, FP_formats fmt));
+unsigned64 convert PARAMS ((SIM_DESC sd, address_word cia, int rm, unsigned64 op, FP_formats from, FP_formats to));
+#define Convert(rm,op,from,to) convert(sd,cia,rm,op,from,to)
+
+/* Macro to update FPSR condition-code field. This is complicated by
+   the fact that there is a hole in the index range of the bits within
+   the FCSR register. Also, the number of bits visible depends on the
+   MIPS ISA version being supported. */
+
+#define SETFCC(cc,v) {\
+  int bit = ((cc == 0) ? 23 : (24 + (cc)));\
+  FCSR = ((FCSR & ~(1 << bit)) | ((v) << bit));\
+}
+#define GETFCC(cc) (((((cc) == 0) ? (FCSR & (1 << 23)) : (FCSR & (1 << (24 + (cc))))) != 0) ? 1 : 0)
+
+/* This should be the COC1 value at the start of the preceding
+   instruction: */
+#define PREVCOC1() ((STATE & simPCOC1) ? 1 : 0)
+
+#if 1
+#define SizeFGR() (WITH_TARGET_WORD_BITSIZE)
+#else
+/* They depend on the CPU being simulated */
+#define SizeFGR() ((WITH_TARGET_WORD_BITSIZE == 64 && ((SR & status_FR) == 1)) ? 64 : 32)
+#endif
+
+/* Standard FCRS bits: */
+#define IR (0) /* Inexact Result */
+#define UF (1) /* UnderFlow */
+#define OF (2) /* OverFlow */
+#define DZ (3) /* Division by Zero */
+#define IO (4) /* Invalid Operation */
+#define UO (5) /* Unimplemented Operation */
+
+/* Get masks for individual flags: */
+#if 1 /* SAFE version */
+#define FP_FLAGS(b)  (((unsigned)(b) < 5) ? (1 << ((b) + 2)) : 0)
+#define FP_ENABLE(b) (((unsigned)(b) < 5) ? (1 << ((b) + 7)) : 0)
+#define FP_CAUSE(b)  (((unsigned)(b) < 6) ? (1 << ((b) + 12)) : 0)
+#else
+#define FP_FLAGS(b)  (1 << ((b) + 2))
+#define FP_ENABLE(b) (1 << ((b) + 7))
+#define FP_CAUSE(b)  (1 << ((b) + 12))
+#endif
+
+#define FP_FS         (1 << 24) /* MIPS III onwards : Flush to Zero */
+
+#define FP_MASK_RM    (0x3)
+#define FP_SH_RM      (0)
+#define FP_RM_NEAREST (0) /* Round to nearest        (Round) */
+#define FP_RM_TOZERO  (1) /* Round to zero           (Trunc) */
+#define FP_RM_TOPINF  (2) /* Round to Plus infinity  (Ceil) */
+#define FP_RM_TOMINF  (3) /* Round to Minus infinity (Floor) */
+#define GETRM()       (int)((FCSR >> FP_SH_RM) & FP_MASK_RM)
+
+
+
+/* Integer ALU operations: */
+
+#include "sim-alu.h"
+
+#define ALU32_END(ANS) \
+  if (ALU32_HAD_OVERFLOW) \
+    SignalExceptionIntegerOverflow (); \
+  (ANS) = ALU32_OVERFLOW_RESULT
+
+
+#define ALU64_END(ANS) \
+  if (ALU64_HAD_OVERFLOW) \
+    SignalExceptionIntegerOverflow (); \
+  (ANS) = ALU64_OVERFLOW_RESULT;
+
+/* start-sanitize-r5900 */
+
+#define BYTES_IN_MMI_REGS       (sizeof(signed_word) + sizeof(signed_word))
+#define HALFWORDS_IN_MMI_REGS   (BYTES_IN_MMI_REGS/2)
+#define WORDS_IN_MMI_REGS       (BYTES_IN_MMI_REGS/4)
+#define DOUBLEWORDS_IN_MMI_REGS (BYTES_IN_MMI_REGS/8)
+
+#define BYTES_IN_MIPS_REGS       (sizeof(signed_word))
+#define HALFWORDS_IN_MIPS_REGS   (BYTES_IN_MIPS_REGS/2)
+#define WORDS_IN_MIPS_REGS       (BYTES_IN_MIPS_REGS/4)
+#define DOUBLEWORDS_IN_MIPS_REGS (BYTES_IN_MIPS_REGS/8)
+
+/* SUB_REG_FETCH - return as lvalue some sub-part of a "register"
+   T  - type of the sub part
+   TC - # of T's in the mips part of the "register"
+   I  - index (from 0) of desired sub part
+   A  - low part of "register"
+   A1 - high part of register
+*/
+#define SUB_REG_FETCH(T,TC,A,A1,I) \
+(*(((I) < (TC) ? (T*)(A) : (T*)(A1)) \
+   + (CURRENT_HOST_BYTE_ORDER == BIG_ENDIAN \
+      ? ((TC) - 1 - (I) % (TC)) \
+      : ((I) % (TC)) \
+      ) \
+   ) \
+ )
+
+/* 
+GPR_<type>(R,I) - return, as lvalue, the I'th <type> of general register R 
+            where <type> has two letters:
+                  1 is S=signed or U=unsigned
+                  2 is B=byte H=halfword W=word D=doubleword 
+*/
+
+#define SUB_REG_SB(A,A1,I) SUB_REG_FETCH(signed8,  BYTES_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_SH(A,A1,I) SUB_REG_FETCH(signed16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
+#define SUB_REG_SW(A,A1,I) SUB_REG_FETCH(signed32, WORDS_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_SD(A,A1,I) SUB_REG_FETCH(signed64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
+
+#define SUB_REG_UB(A,A1,I) SUB_REG_FETCH(unsigned8,  BYTES_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_UH(A,A1,I) SUB_REG_FETCH(unsigned16, HALFWORDS_IN_MIPS_REGS,   A, A1, I)
+#define SUB_REG_UW(A,A1,I) SUB_REG_FETCH(unsigned32, WORDS_IN_MIPS_REGS,       A, A1, I)
+#define SUB_REG_UD(A,A1,I) SUB_REG_FETCH(unsigned64, DOUBLEWORDS_IN_MIPS_REGS, A, A1, I)
+  
+#define GPR_SB(R,I) SUB_REG_SB(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SH(R,I) SUB_REG_SH(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SW(R,I) SUB_REG_SW(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_SD(R,I) SUB_REG_SD(&REGISTERS[R], &REGISTERS1[R], I)
+
+#define GPR_UB(R,I) SUB_REG_UB(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UH(R,I) SUB_REG_UH(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UW(R,I) SUB_REG_UW(&REGISTERS[R], &REGISTERS1[R], I)
+#define GPR_UD(R,I) SUB_REG_UD(&REGISTERS[R], &REGISTERS1[R], I)
+
+
+#define RS_SB(I) SUB_REG_SB(&rs_reg, &rs_reg1, I)
+#define RS_SH(I) SUB_REG_SH(&rs_reg, &rs_reg1, I)
+#define RS_SW(I) SUB_REG_SW(&rs_reg, &rs_reg1, I)
+#define RS_SD(I) SUB_REG_SD(&rs_reg, &rs_reg1, I)
+
+#define RS_UB(I) SUB_REG_UB(&rs_reg, &rs_reg1, I)
+#define RS_UH(I) SUB_REG_UH(&rs_reg, &rs_reg1, I)
+#define RS_UW(I) SUB_REG_UW(&rs_reg, &rs_reg1, I)
+#define RS_UD(I) SUB_REG_UD(&rs_reg, &rs_reg1, I)
+
+#define RT_SB(I) SUB_REG_SB(&rt_reg, &rt_reg1, I)
+#define RT_SH(I) SUB_REG_SH(&rt_reg, &rt_reg1, I)
+#define RT_SW(I) SUB_REG_SW(&rt_reg, &rt_reg1, I)
+#define RT_SD(I) SUB_REG_SD(&rt_reg, &rt_reg1, I)
+
+#define RT_UB(I) SUB_REG_UB(&rt_reg, &rt_reg1, I)
+#define RT_UH(I) SUB_REG_UH(&rt_reg, &rt_reg1, I)
+#define RT_UW(I) SUB_REG_UW(&rt_reg, &rt_reg1, I)
+#define RT_UD(I) SUB_REG_UD(&rt_reg, &rt_reg1, I)
+
+
+
+#define LO_SB(I) SUB_REG_SB(&LO, &LO1, I)
+#define LO_SH(I) SUB_REG_SH(&LO, &LO1, I)
+#define LO_SW(I) SUB_REG_SW(&LO, &LO1, I)
+#define LO_SD(I) SUB_REG_SD(&LO, &LO1, I)
+
+#define LO_UB(I) SUB_REG_UB(&LO, &LO1, I)
+#define LO_UH(I) SUB_REG_UH(&LO, &LO1, I)
+#define LO_UW(I) SUB_REG_UW(&LO, &LO1, I)
+#define LO_UD(I) SUB_REG_UD(&LO, &LO1, I)
+
+#define HI_SB(I) SUB_REG_SB(&HI, &HI1, I)
+#define HI_SH(I) SUB_REG_SH(&HI, &HI1, I)
+#define HI_SW(I) SUB_REG_SW(&HI, &HI1, I)
+#define HI_SD(I) SUB_REG_SD(&HI, &HI1, I)
+
+#define HI_UB(I) SUB_REG_UB(&HI, &HI1, I)
+#define HI_UH(I) SUB_REG_UH(&HI, &HI1, I)
+#define HI_UW(I) SUB_REG_UW(&HI, &HI1, I)
+#define HI_UD(I) SUB_REG_UD(&HI, &HI1, I)
+
+/* end-sanitize-r5900 */
+
+
+
+
+struct _sim_cpu {
+
+
+  /* The following are internal simulator state variables: */
+#define CPU_CIA(CPU) (PC)
+  address_word dspc;  /* delay-slot PC */
+#define DSPC ((STATE_CPU (sd,0))->dspc)
+
+  /* Issue a delay slot instruction immediatly by re-calling
+     idecode_issue */
+#define DELAY_SLOT(TARGET) \
+  do { \
+    address_word target = (TARGET); \
+    instruction_word delay_insn; \
+    sim_events_slip (sd, 1); \
+    CIA = CIA + 4; \
+    STATE |= simDELAYSLOT; \
+    delay_insn = IMEM (CIA); \
+    idecode_issue (sd, delay_insn, (CIA)); \
+    STATE &= ~simDELAYSLOT; \
+    NIA = target; \
+  } while (0)
+#define NULLIFY_NEXT_INSTRUCTION() \
+  do { \
+    sim_events_slip (sd, 1); \
+    dotrace (sd, tracefh, 2, NIA, 4, "load instruction"); \
+    NIA = CIA + 8; \
+  } while (0)
+
+
+
+  /* State of the simulator */
+  unsigned int state;
+  unsigned int dsstate;
+#define STATE ((STATE_CPU (sd,0))->state)
+#define DSSTATE ((STATE_CPU (sd,0))->dsstate)
+
+/* Flags in the "state" variable: */
+#define simHALTEX       (1 << 2)  /* 0 = run; 1 = halt on exception */
+#define simHALTIN       (1 << 3)  /* 0 = run; 1 = halt on interrupt */
+#define simTRACE        (1 << 8)  /* 0 = do nothing; 1 = trace address activity */
+#define simPCOC0        (1 << 17) /* COC[1] from current */
+#define simPCOC1        (1 << 18) /* COC[1] from previous */
+#define simDELAYSLOT    (1 << 24) /* 0 = do nothing; 1 = delay slot entry exists */
+#define simSKIPNEXT     (1 << 25) /* 0 = do nothing; 1 = skip instruction */
+#define simSIGINT      (1 << 28)  /* 0 = do nothing; 1 = SIGINT has occured */
+#define simJALDELAYSLOT        (1 << 29) /* 1 = in jal delay slot */
+
+#define ENGINE_ISSUE_PREFIX_HOOK() \
+  { \
+    /* Set previous flag, depending on current: */ \
+    if (STATE & simPCOC0) \
+     STATE |= simPCOC1; \
+    else \
+     STATE &= ~simPCOC1; \
+    /* and update the current value: */ \
+    if (GETFCC(0)) \
+     STATE |= simPCOC0; \
+    else \
+     STATE &= ~simPCOC0; \
+  }
+
+
+/* This is nasty, since we have to rely on matching the register
+   numbers used by GDB. Unfortunately, depending on the MIPS target
+   GDB uses different register numbers. We cannot just include the
+   relevant "gdb/tm.h" link, since GDB may not be configured before
+   the sim world, and also the GDB header file requires too much other
+   state. */
+
+#ifndef TM_MIPS_H
+#define LAST_EMBED_REGNUM (89)
+#define NUM_REGS (LAST_EMBED_REGNUM + 1)
+/* start-sanitize-r5900 */
+#undef NUM_REGS
+#define NUM_REGS (128)
+/* end-sanitize-r5900 */
+#endif
+
+/* To keep this default simulator simple, and fast, we use a direct
+   vector of registers. The internal simulator engine then uses
+   manifests to access the correct slot. */
+
+  unsigned_word registers[LAST_EMBED_REGNUM + 1];
+  int register_widths[NUM_REGS];
+#define REGISTERS       ((STATE_CPU (sd,0))->registers)
+
+#define GPR     (&REGISTERS[0])
+#define FGRIDX  (38)
+#define FGR     (&REGISTERS[FGRIDX])
+#define LO      (REGISTERS[33])
+#define HI      (REGISTERS[34])
+#define PC      (REGISTERS[37])
+#define CAUSE   (REGISTERS[36])
+#define SRIDX   (32)
+#define SR      (REGISTERS[SRIDX])      /* CPU status register */
+#define FCR0IDX  (71)
+#define FCR0    (REGISTERS[FCR0IDX])    /* really a 32bit register */
+#define FCR31IDX (70)
+#define FCR31   (REGISTERS[FCR31IDX])   /* really a 32bit register */
+#define FCSR    (FCR31)
+#define Debug  (REGISTERS[86])
+#define DEPC   (REGISTERS[87])
+#define EPC    (REGISTERS[88])
+#define COCIDX  (LAST_EMBED_REGNUM + 2) /* special case : outside the normal range */
+
+  unsigned_word c0_config_reg;
+#define C0_CONFIG ((STATE_CPU (sd,0))->c0_config_reg)
+
+/* The following are pseudonyms for standard registers */
+#define ZERO    (REGISTERS[0])
+#define V0      (REGISTERS[2])
+#define A0      (REGISTERS[4])
+#define A1      (REGISTERS[5])
+#define A2      (REGISTERS[6])
+#define A3      (REGISTERS[7])
+#define SP      (REGISTERS[29])
+#define RA      (REGISTERS[31])
+
+  /* Keep the current format state for each register: */
+  FP_formats fpr_state[32];
+#define FPR_STATE ((STATE_CPU (sd, 0))->fpr_state)
+
+
+  /* Slots for delayed register updates. For the moment we just have a
+     fixed number of slots (rather than a more generic, dynamic
+     system). This keeps the simulator fast. However, we only allow
+     for the register update to be delayed for a single instruction
+     cycle. */
+#define PSLOTS (5) /* Maximum number of instruction cycles */
+  int pending_in;
+  int pending_out;
+  int pending_total;
+  int pending_slot_count[PSLOTS];
+  int pending_slot_reg[PSLOTS];
+  unsigned_word pending_slot_value[PSLOTS];
+#define PENDING_IN ((STATE_CPU (sd, 0))->pending_in)
+#define PENDING_OUT ((STATE_CPU (sd, 0))->pending_out)
+#define PENDING_TOTAL ((STATE_CPU (sd, 0))->pending_total)
+#define PENDING_SLOT_COUNT ((STATE_CPU (sd, 0))->pending_slot_count)
+#define PENDING_SLOT_REG ((STATE_CPU (sd, 0))->pending_slot_reg)
+#define PENDING_SLOT_VALUE ((STATE_CPU (sd, 0))->pending_slot_value)
+
+#if 0
+
+  /* The following are not used for MIPS IV onwards: */
+#define PENDING_FILL(r,v) {\
+/* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL); */\
+                            if (PENDING_SLOT_REG[PENDING_IN] != (LAST_EMBED_REGNUM + 1))\
+                             sim_io_eprintf(sd,"Attempt to over-write pending value\n");\
+                            PENDING_SLOT_COUNT[PENDING_IN] = 2;\
+                            PENDING_SLOT_REG[PENDING_IN] = (r);\
+                            PENDING_SLOT_VALUE[PENDING_IN] = (uword64)(v);\
+/*printf("DBG: FILL        reg %d value = 0x%s\n",(r),pr_addr(v));*/\
+                            PENDING_TOTAL++;\
+                            PENDING_IN++;\
+                            if (PENDING_IN == PSLOTS)\
+                             PENDING_IN = 0;\
+/*printf("DBG: FILL AFTER  pending_in = %d, pending_out = %d, pending_total = %d\n",PENDING_IN,PENDING_OUT,PENDING_TOTAL);*/\
+                          }
+#endif
+
+
+  /* LLBIT = Load-Linked bit. A bit of "virtual" state used by atomic
+     read-write instructions. It is set when a linked load occurs. It
+     is tested and cleared by the conditional store. It is cleared
+     (during other CPU operations) when a store to the location would
+     no longer be atomic. In particular, it is cleared by exception
+     return instructions. */
+  int llbit;
+#define LLBIT ((STATE_CPU (sd, 0))->llbit)
+
+
+/* The HIACCESS and LOACCESS counts are used to ensure that
+   corruptions caused by using the HI or LO register to close to a
+   following operation are spotted. */
+
+  int hiaccess;
+  int loaccess;
+#define HIACCESS ((STATE_CPU (sd, 0))->hiaccess)
+#define LOACCESS ((STATE_CPU (sd, 0))->loaccess)
+  /* start-sanitize-r5900 */
+  int hi1access;
+  int lo1access;
+#define HI1ACCESS ((STATE_CPU (sd, 0))->hi1access)
+#define LO1ACCESS ((STATE_CPU (sd, 0))->lo1access)
+  /* end-sanitize-r5900 */
+#if 1
+  /* The 4300 and a few other processors have interlocks on hi/lo
+     register reads, and hence do not have this problem.  To avoid
+     spurious warnings, we just disable this always.  */
+#define CHECKHILO(s)
+#else
+  unsigned_word HLPC;
+  /* If either of the preceding two instructions have accessed the HI
+     or LO registers, then the values they see should be
+     undefined. However, to keep the simulator world simple, we just
+     let them use the value read and raise a warning to notify the
+     user: */
+#define CHECKHILO(s) {\
+  if ((HIACCESS != 0) || (LOACCESS != 0)) \
+    sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
+}
+  /* start-sanitize-r5900 */
+#undef CHECKHILO
+#define CHECKHILO(s) {\
+  if ((HIACCESS != 0) || (LOACCESS != 0) || (HI1ACCESS != 0) || (LO1ACCESS != 0))\
+    sim_io_eprintf(sd,"%s over-writing HI and LO registers values (PC = 0x%s HLPC = 0x%s)\n",(s),pr_addr(PC),pr_addr(HLPC));\
+}
+  /* end-sanitize-r5900 */
+#endif
+
+
+  /* start-sanitize-r5900 */
+  /* The R5900 has 128 bit registers, but the hi 64 bits are only
+     touched by multimedia (MMI) instructions.  The normal mips
+     instructions just use the lower 64 bits.  To avoid changing the
+     older parts of the simulator to handle this weirdness, the high
+     64 bits of each register are kept in a separate array
+     (registers1).  The high 64 bits of any register are by convention
+     refered by adding a '1' to the end of the normal register's name.
+     So LO still refers to the low 64 bits of the LO register, LO1
+     refers to the high 64 bits of that same register.  */
+
+  signed_word registers1[LAST_EMBED_REGNUM + 1];
+#define REGISTERS1 ((STATE_CPU (sd, 0))->registers1)
+#define GPR1     (&REGISTERS1[0])
+#define LO1      (REGISTERS1[32])
+#define HI1      (REGISTERS1[33])
+#define REGISTER_SA    (124)
+
+  unsigned_word sa;        /* the shift amount register */
+#define SA ((STATE_CPU (sd, 0))->sa)
+
+  /* end-sanitize-r5900 */
+  /* start-sanitize-vr5400 */
+
+  /* The MDMX ISA has a very very large accumulator */
+  unsigned8 acc[3 * 8];
+  /* end-sanitize-vr5400 */
+
+  sim_cpu_base base;
+};
+
+
+/* MIPS specific simulator watch config */
+
+void watch_options_install PARAMS ((SIM_DESC sd));
+
+struct swatch {
+  sim_event *pc;
+  sim_event *clock;
+  sim_event *cycles;
+};
+
+
+/* FIXME: At present much of the simulator is still static */
+struct sim_state {
+
+  struct swatch watch;
+
+  sim_cpu cpu[1];
+#if (WITH_SMP)
+#define STATE_CPU(sd,n) (&(sd)->cpu[n])
+#else
+#define STATE_CPU(sd,n) (&(sd)->cpu[0])
+#endif
+
+  sim_state_base base;
+};
+
+
+
+/* Status information: */
+
+/* TODO : these should be the bitmasks for these bits within the
+   status register. At the moment the following are VR4300
+   bit-positions: */
+#define status_KSU_mask  (0x3)          /* mask for KSU bits */
+#define status_KSU_shift (3)            /* shift for field */
+#define ksu_kernel       (0x0)
+#define ksu_supervisor   (0x1)
+#define ksu_user         (0x2)
+#define ksu_unknown      (0x3)
+
+#define status_IE       (1 <<  0)      /* Interrupt enable */
+#define status_EXL      (1 <<  1)      /* Exception level */
+#define status_RE        (1 << 25)      /* Reverse Endian in user mode */
+#define status_FR        (1 << 26)      /* enables MIPS III additional FP registers */
+#define status_SR        (1 << 20)      /* soft reset or NMI */
+#define status_BEV       (1 << 22)      /* Location of general exception vectors */
+#define status_TS        (1 << 21)      /* TLB shutdown has occurred */
+#define status_ERL       (1 <<  2)      /* Error level */
+#define status_RP        (1 << 27)      /* Reduced Power mode */
+
+#define cause_BD        ((unsigned)1 << 31)     /* Exception in branch delay slot */
+
+/* NOTE: We keep the following status flags as bit values (1 for true,
+   0 for false). This allows them to be used in binary boolean
+   operations without worrying about what exactly the non-zero true
+   value is. */
+
+/* UserMode */
+#define UserMode        ((((SR & status_KSU_mask) >> status_KSU_shift) == ksu_user) ? 1 : 0)
+
+/* BigEndianMem */
+/* Hardware configuration. Affects endianness of LoadMemory and
+   StoreMemory and the endianness of Kernel and Supervisor mode
+   execution. The value is 0 for little-endian; 1 for big-endian. */
+#define BigEndianMem    (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
+/*(state & simBE) ? 1 : 0)*/
+
+/* ReverseEndian */
+/* This mode is selected if in User mode with the RE bit being set in
+   SR (Status Register). It reverses the endianness of load and store
+   instructions. */
+#define ReverseEndian   (((SR & status_RE) && UserMode) ? 1 : 0)
+
+/* BigEndianCPU */
+/* The endianness for load and store instructions (0=little;1=big). In
+   User mode this endianness may be switched by setting the state_RE
+   bit in the SR register. Thus, BigEndianCPU may be computed as
+   (BigEndianMem EOR ReverseEndian). */
+#define BigEndianCPU    (BigEndianMem ^ ReverseEndian) /* Already bits */
+
+
+
+/* Exceptions: */
+
+/* NOTE: These numbers depend on the processor architecture being
+   simulated: */
+#define Interrupt               (0)
+#define TLBModification         (1)
+#define TLBLoad                 (2)
+#define TLBStore                (3)
+#define AddressLoad             (4)
+#define AddressStore            (5)
+#define InstructionFetch        (6)
+#define DataReference           (7)
+#define SystemCall              (8)
+#define BreakPoint              (9)
+#define ReservedInstruction     (10)
+#define CoProcessorUnusable     (11)
+#define IntegerOverflow         (12)    /* Arithmetic overflow (IDT monitor raises SIGFPE) */
+#define Trap                    (13)
+#define FPE                     (15)
+#define DebugBreakPoint         (16)
+#define Watch                   (23)
+
+/* The following exception code is actually private to the simulator
+   world. It is *NOT* a processor feature, and is used to signal
+   run-time errors in the simulator. */
+#define SimulatorFault      (0xFFFFFFFF)
+
+void signal_exception (SIM_DESC sd, address_word cia, int exception, ...);
+#define SignalException(exc,instruction)     signal_exception (sd, cia, (exc), (instruction))
+#define SignalExceptionInterrupt()           signal_exception (sd, NULL_CIA, Interrupt)
+#define SignalExceptionInstructionFetch()    signal_exception (sd, cia, InstructionFetch)
+#define SignalExceptionAddressStore()        signal_exception (sd, cia, AddressStore)
+#define SignalExceptionAddressLoad()         signal_exception (sd, cia, AddressLoad)
+#define SignalExceptionSimulatorFault(buf)   signal_exception (sd, cia, SimulatorFault, buf)
+#define SignalExceptionFPE()                 signal_exception (sd, cia, FPE)
+#define SignalExceptionIntegerOverflow()     signal_exception (sd, cia, IntegerOverflow)
+#define SignalExceptionCoProcessorUnusable() signal_exception (sd, cia, CoProcessorUnusable)
+
+
+/* Co-processor accesses */
+
+void cop_lw  PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg, unsigned int memword));
+void cop_ld  PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg, uword64 memword));
+unsigned int cop_sw PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg));
+uword64 cop_sd PARAMS ((SIM_DESC sd, address_word cia, int coproc_num, int coproc_reg));
+
+#define COP_LW(coproc_num,coproc_reg,memword) cop_lw(sd,cia,coproc_num,coproc_reg,memword)
+#define COP_LD(coproc_num,coproc_reg,memword) cop_ld(sd,cia,coproc_num,coproc_reg,memword)
+#define COP_SW(coproc_num,coproc_reg) cop_sw(sd,cia,coproc_num,coproc_reg)
+#define COP_SD(coproc_num,coproc_reg) cop_sd(sd,cia,coproc_num,coproc_reg)
+
+void decode_coproc PARAMS ((SIM_DESC sd, address_word cia, unsigned int instruction));
+#define DecodeCoproc(instruction) decode_coproc(sd, cia, (instruction))
+
+
+
+/* Memory accesses */
+
+/* The following are generic to all versions of the MIPS architecture
+   to date: */
+
+/* Memory Access Types (for CCA): */
+#define Uncached                (0)
+#define CachedNoncoherent       (1)
+#define CachedCoherent          (2)
+#define Cached                  (3)
+
+#define isINSTRUCTION   (1 == 0) /* FALSE */
+#define isDATA          (1 == 1) /* TRUE */
+#define isLOAD          (1 == 0) /* FALSE */
+#define isSTORE         (1 == 1) /* TRUE */
+#define isREAL          (1 == 0) /* FALSE */
+#define isRAW           (1 == 1) /* TRUE */
+/* The parameter HOST (isTARGET / isHOST) is ignored */
+#define isTARGET        (1 == 0) /* FALSE */
+/* #define isHOST          (1 == 1) TRUE */
+
+/* The "AccessLength" specifications for Loads and Stores. NOTE: This
+   is the number of bytes minus 1. */
+#define AccessLength_BYTE       (0)
+#define AccessLength_HALFWORD   (1)
+#define AccessLength_TRIPLEBYTE (2)
+#define AccessLength_WORD       (3)
+#define AccessLength_QUINTIBYTE (4)
+#define AccessLength_SEXTIBYTE  (5)
+#define AccessLength_SEPTIBYTE  (6)
+#define AccessLength_DOUBLEWORD (7)
+#define AccessLength_QUADWORD   (15)
+
+int address_translation PARAMS ((SIM_DESC sd, address_word cia, address_word vAddr, int IorD, int LorS, address_word *pAddr, int *CCA, int raw));
+#define AddressTranslation(vAddr,IorD,LorS,pAddr,CCA,host,raw) \
+address_translation(sd,cia,vAddr,IorD,LorS,pAddr,CCA,raw)
+
+void load_memory PARAMS ((SIM_DESC sd, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, int AccessLength, address_word pAddr, address_word vAddr, int IorD));
+#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
+load_memory(sd,cia,memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD)
+
+void store_memory PARAMS ((SIM_DESC sd, address_word cia, int CCA, int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr));
+#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
+store_memory(sd,cia,CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr)
+
+void cache_op PARAMS ((SIM_DESC sd, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction));
+#define CacheOp(op,pAddr,vAddr,instruction) cache_op(sd,cia,op,pAddr,vAddr,instruction)
+
+void sync_operation PARAMS ((SIM_DESC sd, address_word cia, int stype));
+#define SyncOperation(stype) sync_operation (sd, cia, (stype))
+
+void prefetch PARAMS ((SIM_DESC sd, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint));
+#define Prefetch(CCA,pAddr,vAddr,DATA,hint) prefetch(sd,cia,CCA,pAddr,vAddr,DATA,hint)
+
+unsigned32 ifetch32 PARAMS ((SIM_DESC sd, address_word cia, address_word vaddr));
+#define IMEM(CIA) ifetch32 (SD, (CIA), (CIA))
+
+void dotrace PARAMS ((SIM_DESC sd, FILE *tracefh, int type, SIM_ADDR address, int width, char *comment, ...));
+FILE *tracefh;
+
+#endif
diff --git a/sim/txvu/tconfig.in b/sim/txvu/tconfig.in
new file mode 100644 (file)
index 0000000..66f2b6f
--- /dev/null
@@ -0,0 +1,17 @@
+/* mips target configuration file.  */
+
+/* Define this if the simulator supports profiling.
+   See the mips simulator for an example.
+   This enables the `-p foo' and `-s bar' options.
+   The target is required to provide sim_set_profile{,_size}.  */
+#define SIM_HAVE_PROFILE
+
+/* Define this if the simulator uses an instruction cache.
+   See the h8/300 simulator for an example.
+   This enables the `-c size' option to set the size of the cache.
+   The target is required to provide sim_set_simcache_size.  */
+/* #define SIM_HAVE_SIMCACHE */
+
+/* Define this if the target cpu is bi-endian
+   and the simulator supports it.  */
+#define SIM_HAVE_BIENDIAN
diff --git a/sim/txvu/vr5400.igen b/sim/txvu/vr5400.igen
new file mode 100644 (file)
index 0000000..2e77ea2
--- /dev/null
@@ -0,0 +1,241 @@
+
+
+// Integer Instructions
+// --------------------
+//
+// MulAcc is the Multiply Accumulator.
+//     This register is mapped on the the HI and LO registers.
+//     Upper 32 bits of MulAcc is mapped on to lower 32 bits of HI register.
+//     Lower 32 bits of MulAcc is mapped on to lower 32 bits of LO register.
+
+
+:function:::unsigned64:MulAcc:
+{
+  unsigned64 result = U8_4 (HI, LO);
+  return result;
+}
+
+:function:::void:SET_MulAcc:unsigned64 value
+{
+  *AL4_8 (&HI) = VH4_8 (value);
+  *AL4_8 (&LO) = VL4_8 (value);
+}
+
+:function:::signed64:SignedMultiply:signed32 l, signed32 r
+{
+  signed64 result = (signed64) l * (signed64) r;
+  return result;
+}
+
+:function:::unsigned64:UnsignedMultiply:unsigned32 l, unsigned32 r
+{
+  unsigned64 result = (unsigned64) l * (unsigned64) r;
+  return result;
+}
+
+:function:::unsigned64:Low32Bits:unsigned64 value
+{
+  unsigned64 result = (signed64) (signed32) VL4_8 (value);
+  return result;
+}
+
+:function:::unsigned64:High32Bits:unsigned64 value
+{
+  unsigned64 result = (signed64) (signed32) VH4_8 (value);
+  return result;
+}
+
+
+
+// Multiply and Move LO.
+000000,5.RS,5.RT,5.RD,00001,011000::::MUL
+"mul r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 + SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply and Move LO.
+000000,5.RS,5.RT,5.RD,00001,011001::::MULU
+"mulu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 + UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Multiply and Move HI.
+000000,5.RS,5.RT,5.RD,01001,011000::::MULHI
+"mulhi r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 + SignedMultiply   (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply and Move HI.
+000000,5.RS,5.RT,5.RD,01001,011001::::MULHIU
+"mulhiu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 + UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+
+// Multiply, Negate and Move LO.
+000000,5.RS,5.RT,5.RD,00011,011000::::MULS
+"muls r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 - SignedMultiply   (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Negate and Move LO.
+000000,5.RS,5.RT,5.RD,00011,011001::::MULSU
+"mulsu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 - UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Multiply, Negate and Move HI.
+000000,5.RS,5.RT,5.RD,01011,011000::::MULSHI
+"mulshi r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 - SignedMultiply   (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Negate and Move HI.
+000000,5.RS,5.RT,5.RD,01011,011001::::MULSHIU
+"mulshiu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, 0 - UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+
+// Multiply, Accumulate and Move LO.
+000000,5.RS,5.RT,5.RD,00101,011000::::MACC
+"macc r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) + SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Accumulate and Move LO.
+000000,5.RS,5.RT,5.RD,00101,011001::::MACCU
+"maccu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) + UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Multiply, Accumulate and Move HI.
+000000,5.RS,5.RT,5.RD,01101,011000::::MACCHI
+"macchi r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) + SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Accumulate and Move HI.
+000000,5.RS,5.RT,5.RD,01101,011001::::MACCHIU
+"macchiu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) + UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+
+}
+
+// Multiply, Negate, Accumulate and Move LO.
+000000,5.RS,5.RT,5.RD,00111,011000::::MSAC
+"msac r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) - SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Negate, Accumulate and Move LO.
+000000,5.RS,5.RT,5.RD,00111,011001::::MSACU
+"msacu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) - UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = Low32Bits  (SD_, MulAcc (SD_));
+}
+
+// Multiply, Negate, Accumulate and Move HI.
+000000,5.RS,5.RT,5.RD,01111,011000::::MSACHI
+"msachi r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) - SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+// Unsigned Multiply, Negate, Accumulate and Move HI.
+000000,5.RS,5.RT,5.RD,01111,011001::::MSACHIU
+"msachiu r<RD>, r<RS>, r<RT>"
+*vr5400:
+{
+  SET_MulAcc (SD_, MulAcc (SD_) - UnsignedMultiply (SD_, GPR[RS], GPR[RT]));
+  GPR[RD] = High32Bits (SD_, MulAcc (SD_));
+}
+
+
+// Rotate Right.
+000000,00001,5.RT,5.RD,5.SHIFT,000010::::ROR
+"ror r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+{
+  int s = SHIFT;
+  GPR[RD] = ROTR32 (GPR[RT], s);
+}
+
+// Rotate Right Variable.
+000000,5.RS,5.RT,5.RD,00001,000110::::RORV
+"rorv r<RD>, r<RT>, <RS>"
+*vr5400:
+{
+  int s = MASKED (GPR[RS], 4, 0);
+  GPR[RD] = ROTR32 (GPR[RT], s);
+}
+
+// Double Rotate Right.
+000000,00001,5.RT,5.RD,5.SHIFT,111010::::DROR
+"dror r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+{
+  int s = SHIFT;
+  GPR[RD] = ROTR64 (GPR[RT], s);
+}
+
+// Double Rotate Right Plus 32.
+000000,00001,5.RT,5.RD,5.SHIFT,111110::::DROR32
+"dror32 r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+{
+  int s = SHIFT + 32;
+  GPR[RD] = ROTR64 (GPR[RT], s);
+}
+
+// Double Rotate Right Variable.
+000000,5.RS,5.RT,5.RD,00001,010110::::DRORV
+"drorv r<RD>, r<RT>, <RS>"
+*vr5400:
+{
+  int s = MASKED (GPR[RS], 5, 0);
+  GPR[RD] = ROTR64 (GPR[RT], s);
+}
diff --git a/sim/txvu/vu0.c b/sim/txvu/vu0.c
new file mode 100644 (file)
index 0000000..9c82b9f
--- /dev/null
@@ -0,0 +1,81 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "vu0.h"
+
+static char vu0_mem0_buffer[VU0_MEM0_SIZE];
+static char vu0_mem1_buffer[VU0_MEM1_SIZE];
+
+int
+vu0_io_read_buffer(device *me,
+                      void *dest,
+                      int space,
+                      address_word addr,
+                      unsigned nr_bytes,
+                      sim_cpu *processor,
+                      sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+       return nr_bytes;
+}
+
+int
+vu0_io_write_buffer(device *me,
+                    const void *source,
+                    int space,
+                    address_word addr,
+                    unsigned nr_bytes,
+                    sim_cpu *processor,
+                    sim_cia cia)
+{
+       printf("%s: Write!\n", me->name);
+       return nr_bytes;
+}
+
+device vu0_device = 
+  { 
+    "vu0", 
+    &vu0_io_read_buffer,
+    &vu0_io_write_buffer 
+  };
+
+void 
+vu0_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU0_REGISTER_WINDOW_START,
+                   VU0_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &vu0_device,
+                   NULL /*buffer*/);
+
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU0_MEM0_WINDOW_START,
+                   VU0_MEM0_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   0 /*device*/,
+                   &vu0_mem0_buffer /*buffer*/);
+
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU0_MEM1_WINDOW_START,
+                   VU0_MEM1_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   0 /*device*/,
+                   &vu0_mem1_buffer /*buffer*/);
+}
diff --git a/sim/txvu/vu0.h b/sim/txvu/vu0.h
new file mode 100644 (file)
index 0000000..021a6f6
--- /dev/null
@@ -0,0 +1,36 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef VU0_H_
+#define VU0_H_
+
+#include "sim-main.h"
+
+void vu0_attach(SIM_DESC sd);
+
+#define VU0_MEM0_WINDOW_START  0x11000000
+#define VU0_MEM0_SIZE                  0x1000  /* 4K = 4096 */
+
+#define VU0_MEM1_WINDOW_START  0x11004000
+#define VU0_MEM1_SIZE                  0x1000  /* 4K = 4096 */
+
+#define VU0_REGISTER_WINDOW_START 0x10000c00
+
+#define VU0_VF00               0x10000c00
+/* ... */
+#define VU0_VF31               0x10000df0
+
+#define VU0_VI00               0x10000e00
+/* ... */
+#define VU0_VI15               0x10000ef0
+
+/* ... */
+
+#define VPE0_STAT              0x10000fd0
+
+#define VU0_REGISTER_WINDOW_END   0x10000fe0
+
+#define VU0_REGISTER_WINDOW_SIZE (VU0_REGISTER_WINDOW_END - VU0_REGISTER_WINDOW_START)
+
+#endif
diff --git a/sim/txvu/vu1.c b/sim/txvu/vu1.c
new file mode 100644 (file)
index 0000000..049edd3
--- /dev/null
@@ -0,0 +1,85 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#include "sim-main.h"
+
+#include "device.h"
+#include "vu1.h"
+
+static char vu1_mem0_buffer[VU1_MEM0_SIZE];
+static char vu1_mem1_buffer[VU1_MEM1_SIZE];
+
+int
+vu1_io_read_buffer(device *me,
+                      void *dest,
+                      int space,
+                      address_word addr,
+                      unsigned nr_bytes,
+                      sim_cpu *processor,
+                      sim_cia cia)
+{
+       printf("%s: Read!\n", me->name);
+
+printf("    vu1_mem0[0] = %d\n", *(int*)&vu1_mem0_buffer[0]);
+printf("    vu1_mem1[0] = %d\n", *(int*)&vu1_mem1_buffer[0]);
+
+       return nr_bytes;
+}
+
+int
+vu1_io_write_buffer(device *me,
+                    const void *source,
+                    int space,
+                    address_word addr,
+                    unsigned nr_bytes,
+                    sim_cpu *processor,
+                    sim_cia cia)
+{
+       printf("%s: Write!\n", me->name);
+       return nr_bytes;
+}
+
+device vu1_device = 
+  { 
+    "vu1", 
+    &vu1_io_read_buffer,
+    &vu1_io_write_buffer 
+  };
+
+void 
+vu1_attach(SIM_DESC sd) 
+{
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU1_REGISTER_WINDOW_START,
+                   VU1_REGISTER_WINDOW_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   &vu1_device,
+                   NULL /*buffer*/);
+
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU1_MEM0_WINDOW_START,
+                   VU1_MEM0_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   0 /*device*/,
+                   &vu1_mem0_buffer /*buffer*/);
+
+  sim_core_attach (sd,
+                  NULL,
+                   0 /*level*/,
+                   access_read_write,
+                   0 /*space ???*/,
+                   VU1_MEM1_WINDOW_START,
+                   VU1_MEM1_SIZE /*nr_bytes*/,
+                   0 /*modulo*/,
+                   0 /*device*/,
+                   &vu1_mem1_buffer /*buffer*/);
+}
diff --git a/sim/txvu/vu1.h b/sim/txvu/vu1.h
new file mode 100644 (file)
index 0000000..f336361
--- /dev/null
@@ -0,0 +1,36 @@
+/*  Copyright (C) 1998, Cygnus Solutions
+
+    */
+
+#ifndef VU1_H_
+#define VU1_H_
+
+#include "sim-main.h"
+
+void vu1_attach(SIM_DESC sd);
+
+#define VU1_MEM0_WINDOW_START  0x11008000
+#define VU1_MEM0_SIZE          0x4000    /* 16K = 16384 */
+
+#define VU1_MEM1_WINDOW_START  0x1100c000
+#define VU1_MEM1_SIZE                  0x4000    /* 16K = 16384 */
+
+#define VU1_REGISTER_WINDOW_START 0x11007000
+
+#define VU1_VF00               0x11007000
+/* ... */
+#define VU1_VF31               0x110071f0
+
+#define VU1_VI00               0x11007200
+/* ... */
+#define VU1_VI15               0x110072f0
+
+/* ... */
+
+#define VPE1_STAT              0x11007370
+
+#define VU1_REGISTER_WINDOW_END   0x11007380
+
+#define VU1_REGISTER_WINDOW_SIZE (VU1_REGISTER_WINDOW_END - VU1_REGISTER_WINDOW_START)
+
+#endif