2003-01-04 Richard Sandiford <rsandifo@redhat.com>
authorChris Demetriou <cgd@google.com>
Sun, 5 Jan 2003 07:56:59 +0000 (07:56 +0000)
committerChris Demetriou <cgd@google.com>
Sun, 5 Jan 2003 07:56:59 +0000 (07:56 +0000)
    Andrew Cagney  <ac131313@redhat.com>
    Gavin Romig-Koch  <gavin@redhat.com>
    Graydon Hoare  <graydon@redhat.com>
    Aldy Hernandez  <aldyh@redhat.com>
    Dave Brolley  <brolley@redhat.com>
    Chris Demetriou  <cgd@broadcom.com>

* configure.in (mips64vr*): Define TARGET_ENABLE_FR to 1.
(sim_mach_default): New variable.
(mips64vr-*-*, mips64vrel-*-*): New configurations.
Add a new simulator generator, MULTI.
* configure: Regenerate.
* Makefile.in (SIM_MULTI_OBJ, SIM_EXTRA_DISTCLEAN): New variables.
(multi-run.o): New dependency.
(SIM_MULTI_ALL, SIM_MULTI_IGEN_CONFIGS): New variables.
(tmp-mach-multi, tmp-itable-multi, tmp-run-multi): New rules.
(tmp-multi): Combine them.
(BUILT_SRC_FROM_MULTI): New variable.  Depend on tmp-multi.
(clean-extra): Remove sources in BUILT_SRC_FROM_MULTI.
(distclean-extra): New rule.
* sim-main.h: Include bfd.h.
(MIPS_MACH): New macro.
* mips.igen (vr4120, vr5400, vr5500): New models.
(clo, clz, dclo, dclz, madd, maddu, msub, msub, mul): Add *vr5500.
* vr.igen: Replace with new version.

sim/mips/ChangeLog
sim/mips/Makefile.in
sim/mips/configure
sim/mips/configure.in
sim/mips/mips.igen
sim/mips/sim-main.h
sim/mips/vr.igen

index 75a59bdf169755dbe90de1acf4bc104dae3965cc..0cf73cbb33333c6d7f87aa304623a7645f59159b 100644 (file)
@@ -1,3 +1,30 @@
+2003-01-04  Richard Sandiford  <rsandifo@redhat.com>
+           Andrew Cagney  <ac131313@redhat.com>
+           Gavin Romig-Koch  <gavin@redhat.com>
+           Graydon Hoare  <graydon@redhat.com>
+           Aldy Hernandez  <aldyh@redhat.com>
+           Dave Brolley  <brolley@redhat.com>
+           Chris Demetriou  <cgd@broadcom.com>
+
+       * configure.in (mips64vr*): Define TARGET_ENABLE_FR to 1.
+       (sim_mach_default): New variable.
+       (mips64vr-*-*, mips64vrel-*-*): New configurations.
+       Add a new simulator generator, MULTI.
+       * configure: Regenerate.
+       * Makefile.in (SIM_MULTI_OBJ, SIM_EXTRA_DISTCLEAN): New variables.
+       (multi-run.o): New dependency.
+       (SIM_MULTI_ALL, SIM_MULTI_IGEN_CONFIGS): New variables.
+       (tmp-mach-multi, tmp-itable-multi, tmp-run-multi): New rules.
+       (tmp-multi): Combine them.
+       (BUILT_SRC_FROM_MULTI): New variable.  Depend on tmp-multi.
+       (clean-extra): Remove sources in BUILT_SRC_FROM_MULTI.
+       (distclean-extra): New rule.
+       * sim-main.h: Include bfd.h.
+       (MIPS_MACH): New macro.
+       * mips.igen (vr4120, vr5400, vr5500): New models.
+       (clo, clz, dclo, dclz, madd, maddu, msub, msub, mul): Add *vr5500.
+       * vr.igen: Replace with new version.
+
 2003-01-04  Chris Demetriou  <cgd@broadcom.com>
 
        * configure.in: Use SIM_AC_OPTION_RESERVED_BITS(1).
index e0e9fafcafeaf718644713a6a6fd75e2cc64094b..72ec4ab6905f89da7223ab9e55139927211ee9b3 100644 (file)
@@ -33,6 +33,7 @@ SIM_M16_OBJ = \
        itable.o \
        m16run.o \
 
+SIM_MULTI_OBJ = itable.o @sim_multi_obj@
 
 MIPS_EXTRA_OBJS = @mips_extra_objs@
 MIPS_EXTRA_LIBS = @mips_extra_libs@
@@ -57,6 +58,7 @@ SIM_SUBTARGET=@SIM_SUBTARGET@
 SIM_EXTRA_CFLAGS = $(SIM_SUBTARGET)
 
 SIM_EXTRA_CLEAN = clean-extra
+SIM_EXTRA_DISTCLEAN = distclean-extra
 
 SIM_EXTRA_ALL = $(SIM_@sim_gen@_ALL)
 
@@ -74,6 +76,8 @@ cp1.o: $(srcdir)/cp1.c config.h sim-main.h
 
 mdmx.o: $(srcdir)/mdmx.c $(srcdir)/sim-main.h
 
+multi-run.o: multi-include.h tmp-mach-multi
+
 ../igen/igen:
        cd ../igen && $(MAKE)
 
@@ -98,6 +102,7 @@ BUILT_SRC_FROM_GEN = \
 
 SIM_IGEN_ALL = tmp-igen
 SIM_M16_ALL = tmp-m16
+SIM_MULTI_ALL = tmp-multi
 
 $(BUILT_SRC_FROM_GEN): $(SIM_@sim_gen@_ALL)
 
@@ -291,10 +296,99 @@ tmp-m16: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
        touch tmp-m16
 
 
+BUILT_SRC_FROM_MULTI = @sim_multi_src@
+SIM_MULTI_IGEN_CONFIGS = @sim_multi_igen_configs@
+
+$(BUILT_SRC_FROM_MULTI): tmp-multi
+tmp-multi: tmp-mach-multi tmp-itable-multi tmp-run-multi targ-vals.h
+tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+       for t in $(SIM_MULTI_IGEN_CONFIGS); do \
+         p=`echo $${t} | sed -e 's/:.*//'` ; \
+         m=`echo $${t} | sed -e 's/.*:\(.*\):.*/\1/'` ; \
+         f=`echo $${t} | sed -e 's/.*://'` ; \
+         case $${p} in \
+           m16*) e="-B 16 -H 15 -o $(M16_DC) -F 16" ;; \
+           *) e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}" ;; \
+         esac; \
+         ../igen/igen \
+               $(IGEN_TRACE) \
+               $${e} \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               -N 0 \
+               -M $${m} \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -i $(IGEN_INSN) \
+               -P $${p}_ \
+               -x \
+               -n $${p}_icache.h    -hc tmp-icache.h \
+               -n $${p}_icache.c    -c  tmp-icache.c \
+               -n $${p}_semantics.h -hs tmp-semantics.h \
+               -n $${p}_semantics.c -s  tmp-semantics.c \
+               -n $${p}_idecode.h   -hd tmp-idecode.h \
+               -n $${p}_idecode.c   -d  tmp-idecode.c \
+               -n $${p}_model.h     -hm tmp-model.h \
+               -n $${p}_model.c     -m  tmp-model.c \
+               -n $${p}_support.h   -hf tmp-support.h \
+               -n $${p}_support.c   -f  tmp-support.c \
+               -n $${p}_engine.h    -he tmp-engine.h \
+               -n $${p}_engine.c    -e  tmp-engine.c \
+               ; \
+         $(srcdir)/../../move-if-change tmp-icache.h $${p}_icache.h ; \
+         $(srcdir)/../../move-if-change tmp-icache.c $${p}_icache.c ; \
+         $(srcdir)/../../move-if-change tmp-idecode.h $${p}_idecode.h ; \
+         $(srcdir)/../../move-if-change tmp-idecode.c $${p}_idecode.c ; \
+         $(srcdir)/../../move-if-change tmp-semantics.h $${p}_semantics.h ; \
+         $(srcdir)/../../move-if-change tmp-semantics.c $${p}_semantics.c ; \
+         $(srcdir)/../../move-if-change tmp-model.h $${p}_model.h ; \
+         $(srcdir)/../../move-if-change tmp-model.c $${p}_model.c ; \
+         $(srcdir)/../../move-if-change tmp-support.h $${p}_support.h ; \
+         $(srcdir)/../../move-if-change tmp-support.c $${p}_support.c ; \
+         $(srcdir)/../../move-if-change tmp-engine.h $${p}_engine.h ; \
+         $(srcdir)/../../move-if-change tmp-engine.c $${p}_engine.c ; \
+       done
+       touch tmp-mach-multi
+tmp-itable-multi: $(IGEN_INSN) $(IGEN_DC) ../igen/igen $(IGEN_INCLUDE)
+       ../igen/igen \
+               $(IGEN_TRACE) \
+               -I $(srcdir) \
+               -Werror \
+               -Wnodiscard \
+               -Wnowidth \
+               -N 0 \
+               @sim_multi_flags@ \
+               -G gen-direct-access \
+               -G gen-zero-r0 \
+               -i $(IGEN_INSN) \
+               -n itable.h    -ht tmp-itable.h \
+               -n itable.c    -t  tmp-itable.c \
+               #
+       $(srcdir)/../../move-if-change tmp-itable.h itable.h
+       $(srcdir)/../../move-if-change tmp-itable.c itable.c
+       touch tmp-itable-multi
+tmp-run-multi: $(srcdir)/m16run.c
+       for t in $(SIM_MULTI_IGEN_CONFIGS); do \
+         case $${t} in \
+           *:*mips16*:*) \
+             m=`echo $${t} | sed -e 's/^m16//' -e 's/:.*//'`; \
+             sed <  $(srcdir)/m16run.c > tmp-run \
+                   -e "s/^sim_/m16$${m}_/" \
+                   -e "s/m16_/m16$${m}_/" \
+                   -e "s/m32_/m32$${m}_/" ; \
+             $(srcdir)/../../move-if-change tmp-run m16$${m}_run.c ; \
+         esac \
+       done
+       touch tmp-run-multi
+
 clean-extra:
        rm -f $(BUILT_SRC_FROM_GEN)
        rm -f $(BUILT_SRC_FROM_IGEN)
        rm -f $(BUILT_SRC_FROM_M16)
+       rm -f $(BUILT_SRC_FROM_MULTI)
        rm -f tmp-*
        rm -f m16*.o m32*.o itable*.o
 
+distclean-extra:
+       rm -f multi-include.h multi-run.c
index 4d009d803b8c4d3c4c0b483af9312f267a1a9793..a0471b3c752588284bf385a2e46f3440e1002a7f 100755 (executable)
@@ -3831,6 +3831,7 @@ fi
 # in question.
 #
 case "${target}" in
+  mips64vr*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1" ;;
   mips*tx39*)           SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
   mipsisa32*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";;
   mipsisa64*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";;
@@ -4063,6 +4064,8 @@ sim_igen_machine="-M mipsIV"
 sim_m16_machine="-M mips16"
 sim_igen_filter="32,64,f"
 sim_m16_filter="16"
+sim_mach_default="mips8000"
+
 case "${target}" in
   mips*tx39*)          sim_gen=IGEN
                        sim_igen_filter="32,f"
@@ -4070,16 +4073,29 @@ case "${target}" in
                        ;;
   mips64vr43*-*-*)     sim_gen=IGEN
                        sim_igen_machine="-M mipsIV"
+                       sim_mach_default="mips8000"
                        ;;
   mips64vr5*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M vr5000"
+                       sim_mach_default="mips5000"
                        ;;
   mips64vr41*)         sim_gen=M16
                        sim_igen_machine="-M vr4100"
                        sim_m16_machine="-M vr4100"
                        sim_igen_filter="32,64,f"
                        sim_m16_filter="16"
+                       sim_mach_default="mips4100"
                         ;;
+  mips64vr-*-* | mips64vrel-*-*)
+                       sim_gen=MULTI
+                       sim_multi_configs="\
+                         vr4100:mipsIII,mips16,vr4100:32,64:mips4100,mips4111\
+                         vr4120:mipsIII,mips16,vr4120:32,64:mips4120\
+                         vr5000:mipsIV:32,64,f:mips4300,mips5000\
+                         vr5400:mipsIV,vr5400:32,64,f:mips5400\
+                         vr5500:mipsIV,vr5500:32,64,f:mips5500"
+                       sim_multi_default=mips5000
+                       ;;
   mips64*-*-*)         sim_igen_filter="32,64,f"
                        sim_gen=IGEN
                        ;;
@@ -4090,25 +4106,232 @@ case "${target}" in
   mipsisa32*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M mips32"
                        sim_igen_filter="32,f"
+                       sim_mach_default="mipsisa32"
                        ;;
   mipsisa64sb1*-*-*)   sim_gen=IGEN
                        sim_igen_machine="-M mips64,sb1"
                        sim_igen_filter="32,64,f"
+                       sim_mach_default="mips_sb1"
                        ;;
   mipsisa64*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M mips64,mips3d"
                        sim_igen_filter="32,64,f"
+                       sim_mach_default="mipsisa64"
                        ;;
   mips*lsi*)           sim_gen=M16
                        sim_igen_machine="-M mipsIII,mips16"
                        sim_m16_machine="-M mips16,mipsIII"
                        sim_igen_filter="32,f"
                        sim_m16_filter="16"
+                       sim_mach_default="mips4000"
                         ;;
   mips*-*-*)           sim_gen=IGEN
                        sim_igen_filter="32,f"
                        ;;
 esac
+
+# The MULTI generator can combine several simulation engines into one.
+# executable.  A configuration which uses the MULTI should set two
+# variables: ${sim_multi_configs} and ${sim_multi_default}.
+#
+# ${sim_multi_configs} is the list of engines to build.  Each
+# space-separated entry has the form NAME:MACHINE:FILTER:BFDMACHS,
+# where:
+#
+# - NAME is a C-compatible prefix for the engine,
+# - MACHINE is a -M argument,
+# - FILTER is a -F argument, and
+# - BFDMACHS is a comma-separated list of bfd machines that the
+#     simulator can run.
+#
+# Each entry will have a separate simulation engine whose prefix is
+# m32<NAME>.  If the machine list includes "mips16", there will also
+# be a mips16 engine, prefix m16<NAME>.  The mips16 engine will be
+# generated using the same machine list as the 32-bit version,
+# but the filter will be "16" instead of FILTER.
+#
+# The simulator compares the bfd mach against BFDMACHS to decide
+# which engine to use.  Entries in BFDMACHS should be bfd_mach
+# values with "bfd_mach_" removed.  ${sim_multi_default} says
+# which entry should be the default.
+if test ${sim_gen} = MULTI; then
+
+  # Simple sanity check.
+  if test -z "${sim_multi_configs}" || test -z "${sim_multi_default}"; then
+    { echo "configure: error: Error in configure.in: MULTI simulator not set up correctly" 1>&2; exit 1; }
+  fi
+
+  # Start in a known state.
+  rm -f multi-include.h multi-run.c
+  sim_multi_flags=
+  sim_multi_src=
+  sim_multi_obj=multi-run.o
+  sim_multi_igen_configs=
+  sim_seen_default=no
+
+  cat << __EOF__ > multi-run.c
+/* Main entry point for MULTI simulators.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+   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.
+
+   --
+
+   This file was generated by sim/mips/configure.  */
+
+#include "sim-main.h"
+#include "multi-include.h"
+
+#define SD sd
+#define CPU cpu
+
+void
+sim_engine_run (SIM_DESC sd,
+               int next_cpu_nr,
+               int nr_cpus,
+               int signal) /* ignore */
+{
+  int mach;
+
+  if (STATE_ARCHITECTURE (sd) == NULL)
+    mach = bfd_mach_${sim_multi_default};
+  else
+    mach = STATE_ARCHITECTURE (SD)->mach;
+
+  switch (mach)
+    {
+__EOF__
+
+  for fc in ${sim_multi_configs}; do
+
+    # Split up the entry.  ${c} contains the first three elements.
+    # Note: outer sqaure brackets are m4 quotes.
+    c=`echo ${fc} | sed 's/:[^:]*$//'`
+    bfdmachs=`echo ${fc} | sed 's/.*://'`
+    name=`echo ${c} | sed 's/:.*//'`
+    machine=`echo ${c} | sed 's/.*:\(.*\):.*/\1/'`
+    filter=`echo ${c} | sed 's/.*://'`
+
+    # Build the following lists:
+    #
+    #   sim_multi_flags: all -M and -F flags used by the simulator
+    #   sim_multi_src: all makefile-generated source files
+    #   sim_multi_obj: the objects for ${sim_multi_src}
+    #   sim_multi_igen_configs: igen configuration strings.
+    #
+    # Each entry in ${sim_multi_igen_configs} is a prefix (m32
+    # or m16) followed by the NAME, MACHINE and FILTER part of
+    # the ${sim_multi_configs} entry.
+    sim_multi_flags="${sim_multi_flags} -F ${filter} -M ${machine}"
+
+    # Check whether mips16 handling is needed.
+    case ${c} in
+      *:*mips16*:*)
+       # Run igen twice, once for normal mode and once for mips16.
+       ws="m32 m16"
+
+       # The top-level function for the mips16 simulator is
+       # in a file m16${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} m16${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} m16${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16"
+       ;;
+      *)
+       ws=m32
+       ;;
+    esac
+
+    # Now add the list of igen-generated files to ${sim_multi_src}
+    # and ${sim_multi_obj}.
+    for w in ${ws}; do
+      for base in engine icache idecode model semantics support; do
+       sim_multi_src="${sim_multi_src} ${w}${name}_${base}.c"
+       sim_multi_src="${sim_multi_src} ${w}${name}_${base}.h"
+       sim_multi_obj="${sim_multi_obj} ${w}${name}_${base}.o"
+      done
+      sim_multi_igen_configs="${sim_multi_igen_configs} ${w}${c}"
+    done
+
+    # Add an include for the engine.h file.  This file declares the
+    # top-level foo_engine_run() function.
+    echo "#include \"${w}${name}_engine.h\"" >> multi-include.h
+
+    # Add case statements for this engine to sim_engine_run().
+    for mach in `echo ${bfdmachs} | sed 's/,/ /g'`; do
+      echo "    case bfd_mach_${mach}:" >> multi-run.c
+      if test ${mach} = ${sim_multi_default}; then
+       echo "    default:" >> multi-run.c
+       sim_seen_default=yes
+      fi
+    done
+    echo "      ${w}${name}_engine_run (sd, next_cpu_nr, nr_cpus, signal);" \
+      >> multi-run.c
+    echo "      break;" >> multi-run.c
+  done
+
+  # Check whether we added a 'default:' label.
+  if test ${sim_seen_default} = no; then
+    { echo "configure: error: Error in configure.in: \${sim_multi_configs} doesn't have an entry for \${sim_multi_default}" 1>&2; exit 1; }
+  fi
+
+  cat << __EOF__ >> multi-run.c
+    }
+}
+
+int
+mips_mach_multi (SIM_DESC sd)
+{
+  if (STATE_ARCHITECTURE (sd) == NULL)
+    return bfd_mach_${sim_multi_default};
+
+  switch (STATE_ARCHITECTURE (SD)->mach)
+    {
+__EOF__
+
+  # Add case statements for this engine to mips_mach_multi().
+  for fc in ${sim_multi_configs}; do
+
+    # Split up the entry.  ${c} contains the first three elements.
+    # Note: outer sqaure brackets are m4 quotes.
+    c=`echo ${fc} | sed 's/:[^:]*$//'`
+    bfdmachs=`echo ${fc} | sed 's/.*://'`
+
+    for mach in `echo ${bfdmachs} | sed 's/,/ /g'`; do
+      echo "    case bfd_mach_${mach}:" >> multi-run.c
+    done
+  done
+
+  cat << __EOF__ >> multi-run.c
+      return (STATE_ARCHITECTURE (SD)->mach);
+    default:
+      return bfd_mach_${sim_multi_default};
+    }
+}
+__EOF__
+
+  SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_MULTI"
+else
+  # For clean-extra
+  sim_multi_src=doesnt-exist.c
+
+  if test x"${sim_mach_default}" = x""; then
+    { echo "configure: error: Error in configure.in: \${sim_mach_default} not defined" 1>&2; exit 1; }
+  fi
+  SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_DEFAULT=bfd_mach_${sim_mach_default}"
+fi
 sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
 sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}  ${sim_igen_smp}"
 
@@ -4116,6 +4339,10 @@ sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}  ${sim_igen_smp}"
 
 
 
+
+
+
+
 #
 # Add simulated hardware devices
 #
@@ -4204,7 +4431,7 @@ esac
 # Uses ac_ vars as temps to allow command line to override cache and checks.
 # --without-x overrides everything else, but does not touch the cache.
 echo $ac_n "checking for X""... $ac_c" 1>&6
-echo "configure:4208: checking for X" >&5
+echo "configure:4435: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -4266,12 +4493,12 @@ if test "$ac_x_includes" = NO; then
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 4270 "configure"
+#line 4497 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4340,14 +4567,14 @@ if test "$ac_x_libraries" = NO; then
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4344 "configure"
+#line 4571 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:4351: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
 # We can link X programs with no special library path.
@@ -4440,17 +4667,17 @@ 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:4444: checking for $ac_hdr" >&5
+echo "configure:4671: 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 4449 "configure"
+#line 4676 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4454: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4681: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4477,7 +4704,7 @@ fi
 done
 
 echo $ac_n "checking for fabs in -lm""... $ac_c" 1>&6
-echo "configure:4481: checking for fabs in -lm" >&5
+echo "configure:4708: 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
@@ -4485,7 +4712,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 4489 "configure"
+#line 4716 "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
@@ -4496,7 +4723,7 @@ int main() {
 fabs()
 ; return 0; }
 EOF
-if { (eval echo configure:4500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -4526,12 +4753,12 @@ fi
 for ac_func in aint anint sqrt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4530: checking for $ac_func" >&5
+echo "configure:4757: 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 4535 "configure"
+#line 4762 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -4554,7 +4781,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:4558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -4793,6 +5020,10 @@ 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
+s%@sim_multi_flags@%$sim_multi_flags%g
+s%@sim_multi_igen_configs@%$sim_multi_igen_configs%g
+s%@sim_multi_src@%$sim_multi_src%g
+s%@sim_multi_obj@%$sim_multi_obj%g
 s%@mips_extra_objs@%$mips_extra_objs%g
 s%@mips_igen_engine@%$mips_igen_engine%g
 s%@mips_extra_libs@%$mips_extra_libs%g
index b24225470db4aec403d72667107465e8d6a9b313..1ea4901f87cc8ef51ec28ed5c26694a6d8f387f2 100644 (file)
@@ -19,6 +19,7 @@ SIM_AC_OPTION_RESERVED_BITS(1)
 # in question.
 #
 case "${target}" in
+  mips64vr*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1" ;;
   mips*tx39*)           SIM_SUBTARGET="-DSUBTARGET_R3900=1";;
   mipsisa32*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";;
   mipsisa64*-*-*)       SIM_SUBTARGET="-DTARGET_ENABLE_FR=1";;
@@ -101,6 +102,8 @@ sim_igen_machine="-M mipsIV"
 sim_m16_machine="-M mips16"
 sim_igen_filter="32,64,f"
 sim_m16_filter="16"
+sim_mach_default="mips8000"
+
 case "${target}" in
   mips*tx39*)          sim_gen=IGEN
                        sim_igen_filter="32,f"
@@ -108,16 +111,29 @@ case "${target}" in
                        ;;
   mips64vr43*-*-*)     sim_gen=IGEN
                        sim_igen_machine="-M mipsIV"
+                       sim_mach_default="mips8000"
                        ;;
   mips64vr5*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M vr5000"
+                       sim_mach_default="mips5000"
                        ;;
   mips64vr41*)         sim_gen=M16
                        sim_igen_machine="-M vr4100"
                        sim_m16_machine="-M vr4100"
                        sim_igen_filter="32,64,f"
                        sim_m16_filter="16"
+                       sim_mach_default="mips4100"
                         ;;
+  mips64vr-*-* | mips64vrel-*-*)
+                       sim_gen=MULTI
+                       sim_multi_configs="\
+                         vr4100:mipsIII,mips16,vr4100:32,64:mips4100,mips4111\
+                         vr4120:mipsIII,mips16,vr4120:32,64:mips4120\
+                         vr5000:mipsIV:32,64,f:mips4300,mips5000\
+                         vr5400:mipsIV,vr5400:32,64,f:mips5400\
+                         vr5500:mipsIV,vr5500:32,64,f:mips5500"
+                       sim_multi_default=mips5000
+                       ;;
   mips64*-*-*)         sim_igen_filter="32,64,f"
                        sim_gen=IGEN
                        ;;
@@ -128,30 +144,241 @@ case "${target}" in
   mipsisa32*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M mips32"
                        sim_igen_filter="32,f"
+                       sim_mach_default="mipsisa32"
                        ;;
   mipsisa64sb1*-*-*)   sim_gen=IGEN
                        sim_igen_machine="-M mips64,sb1"
                        sim_igen_filter="32,64,f"
+                       sim_mach_default="mips_sb1"
                        ;;
   mipsisa64*-*-*)      sim_gen=IGEN
                        sim_igen_machine="-M mips64,mips3d"
                        sim_igen_filter="32,64,f"
+                       sim_mach_default="mipsisa64"
                        ;;
   mips*lsi*)           sim_gen=M16
                        sim_igen_machine="-M mipsIII,mips16"
                        sim_m16_machine="-M mips16,mipsIII"
                        sim_igen_filter="32,f"
                        sim_m16_filter="16"
+                       sim_mach_default="mips4000"
                         ;;
   mips*-*-*)           sim_gen=IGEN
                        sim_igen_filter="32,f"
                        ;;
 esac
+
+# The MULTI generator can combine several simulation engines into one.
+# executable.  A configuration which uses the MULTI should set two
+# variables: ${sim_multi_configs} and ${sim_multi_default}.
+#
+# ${sim_multi_configs} is the list of engines to build.  Each
+# space-separated entry has the form NAME:MACHINE:FILTER:BFDMACHS,
+# where:
+#
+# - NAME is a C-compatible prefix for the engine,
+# - MACHINE is a -M argument,
+# - FILTER is a -F argument, and
+# - BFDMACHS is a comma-separated list of bfd machines that the
+#     simulator can run.
+#
+# Each entry will have a separate simulation engine whose prefix is
+# m32<NAME>.  If the machine list includes "mips16", there will also
+# be a mips16 engine, prefix m16<NAME>.  The mips16 engine will be
+# generated using the same machine list as the 32-bit version,
+# but the filter will be "16" instead of FILTER.
+#
+# The simulator compares the bfd mach against BFDMACHS to decide
+# which engine to use.  Entries in BFDMACHS should be bfd_mach
+# values with "bfd_mach_" removed.  ${sim_multi_default} says
+# which entry should be the default.
+if test ${sim_gen} = MULTI; then
+
+  # Simple sanity check.
+  if test -z "${sim_multi_configs}" || test -z "${sim_multi_default}"; then
+    AC_MSG_ERROR(Error in configure.in: MULTI simulator not set up correctly)
+  fi
+
+  # Start in a known state.
+  rm -f multi-include.h multi-run.c
+  sim_multi_flags=
+  sim_multi_src=
+  sim_multi_obj=multi-run.o
+  sim_multi_igen_configs=
+  sim_seen_default=no
+
+  cat << __EOF__ > multi-run.c
+/* Main entry point for MULTI simulators.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+   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.
+
+   --
+
+   This file was generated by sim/mips/configure.  */
+
+#include "sim-main.h"
+#include "multi-include.h"
+
+#define SD sd
+#define CPU cpu
+
+void
+sim_engine_run (SIM_DESC sd,
+               int next_cpu_nr,
+               int nr_cpus,
+               int signal) /* ignore */
+{
+  int mach;
+
+  if (STATE_ARCHITECTURE (sd) == NULL)
+    mach = bfd_mach_${sim_multi_default};
+  else
+    mach = STATE_ARCHITECTURE (SD)->mach;
+
+  switch (mach)
+    {
+__EOF__
+
+  for fc in ${sim_multi_configs}; do
+
+    # Split up the entry.  ${c} contains the first three elements.
+    # Note: outer sqaure brackets are m4 quotes.
+    c=`echo ${fc} | sed ['s/:[^:]*$//']`
+    bfdmachs=`echo ${fc} | sed 's/.*://'`
+    name=`echo ${c} | sed 's/:.*//'`
+    machine=`echo ${c} | sed 's/.*:\(.*\):.*/\1/'`
+    filter=`echo ${c} | sed 's/.*://'`
+
+    # Build the following lists:
+    #
+    #   sim_multi_flags: all -M and -F flags used by the simulator
+    #   sim_multi_src: all makefile-generated source files
+    #   sim_multi_obj: the objects for ${sim_multi_src}
+    #   sim_multi_igen_configs: igen configuration strings.
+    #
+    # Each entry in ${sim_multi_igen_configs} is a prefix (m32
+    # or m16) followed by the NAME, MACHINE and FILTER part of
+    # the ${sim_multi_configs} entry.
+    sim_multi_flags="${sim_multi_flags} -F ${filter} -M ${machine}"
+
+    # Check whether mips16 handling is needed.
+    case ${c} in
+      *:*mips16*:*)
+       # Run igen twice, once for normal mode and once for mips16.
+       ws="m32 m16"
+
+       # The top-level function for the mips16 simulator is
+       # in a file m16${name}_run.c, generated by the
+       # tmp-run-multi Makefile rule.
+       sim_multi_src="${sim_multi_src} m16${name}_run.c"
+       sim_multi_obj="${sim_multi_obj} m16${name}_run.o"
+       sim_multi_flags="${sim_multi_flags} -F 16"
+       ;;
+      *)
+       ws=m32
+       ;;
+    esac
+
+    # Now add the list of igen-generated files to ${sim_multi_src}
+    # and ${sim_multi_obj}.
+    for w in ${ws}; do
+      for base in engine icache idecode model semantics support; do
+       sim_multi_src="${sim_multi_src} ${w}${name}_${base}.c"
+       sim_multi_src="${sim_multi_src} ${w}${name}_${base}.h"
+       sim_multi_obj="${sim_multi_obj} ${w}${name}_${base}.o"
+      done
+      sim_multi_igen_configs="${sim_multi_igen_configs} ${w}${c}"
+    done
+
+    # Add an include for the engine.h file.  This file declares the
+    # top-level foo_engine_run() function.
+    echo "#include \"${w}${name}_engine.h\"" >> multi-include.h
+
+    # Add case statements for this engine to sim_engine_run().
+    for mach in `echo ${bfdmachs} | sed 's/,/ /g'`; do
+      echo "    case bfd_mach_${mach}:" >> multi-run.c
+      if test ${mach} = ${sim_multi_default}; then
+       echo "    default:" >> multi-run.c
+       sim_seen_default=yes
+      fi
+    done
+    echo "      ${w}${name}_engine_run (sd, next_cpu_nr, nr_cpus, signal);" \
+      >> multi-run.c
+    echo "      break;" >> multi-run.c
+  done
+
+  # Check whether we added a 'default:' label.
+  if test ${sim_seen_default} = no; then
+    AC_MSG_ERROR(Error in configure.in: \${sim_multi_configs} doesn't have an entry for \${sim_multi_default})
+  fi
+
+  cat << __EOF__ >> multi-run.c
+    }
+}
+
+int
+mips_mach_multi (SIM_DESC sd)
+{
+  if (STATE_ARCHITECTURE (sd) == NULL)
+    return bfd_mach_${sim_multi_default};
+
+  switch (STATE_ARCHITECTURE (SD)->mach)
+    {
+__EOF__
+
+  # Add case statements for this engine to mips_mach_multi().
+  for fc in ${sim_multi_configs}; do
+
+    # Split up the entry.  ${c} contains the first three elements.
+    # Note: outer sqaure brackets are m4 quotes.
+    c=`echo ${fc} | sed ['s/:[^:]*$//']`
+    bfdmachs=`echo ${fc} | sed 's/.*://'`
+
+    for mach in `echo ${bfdmachs} | sed 's/,/ /g'`; do
+      echo "    case bfd_mach_${mach}:" >> multi-run.c
+    done
+  done
+
+  cat << __EOF__ >> multi-run.c
+      return (STATE_ARCHITECTURE (SD)->mach);
+    default:
+      return bfd_mach_${sim_multi_default};
+    }
+}
+__EOF__
+
+  SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_MULTI"
+else
+  # For clean-extra
+  sim_multi_src=doesnt-exist.c
+
+  if test x"${sim_mach_default}" = x""; then
+    AC_MSG_ERROR(Error in configure.in: \${sim_mach_default} not defined)
+  fi
+  SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_DEFAULT=bfd_mach_${sim_mach_default}"
+fi
 sim_igen_flags="-F ${sim_igen_filter} ${sim_igen_machine} ${sim_igen_smp}"
 sim_m16_flags=" -F ${sim_m16_filter}  ${sim_m16_machine}  ${sim_igen_smp}"
 AC_SUBST(sim_igen_flags)
 AC_SUBST(sim_m16_flags)
 AC_SUBST(sim_gen)
+AC_SUBST(sim_multi_flags)
+AC_SUBST(sim_multi_igen_configs)
+AC_SUBST(sim_multi_src)
+AC_SUBST(sim_multi_obj)
 
 
 #
index 3d4eeb0f9ccfc79294da773c9aa854959a6d2e28..fece487e10d6a3a9844b8b59fd12fdd57125796e 100644 (file)
 //  (or which pre-date or use different encodings than the standard
 //  instructions) are (for the most part) in separate .igen files.
 :model:::vr4100:mips4100:              // vr.igen
+:model:::vr4120:mips4120:
 :model:::vr5000:mips5000:
+:model:::vr5400:mips5400:
+:model:::vr5500:mips5500:
 :model:::r3900:mips3900:               // tx.igen
 
 //  MIPS Application Specific Extensions (ASEs)
 "clo r<RD>, r<RS>"
 *mips32:
 *mips64:
+*vr5500:
 {
   unsigned32 temp = GPR[RS];
   unsigned32 i, mask;
 "clz r<RD>, r<RS>"
 *mips32:
 *mips64:
+*vr5500:
 {
   unsigned32 temp = GPR[RS];
   unsigned32 i, mask;
 011100,5.RS,5.RT,5.RD,00000,100101:SPECIAL2:64::DCLO
 "dclo r<RD>, r<RS>"
 *mips64:
+*vr5500:
 {
   unsigned64 temp = GPR[RS];
   unsigned32 i;
 011100,5.RS,5.RT,5.RD,00000,100100:SPECIAL2:64::DCLZ
 "dclz r<RD>, r<RS>"
 *mips64:
+*vr5500:
 {
   unsigned64 temp = GPR[RS];
   unsigned32 i;
 "madd r<RS>, r<RT>"
 *mips32:
 *mips64:
+*vr5500:
 {
   signed64 temp;
   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
 "maddu r<RS>, r<RT>"
 *mips32:
 *mips64:
+*vr5500:
 {
   unsigned64 temp;
   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
 "msub r<RS>, r<RT>"
 *mips32:
 *mips64:
+*vr5500:
 {
   signed64 temp;
   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
 "msubu r<RS>, r<RT>"
 *mips32:
 *mips64:
+*vr5500:
 {
   unsigned64 temp;
   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
 "mul r<RD>, r<RS>, r<RT>"
 *mips32:
 *mips64:
+*vr5500:
 {
   signed64 prod;
   if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
index 3cb9b35223e6dffef603bc19dcce71ce91b314e6..2f3ffa40bb555c9f63e39dac1bf4c5f99d7d14de 100644 (file)
@@ -1,5 +1,5 @@
 /* MIPS Simulator definition.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 2003 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
 This file is part of GDB, the GNU debugger.
@@ -41,7 +41,7 @@ mips_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ER
 typedef address_word sim_cia;
 
 #include "sim-base.h"
-
+#include "bfd.h"
 
 /* Deprecated macros and types for manipulating 64bit values.  Use
    ../common/sim-bits.h and ../common/sim-endian.h macros instead. */
@@ -946,6 +946,12 @@ void mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word pc);
 void mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception);
 void mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception);
 
+#ifdef MIPS_MACH_MULTI
+extern int mips_mach_multi(SIM_DESC sd);
+#define MIPS_MACH(SD)  mips_mach_multi(SD)
+#else
+#define        MIPS_MACH(SD)   MIPS_MACH_DEFAULT
+#endif
 
 #if H_REVEALS_MODULE_P (SIM_MAIN_INLINE)
 #include "sim-main.c"
index 863bb556229cb72203f21bcd451c552e9055fc93..0eb5f4de2d9df1a463e93a172a2e0675922070db 100644 (file)
 // NEC specific instructions
 //
 
-// 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.
+:%s::::MFHI:int hi
+{
+  return hi ? "hi" : "";
+}
 
+:%s::::SAT:int s
+{
+  return s ? "s" : "";
+}
 
-:function:::unsigned64:MulAcc:
-*vr4100:
+:%s::::UNS:int u
 {
-  unsigned64 result = U8_4 (HI, LO);
-  return result;
+  return u ? "u" : "";
 }
 
-:function:::void:SET_MulAcc:unsigned64 value
-*vr4100:
+// Simulate the various kinds of multiply and multiply-accumulate instructions.
+// Perform an operation of the form:
+//
+//     LHS (+/-) GPR[RS] * GPR[RT]
+//
+// and store it in the 64-bit accumulator.  Optionally copy either LO or
+// HI into a general purpose register.
+//
+// - RD is the destination register of the LO or HI move
+// - RS are RT are the multiplication source registers
+// - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator,
+//     false if it should be 0.
+// - STORE_HI_P is true if HI should be stored in RD, false if LO should be.
+// - UNSIGNED_P is true if the operation should be unsigned.
+// - SATURATE_P is true if the result should be saturated to a 32-bit value.
+// - SUBTRACT_P is true if the right hand side should be subtraced from LHS,
+//     false if it should be added.
+// - SHORT_P is true if RS and RT must be 16-bit numbers.
+// - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a
+//     concatenation of the low 32 bits of HI and LO.
+:function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
 {
-  /* 64 bit specific */
-  *AL4_8 (&HI) = VH4_8 (value);
-  *AL4_8 (&LO) = VL4_8 (value);
+  unsigned64 lhs, x, y, xcut, ycut, product, result;
+
+  check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
+
+  lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
+  x = GPR[rs];
+  y = GPR[rt];
+
+  /* Work out the canonical form of X and Y from their significant bits.  */
+  if (!short_p)
+    {
+      /* Normal sign-extension rule for 32-bit operands.  */
+      xcut = EXTEND32 (x);
+      ycut = EXTEND32 (y);
+    }
+  else if (unsigned_p)
+    {
+      /* Operands must be zero-extended 16-bit numbers.  */
+      xcut = x & 0xffff;
+      ycut = y & 0xffff;
+    }
+  else
+    {
+      /* Likewise but sign-extended.  */
+      xcut = EXTEND16 (x);
+      ycut = EXTEND16 (y);
+    }
+  if (x != xcut || y != ycut)
+    sim_engine_abort (SD, CPU, CIA,
+                     "invalid multiplication operand at 0x%08lx\n",
+                     (long) CIA);
+
+  TRACE_ALU_INPUT2 (x, y);
+  product = (unsigned_p ? x * y : EXTEND32 (x) * EXTEND32 (y));
+  result = (subtract_p ? lhs - product : lhs + product);
+  if (saturate_p)
+    {
+      /* Saturate the result to 32 bits.  An unsigned, unsaturated
+        result is zero-extended to 64 bits, but unsigned overflow
+        causes all 64 bits to be set.  */
+      if (!unsigned_p && (unsigned64) EXTEND32 (result) != result)
+       result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
+      else if (unsigned_p && (result >> 32) != 0)
+       result = (unsigned64) 0 - 1;
+    }
+  TRACE_ALU_RESULT (result);
+
+  if (double_p)
+    LO = result;
+  else
+    {
+      LO = EXTEND32 (result);
+      HI = EXTEND32 (VH4_8 (result));
+    }
+  if (rd != 0)
+    GPR[rd] = store_hi_p ? HI : LO;
 }
 
-:function:::signed64:SignedMultiply:signed32 l, signed32 r
-*vr4100:
+// 32-bit rotate right of X by Y bits.
+:function:::unsigned64:do_ror:unsigned32 x,unsigned32 y
+*vr5400:
+*vr5500:
 {
-  signed64 result = (signed64) l * (signed64) r;
+  unsigned64 result;
+
+  y &= 31;
+  TRACE_ALU_INPUT2 (x, y);
+  result = EXTEND32 (ROTR32 (x, y));
+  TRACE_ALU_RESULT (result);
   return result;
 }
 
-:function:::unsigned64:UnsignedMultiply:unsigned32 l, unsigned32 r
-*vr4100:
+// Likewise 64-bit
+:function:::unsigned64:do_dror:unsigned64 x,unsigned64 y
+*vr5400:
+*vr5500:
 {
-  unsigned64 result = (unsigned64) l * (unsigned64) r;
+  unsigned64 result;
+
+  y &= 63;
+  TRACE_ALU_INPUT2 (x, y);
+  result = ROTR64 (x, y);
+  TRACE_ALU_RESULT (result);
   return result;
 }
 
-:function:::unsigned64:Low32Bits:unsigned64 value
+
+// VR4100 instructions.
+
+000000,5.RS,5.RT,00000,00000,101000::32::MADD16
+"madd16 r<RS>, r<RT>"
 *vr4100:
 {
-  unsigned64 result = (signed64) (signed32) VL4_8 (value);
-  return result;
+  do_vr_mul_op (SD_, 0, RS, RT,
+               1 /* accumulate */,
+               0 /* store in LO */,
+               0 /* signed arithmetic */,
+               0 /* don't saturate */,
+               0 /* don't subtract */,
+               1 /* short */,
+               0 /* single */);
 }
 
-:function:::unsigned64:High32Bits:unsigned64 value
+000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
+"dmadd16 r<RS>, r<RT>"
 *vr4100:
 {
-  unsigned64 result = (signed64) (signed32) VH4_8 (value);
-  return result;
+  do_vr_mul_op (SD_, 0, RS, RT,
+               1 /* accumulate */,
+               0 /* store in LO */,
+               0 /* signed arithmetic */,
+               0 /* don't saturate */,
+               0 /* don't subtract */,
+               1 /* short */,
+               1 /* double */);
 }
 
 
 
-// Multiply, Accumulate
-000000,5.RS,5.RT,00000,00000,101000::64::MAC
-"mac r<RS>, r<RT>"
-*vr4100:
+// VR4120 and VR4130 instructions.
+
+000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
+"dmacc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
+*vr4120:
 {
-  SET_MulAcc (SD_, MulAcc (SD_) + SignedMultiply (SD_, GPR[RS], GPR[RT]));
+  do_vr_mul_op (SD_, RD, RS, RT,
+               1 /* accumulate */,
+               MFHI, UNS, SAT,
+               0 /* don't subtract */,
+               SAT /* short */,
+               1 /* double */);
 }
 
+000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
+"macc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
+*vr4120:
+{
+  do_vr_mul_op (SD_, RD, RS, RT,
+               1 /* accumulate */,
+               MFHI, UNS, SAT,
+               0 /* don't subtract */,
+               SAT /* short */,
+               0 /* single */);
+}
 
-// D-Multiply, Accumulate
-000000,5.RS,5.RT,00000,00000,101001::64::DMAC
-"dmac r<RS>, r<RT>"
-*vr4100:
+
+// VR5400 and VR5500 instructions.
+
+000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
+"mul%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
+*vr5400:
+*vr5500:
 {
-  LO = LO + SignedMultiply (SD_, GPR[RS], GPR[RT]);
+  do_vr_mul_op (SD_, RD, RS, RT,
+               0 /* don't accumulate */,
+               MFHI, UNS,
+               0 /* don't saturate */,
+               0 /* don't subtract */,
+               0 /* not short */,
+               0 /* single */);
 }
 
+000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
+"muls%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
+*vr5400:
+*vr5500:
+{
+  do_vr_mul_op (SD_, RD, RS, RT,
+               0 /* don't accumulate */,
+               MFHI, UNS,
+               0 /* don't saturate */,
+               1 /* subtract */,
+               0 /* not short */,
+               0 /* single */);
+}
+
+000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
+"macc%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
+*vr5400:
+*vr5500:
+{
+  do_vr_mul_op (SD_, RD, RS, RT,
+               1 /* accumulate */,
+               MFHI, UNS,
+               0 /* don't saturate */,
+               0 /* don't subtract */,
+               0 /* not short */,
+               0 /* single */);
+}
+
+000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
+"msac%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
+*vr5400:
+*vr5500:
+{
+  do_vr_mul_op (SD_, RD, RS, RT,
+               1 /* accumulate */,
+               MFHI, UNS,
+               0 /* don't saturate */,
+               1 /* subtract */,
+               0 /* not short */,
+               0 /* single */);
+}
+
+000000,00001,5.RT,5.RD,5.SHIFT,000010::32::ROR
+"ror r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+*vr5500:
+{
+  GPR[RD] = do_ror (SD_, GPR[RT], SHIFT);
+}
+
+000000,5.RS,5.RT,5.RD,00001,000110::32::RORV
+"rorv r<RD>, r<RT>, r<RS>"
+*vr5400:
+*vr5500:
+{
+  GPR[RD] = do_ror (SD_, GPR[RT], GPR[RS]);
+}
+
+000000,00001,5.RT,5.RD,5.SHIFT,111010::64::DROR
+"dror r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+*vr5500:
+{
+  GPR[RD] = do_dror (SD_, GPR[RT], SHIFT);
+}
+
+000000,00001,5.RT,5.RD,5.SHIFT,111110::64::DROR32
+"dror32 r<RD>, r<RT>, <SHIFT>"
+*vr5400:
+*vr5500:
+{
+  GPR[RD] = do_dror (SD_, GPR[RT], SHIFT + 32);
+}
+
+000000,5.RS,5.RT,5.RD,00001,010110::64::DRORV
+"drorv r<RD>, r<RT>, r<RS>"
+*vr5400:
+*vr5500:
+{
+  GPR[RD] = do_dror (SD_, GPR[RT], GPR[RS]);
+}
+
+010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
+"luxc1 f<FD>, r<INDEX>(r<BASE>)"
+*vr5500:
+{
+  check_fpu (SD_);
+  COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
+                         (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
+}
+
+010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
+"suxc1 f<FS>, r<INDEX>(r<BASE>)"
+*vr5500:
+{
+  check_fpu (SD_);
+  do_store (SD_, AccessLength_DOUBLEWORD,
+           (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
+           COP_SD (1, FS));
+}
+
+010000,1,19.*,100000:COP0:32::WAIT
+"wait"
+*vr5500:
+
+011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
+"mfdr r<RT>, r<DR>"
+*vr5400:
+*vr5500:
 
+011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
+"mtdr r<RT>, r<DR>"
+*vr5400:
+*vr5500:
 
+011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
+"dret"
+*vr5400:
+*vr5500: