public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] sim: Add nanoMIPS port
@ 2022-12-13 16:09 Aleksandar Rikalo
  0 siblings, 0 replies; 5+ messages in thread
From: Aleksandar Rikalo @ 2022-12-13 16:09 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: gdb-patches, arikalo

[-- Attachment #1: Type: text/plain, Size: 278 bytes --]

Hello Mike,

Thanks again for your time.
I'll post a new version when those changes are in place.

Aleksandar

> let's circle back once GDB 13 branches, and some pending sim changes are
> merged.  then you can rebase on top of that and send out a new version.
> -mike

^ permalink raw reply	[flat|nested] 5+ messages in thread
* [PATCH 2/3] sim: Add nanoMIPS port
@ 2022-04-29 15:58 Aleksandar Rikalo
  2022-11-21 11:06 ` [PATCH v3 1/2] " Aleksandar Rikalo
  0 siblings, 1 reply; 5+ messages in thread
From: Aleksandar Rikalo @ 2022-04-29 15:58 UTC (permalink / raw)
  To: gdb-patches

Co-Authored-By: Jaydeep Patil <jaydeep.patil@imgtec.com>
Co-Authored-By: Matthew Fortune <matthew.fortune@imgtec.com>
Co-Authored-By: Maciej W. Rozycki <macro@mips.com>
Co-Authored-By: Stefan Markovic <stefan.markovic@mips.com>
Co-Authored-By: Sara Graovac <sara.graovac@syrmia.com>
Co-Authored-By: Dragan Mladjenovic <dragan.mladjenovic@syrmia.com>
---
 sim/common/sim-bits.h     |    4 +
 sim/configure             |    8 +
 sim/mips/Makefile.in      |   42 +
 sim/mips/configure        |   71 +
 sim/mips/configure.ac     |   28 +
 sim/mips/interp.c         |   75 +-
 sim/mips/micromips.igen   |   22 +-
 sim/mips/micromips16.dc   |    3 +
 sim/mips/mips.igen        |  441 +++--
 sim/mips/nanomipsdsp.igen | 1116 +++++++++++++
 sim/mips/nanomipsr6.igen  | 3283 +++++++++++++++++++++++++++++++++++++
 sim/mips/nanomipsrun.c    |  109 ++
 sim/mips/nms.c            |   44 +
 sim/mips/sim-main.c       |   87 +-
 sim/mips/sim-main.h       |  154 +-
 15 files changed, 5321 insertions(+), 166 deletions(-)
 create mode 100644 sim/mips/nanomipsdsp.igen
 create mode 100644 sim/mips/nanomipsr6.igen
 create mode 100644 sim/mips/nanomipsrun.c
 create mode 100644 sim/mips/nms.c

diff --git a/sim/common/sim-bits.h b/sim/common/sim-bits.h
index fab1dab478c..8799916de26 100644
--- a/sim/common/sim-bits.h
+++ b/sim/common/sim-bits.h
@@ -499,15 +499,19 @@ INLINE_SIM_BITS(unsigned_word) MSINSERTED (unsigned_word val, int start, int sto
 #define EXTEND4(X)  (LSSEXT ((X), 3))
 #define EXTEND5(X)  (LSSEXT ((X), 4))
 #define EXTEND6(X)  (LSSEXT ((X), 5))
+#define EXTEND7(X)  (LSSEXT ((X), 6))
 #define EXTEND8(X)  ((signed_word)(int8_t)(X))
 #define EXTEND9(X)  (LSSEXT ((X), 8))
+#define EXTEND10(X)  (LSSEXT ((X), 9))
 #define EXTEND11(X)  (LSSEXT ((X), 10))
 #define EXTEND12(X)  (LSSEXT ((X), 11))
+#define EXTEND14(X)  (LSSEXT ((X), 13))
 #define EXTEND15(X)  (LSSEXT ((X), 14))
 #define EXTEND16(X) ((signed_word)(int16_t)(X))
 #define EXTEND18(X)  (LSSEXT ((X), 17))
 #define EXTEND19(X)  (LSSEXT ((X), 18))
 #define EXTEND21(X)  (LSSEXT ((X), 20))
+#define EXTEND22(X)  (LSSEXT ((X), 21))
 #define EXTEND24(X)  (LSSEXT ((X), 23))
 #define EXTEND25(X)  (LSSEXT ((X), 24))
 #define EXTEND26(X)  (LSSEXT ((X), 25))
diff --git a/sim/configure b/sim/configure
index b31c2f5d8f3..cc2d957192f 100755
--- a/sim/configure
+++ b/sim/configure
@@ -15298,6 +15298,14 @@ fi
       sim_enable_arch_mips=true
       sim_igen=yes
       ;;
+    nanomips*-*-*)
+
+      sim_arch=mips
+      subdirs="$subdirs mips"
+
+      sim_igen=yes
+        ;;
+
   esac
 
 
diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in
index 75438be5a18..6bf2d14bdef 100644
--- a/sim/mips/Makefile.in
+++ b/sim/mips/Makefile.in
@@ -61,6 +61,7 @@ SIM_OBJS = \
 	cp1.o \
 	mdmx.o \
 	dsp.o \
+	nms.o \
 	sim-main.o \
 	sim-resume.o \
 
@@ -79,6 +80,20 @@ SIM_EXTRA_DEPS = itable.h
 
 ## COMMON_POST_CONFIG_FRAG
 
+interp.o: $(srcdir)/interp.c sim-main.h itable.h
+
+m16run.o: sim-main.h m16_idecode.h m32_idecode.h m16run.c $(SIM_EXTRA_DEPS)
+
+micromipsrun.o: sim-main.h micromips16_idecode.h micromips32_idecode.h \
+		micromips_m32_idecode.h micromipsrun.c $(SIM_EXTRA_DEPS)
+
+nms.o: $(srcdir)/nms.c $(srcdir)/sim-main.h
+
+multi-run.o: multi-include.h tmp-mach-multi
+
+../igen/igen:
+	cd ../igen && $(MAKE)
+
 IGEN_TRACE= # -G omit-line-numbers # -G trace-rule-selection -G trace-rule-rejection -G trace-entries # -G trace-all
 IGEN_INSN=$(srcdir)/mips.igen
 IGEN_DC=$(srcdir)/mips.dc
@@ -99,6 +114,8 @@ IGEN_INCLUDE=\
 	$(srcdir)/dsp2.igen \
 	$(srcdir)/mips3264r2.igen \
 	$(srcdir)/mips3264r6.igen \
+	$(srcdir)/nanomipsdsp.igen \
+	$(srcdir)/nanomipsr6.igen
 
 # NB:	Since these can be built by a number of generators, care
 #	must be taken to ensure that they are only dependant on
@@ -463,8 +480,11 @@ tmp-mach-multi: $(IGEN_INSN) $(IGEN_DC) $(IGEN) $(IGEN_INCLUDE)
 	  f=`echo $${t} | sed -e 's/.*://'` ; \
 	  case $${p} in \
 	    micromips16*) e="-B 16 -H 15 -o $(MICROMIPS16_DC) -F 16" ;; \
+	    nanomips16*) e="-B 16 -H 15 -o $(MICROMIPS16_DC) -F 16" ;; \
 	    micromips32* | micromips64*) \
 		e="-B 32 -H 31 -o $(MICROMIPS32_DC) -F $${f}" ;; \
+	    nanomips32* | nanomips64*) \
+		e="-B 32 -H 31 -o $(MICROMIPS32_DC) -F $${f}" ;; \
 	    micromips_m32*) \
 		e="-B 32 -H 31 -o $(IGEN_DC) -F $${f}"; \
 		m="mips32r2,mips3d,mdmx,dsp,dsp2,smartmips" ;; \
@@ -579,6 +599,28 @@ tmp-run-multi: $(srcdir)/m16run.c $(srcdir)/micromipsrun.c
 	      $(SHELL) $(srcdir)/../../move-if-change tmp-run \
 						      micromips$${m}_run.c ; \
              ;;\
+	    nanomips32*) \
+	      m=`echo $${t} | sed -e 's/^nanomips32//' -e 's/:.*//'`; \
+	      sed <  $(srcdir)/nanomipsrun.c > tmp-run \
+		    -e "s/^sim_/nanomips32$${m}_/" \
+		    -e "s/nanomips_instruction_decode/nanomips32$${m}_instruction_decode/g" \
+		    -e "s/nanomips16_/nanomips16$${m}_/" \
+		    -e "s/nanomips32_/nanomips32$${m}_/" \
+		    -e "s/m32_/m32$${m}_/" ; \
+	      $(SHELL) $(srcdir)/../../move-if-change tmp-run \
+						      nanomips$${m}_run.c ; \
+             ;;\
+	    nanomips64*) \
+	      m=`echo $${t} | sed -e 's/^nanomips64//' -e 's/:.*//'`; \
+	      sed <  $(srcdir)/nanomipsrun.c > tmp-run \
+		    -e "s/^sim_/nanomips64$${m}_/" \
+		    -e "s/nanomips_instruction_decode/nanomips64$${m}_instruction_decode/g" \
+		    -e "s/nanomips16_/nanomips16$${m}_/" \
+		    -e "s/nanomips32_/nanomips64$${m}_/" \
+		    -e "s/m32_/m64$${m}_/" ; \
+	      $(SHELL) $(srcdir)/../../move-if-change tmp-run \
+						      nanomips$${m}_run.c ; \
+             ;;\
 	  esac \
 	done
 	$(SILENCE) touch $@
diff --git a/sim/mips/configure b/sim/mips/configure
index 2f635a50e10..1438951b5d1 100755
--- a/sim/mips/configure
+++ b/sim/mips/configure
@@ -1874,6 +1874,12 @@ case "${target}" in
 			  mipsisa64r6:mips64r6:32,64,f:mipsisa32r6,mipsisa64r6"
 			sim_multi_default=mipsisa64r2
 			;;
+  nanomips*-elf*)
+			sim_gen=MULTI
+			sim_multi_configs="\
+			  nanor6sim:nanomips64r6,nanomipsdsp:32,64,f:nanomipsisa64r6,nanomipsisa32r6"
+			sim_multi_default=nanomipsisa32r6
+			;;
   mips64*-*-*)		sim_igen_filter="32,64,f"
 			sim_gen=IGEN
 			;;
@@ -2072,6 +2078,17 @@ __EOF__
 	sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
 	sim_multi_flags="${sim_multi_flags} -F 16,32"
 	;;
+      *:*nanomips32*)
+	# Run igen twice, once for nanomips32 and once for nanomips16.
+	ws="nanomips16 nanomips32"
+
+	# The top-level function for the micromips simulator is
+	# in a file micromips${name}_run.c, generated by the
+	# tmp-run-multi Makefile rule.
+	sim_multi_src="${sim_multi_src} nanomips${name}_run.c"
+	sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o"
+	sim_multi_flags="${sim_multi_flags} -F 16,32"
+	;;
       *:*micromips64*:*)
 	# Run igen thrice, once for micromips64, once for micromips16,
 	# and once for m64.
@@ -2084,6 +2101,17 @@ __EOF__
 	sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
 	sim_multi_flags="${sim_multi_flags} -F 16,32,64"
 	;;
+      *:*nanomips64*)
+	# Run igen twice, once for nanomips64 and once for nanomips16.
+	ws="nanomips16 nanomips64"
+
+	# The top-level function for the micromips simulator is
+	# in a file micromips${name}_run.c, generated by the
+	# tmp-run-multi Makefile rule.
+	sim_multi_src="${sim_multi_src} nanomips${name}_run.c"
+	sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o"
+	sim_multi_flags="${sim_multi_flags} -F 16,32,64"
+	;;
       *)
 	ws=m32
 	;;
@@ -2126,6 +2154,8 @@ __EOF__
     }
 }
 
+int
+mips_mach_multi (SIM_DESC sd);
 int
 mips_mach_multi (SIM_DESC sd)
 {
@@ -2155,6 +2185,47 @@ __EOF__
       return bfd_mach_${sim_multi_default};
     }
 }
+
+address_word
+micromips_instruction_decode_multi (SIM_DESC sd,
+            sim_cpu* cpu,
+            address_word cia,
+            int instruction_size)
+{
+  unsigned long bfdmach;
+  if (STATE_ARCHITECTURE(SD) == NULL)
+    bfdmach = bfd_mach_${sim_multi_default};
+  else
+    bfdmach = STATE_ARCHITECTURE(SD)->mach;
+
+  switch (bfdmach)
+    {
+__EOF__
+
+  # Add a case statement for each micromips-enabled engine
+  for fc in ${micromips_configs}; do
+    machine=`echo ${fc} | sed 's/.*:\(.*\):.*:.*:.*:.*/\1/'`
+    name=`echo ${fc} | sed 's/:.*//'`
+    bfdmachs=`echo ${fc} | sed 's/.*:.*:.*:.*:\(.*\):.*/\1/'`
+    case ${machine} in
+      micromips*)
+  for bfdmach in `echo ${bfdmachs} | sed 's/,/ /g'`; do
+    echo "      case bfd_mach_${bfdmach}:" >> multi-run.c
+  done
+  echo "  return ${name}_instruction_decode (sd, cpu, cia, instruction_size);" >> multi-run.c
+  ;;
+      *)
+  ;;
+    esac
+  done
+
+  cat << __EOF__ >> multi-run.c
+      default:
+  fprintf(stderr, "no valid micromips instruction decoder for this micromips engine\n");
+  abort();
+  break;
+    }
+}
 __EOF__
 
   SIM_SUBTARGET="$SIM_SUBTARGET -DMIPS_MACH_MULTI"
diff --git a/sim/mips/configure.ac b/sim/mips/configure.ac
index 96806424958..0d48b9630d9 100644
--- a/sim/mips/configure.ac
+++ b/sim/mips/configure.ac
@@ -106,6 +106,12 @@ case "${target}" in
 			  mipsisa64r6:mips64r6:32,64,f:mipsisa32r6,mipsisa64r6"
 			sim_multi_default=mipsisa64r2
 			;;
+  nanomips*-*-elf*)
+			sim_gen=MULTI
+			sim_multi_configs="\
+			  nanor6sim:nanomips64r6,nanomipsdsp:32,64,f:nanomipsisa64r6,nanomipsisa32r6"
+			sim_multi_default=nanomipsisa64r6
+			;;
   mips64*-*-*)		sim_igen_filter="32,64,f"
 			sim_gen=IGEN
 			;;
@@ -304,6 +310,17 @@ __EOF__
 	sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
 	sim_multi_flags="${sim_multi_flags} -F 16,32"
 	;;
+      *:*nanomips32*)
+	# Run igen twice, once for nanomips32 and once for nanomips16.
+	ws="nanomips16 nanomips32"
+
+	# The top-level function for the micromips simulator is
+	# in a file micromips${name}_run.c, generated by the
+	# tmp-run-multi Makefile rule.
+	sim_multi_src="${sim_multi_src} nanomips${name}_run.c"
+	sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o"
+	sim_multi_flags="${sim_multi_flags} -F 16,32"
+	;;
       *:*micromips64*:*)
 	# Run igen thrice, once for micromips64, once for micromips16,
 	# and once for m64.
@@ -316,6 +333,17 @@ __EOF__
 	sim_multi_obj="${sim_multi_obj} micromips${name}_run.o"
 	sim_multi_flags="${sim_multi_flags} -F 16,32,64"
 	;;
+      *:*nanomips64*)
+	# Run igen twice, once for nanomips64 and once for nanomips16.
+	ws="nanomips16 nanomips64"
+
+	# The top-level function for the micromips simulator is
+	# in a file micromips${name}_run.c, generated by the
+	# tmp-run-multi Makefile rule.
+	sim_multi_src="${sim_multi_src} nanomips${name}_run.c"
+	sim_multi_obj="${sim_multi_obj} nanomips${name}_run.o"
+	sim_multi_flags="${sim_multi_flags} -F 16,32,64"
+	;;
       *)
 	ws=m32
 	;;
diff --git a/sim/mips/interp.c b/sim/mips/interp.c
index c5d0901428b..eba56df0a3e 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -140,6 +140,7 @@ static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
 
 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
 
+int is_nanomips = 0;
 #define MEM_SIZE (8 << 20)	/* 8 MBytes */
 
 
@@ -672,10 +673,13 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
 	  cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
 	else if ((rn >= 33) && (rn <= 37))
 	  cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
+	else if ((rn >= 70) && (rn <= 78))
+	  cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
 	else if ((rn == SRIDX)
 		 || (rn == FCR0IDX)
 		 || (rn == FCR31IDX)
-		 || ((rn >= 72) && (rn <= 89)))
+		 || (rn == DSPCRIDX)
+		 || ((rn >= 80) && (rn <= 89)))
 	  cpu->register_widths[rn] = 32;
 	else
 	  cpu->register_widths[rn] = 0;
@@ -1200,7 +1204,7 @@ sim_monitor (SIM_DESC sd,
     case 6: /* int open(char *path,int flags) */
       {
 	char *path = fetch_str (sd, A0);
-	V0 = sim_io_open (sd, path, (int)A1);
+	SET_RV0 (sim_io_open (sd, path, (int)A1));
 	free (path);
 	break;
       }
@@ -1210,7 +1214,7 @@ sim_monitor (SIM_DESC sd,
 	int fd = A0;
 	int nr = A2;
 	char *buf = zalloc (nr);
-	V0 = sim_io_read (sd, fd, buf, nr);
+	SET_RV0 (sim_io_read (sd, fd, buf, nr));
 	sim_write (sd, A1, (unsigned char *)buf, nr);
 	free (buf);
       }
@@ -1222,7 +1226,7 @@ sim_monitor (SIM_DESC sd,
 	int nr = A2;
 	char *buf = zalloc (nr);
 	sim_read (sd, A1, (unsigned char *)buf, nr);
-	V0 = sim_io_write (sd, fd, buf, nr);
+	SET_RV0 (sim_io_write (sd, fd, buf, nr));
 	if (fd == 1)
 	    sim_io_flush_stdout (sd);
 	else if (fd == 2)
@@ -1233,14 +1237,14 @@ sim_monitor (SIM_DESC sd,
 
     case 10: /* int close(int file) */
       {
-	V0 = sim_io_close (sd, (int)A0);
+	SET_RV0 (sim_io_close (sd, (int)A0));
 	break;
       }
 
     case 2:  /* Densan monitor: char inbyte(int waitflag) */
       {
 	if (A0 == 0)	/* waitflag == NOWAIT */
-	  V0 = (unsigned_word)-1;
+	    SET_RV0 ((unsigned_word)-1);
       }
      /* Drop through to case 11 */
 
@@ -1252,10 +1256,10 @@ sim_monitor (SIM_DESC sd,
         if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
 	  {
 	    sim_io_error(sd,"Invalid return from character read");
-	    V0 = (unsigned_word)-1;
+	    SET_RV0 ((unsigned_word)-1);
 	  }
         else
-	  V0 = (unsigned_word)tmp;
+	    SET_RV0 ((unsigned_word)tmp);
 	break;
       }
 
@@ -1531,21 +1535,26 @@ store_word (SIM_DESC sd,
 	    uword64 vaddr,
 	    signed_word val)
 {
-  address_word paddr = vaddr;
+  address_word paddr;
+  int uncached;
 
   if ((vaddr & 3) != 0)
     SignalExceptionAddressStore ();
   else
     {
-      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 (AccessLength_WORD, memval, 0, paddr, vaddr,
-		   isREAL);
+      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);
+	}
     }
 }
 
@@ -1567,18 +1576,24 @@ load_word (SIM_DESC sd,
     }
   else
     {
-      address_word paddr = vaddr;
-      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, AccessLength_WORD, paddr, vaddr, isDATA,
-		  isREAL);
-      byte = (vaddr & mask) ^ (bigend << 2);
-      return EXTEND32 (memval >> (8 * byte));
+      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 EXTEND32 (memval >> (8 * byte));
+	}
     }
 
   return 0;
diff --git a/sim/mips/micromips.igen b/sim/mips/micromips.igen
index bb61b3f26e6..55545403a4b 100644
--- a/sim/mips/micromips.igen
+++ b/sim/mips/micromips.igen
@@ -42,6 +42,7 @@
 *micromips32:
 *micromips64:
 *micromipsdsp:
+*nanomipsdsp:
 {
   instruction_word delay_insn;
   sim_events_slip (SD, 1);
@@ -49,7 +50,7 @@
   CIA = nia;
   STATE |= simDELAYSLOT;
   ENGINE_ISSUE_PREFIX_HOOK();
-  micromips_instruction_decode (SD, CPU, CIA, delayslot_instruction_size);
+  MICROMIPS_INSTRUCTION_DECODE (SD, CPU, CIA, delayslot_instruction_size);
   STATE &= ~simDELAYSLOT;
   return target;
 }
@@ -128,6 +129,8 @@
 :function:::FP_formats:convert_fmt_micromips:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
@@ -141,6 +144,8 @@
 :function:::FP_formats:convert_fmt_micromips_cvt_d:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
@@ -155,6 +160,8 @@
 :function:::FP_formats:convert_fmt_micromips_cvt_s:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
@@ -865,8 +872,11 @@
   address_word base = GPR[BASE];
   address_word offset = EXTEND12 (IMMEDIATE);
   address_word vaddr = loadstore_ea (SD_, base, offset);
-  address_word paddr = vaddr;
-  CacheOp (OP, vaddr, paddr, instruction_0);
+  address_word paddr;
+  int uncached;
+  if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+			  isTARGET, isREAL))
+    CacheOp (OP, vaddr, paddr, instruction_0);
 }
 
 
@@ -2275,6 +2285,8 @@
 :%s::::FMT_MICROMIPS:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
@@ -2289,6 +2301,8 @@
 :%s::::FMT_MICROMIPS_CVT_D:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
@@ -2303,6 +2317,8 @@
 :%s::::FMT_MICROMIPS_CVT_S:int fmt
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   switch (fmt)
     {
diff --git a/sim/mips/micromips16.dc b/sim/mips/micromips16.dc
index a1cd9a0ea89..ace9bb94fad 100644
--- a/sim/mips/micromips16.dc
+++ b/sim/mips/micromips16.dc
@@ -8,4 +8,7 @@
 
   switch,combine        :  9 :    6 :    :    :    :      :      :
   switch,combine        :  9 :    5 :    :    :    :      :      :
+  switch,combine        :  3 :    0 :    :    :    :      :      :
+  switch,combine        :  2 :    0 :    :    :    :      :      :
+  switch,combine        :  5 :    3 :    :    :    :      :      :
   switch,combine        :  0 :    0 :    :    :    :      :      :
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen
index dfad4227615..8f427ce258b 100644
--- a/sim/mips/mips.igen
+++ b/sim/mips/mips.igen
@@ -79,6 +79,9 @@
 :model:::micromips32:micromips64:	// micromips.igen
 :model:::micromips64:micromips64:	// micromips.igen
 :model:::micromipsdsp:micromipsdsp:	// micromipsdsp.igen
+:model:::nanomips32r6:nanomips32r6: // nanomipsr6.igen
+:model:::nanomips64r6:nanomips64r6: // nanomipsr6.igen
+:model:::nanomipsdsp:nanomipsdsp: // nanompsdsp.igen
 
 //  Vendor Extensions
 //
@@ -98,6 +101,31 @@
 // For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK
 000000,5.*,5.*,5.*,5.OP,111001:SPECIAL:32::RSVD
 "rsvd <OP>"
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips64:
+*mips64r2:
+*vr4100:
+*vr4120:
+*vr5000:
+*vr5400:
+*vr5500:
+*r3900:
+*mips16:
+*mips16e:
+*mips3d:
+*mdmx:
+*dsp:
+*dsp2:
+*smartmips:
+*micromips32:
+*micromips64:
+*micromipsdsp:
 {
   SignalException (ReservedInstruction, instruction_0);
 }
@@ -192,6 +220,7 @@
 *vr5000:
 *r3900:
 *micromips32:
+*nanomips32r6:
 {
   return base + offset;
 }
@@ -201,6 +230,7 @@
 *mips64r2:
 *micromips64:
 *mips64r6:
+*nanomips64r6:
 {
 #if 0 /* XXX FIXME: enable this only after some additional testing.  */
   /* If in user mode and UX is not set, use 32-bit compatibility effective
@@ -237,6 +267,8 @@
 *micromips32:
 *micromips64:
 *mips64r6:
+*nanomips32r6:
+*nanomips64r6:
 {
 #if WITH_TARGET_WORD_BITSIZE == 64
   return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
@@ -274,6 +306,8 @@
 *micromips32:
 *micromips64:
 *mips64r6:
+*nanomips32r6:
+*nanomips64r6:
 {
   unpredictable_action (CPU, CIA);
 }
@@ -369,6 +403,7 @@
 *r3900:
 *micromips32:
 *micromips64:
+*nanomipsdsp:
 {
   int64_t time = sim_events_time (SD);
   history->mt.timestamp = time;
@@ -399,6 +434,7 @@
 *r3900:
 *micromips32:
 *micromips64:
+*nanomipsdsp:
 {
   int64_t time = sim_events_time (SD);
   int ok = 1;
@@ -473,6 +509,7 @@
 *r3900:
 *micromips32:
 *micromips64:
+*nanomipsdsp:
 {
   /* FIXME: could record the fact that a stall occured if we want */
   int64_t time = sim_events_time (SD);
@@ -570,6 +607,8 @@
 *micromips64:
 *micromips32:
 *mips64r6:
+*nanomips32r6:
+*nanomips64r6:
 {
 #if 0 /* XXX FIXME: enable this only after some additional testing.  */
   if (UserMode && (SR & (status_UX|status_PX)) == 0)
@@ -781,12 +820,44 @@
 }
 
 :function:::void:do_lb:int rt, int offset, int base
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips32:
+*micromips64:
 {
   GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base],
 			      EXTEND16 (offset)));
 }
 
 :function:::void:do_lh:int rt, int offset, int base
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips32:
+*micromips64:
 {
   GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base],
 			       EXTEND16 (offset)));
@@ -811,6 +882,22 @@
 }
 
 :function:::void:do_lw:int rt, int offset, int base
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips32:
+*micromips64:
 {
   GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base],
 			       EXTEND16 (offset)));
@@ -823,6 +910,22 @@
 }
 
 :function:::void:do_lhu:int rt, int offset, int base
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips32:
+*micromips64:
 {
   GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], EXTEND16 (offset));
 }
@@ -844,7 +947,8 @@
   address_word offset = EXTEND16 (insn_offset);
     {
       address_word vaddr = loadstore_ea (SD_, base, offset);
-      address_word paddr = vaddr;
+      address_word paddr;
+      int uncached;
       if ((vaddr & 3) != 0)
 	{
 	  SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, read_transfer,
@@ -852,19 +956,23 @@
 	}
       else
 	{
-	  uint64_t memval = 0;
-	  uint64_t memval1 = 0;
-	  uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-	  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, AccessLength_WORD, paddr, vaddr,
-		      isDATA, isREAL);
-	  byte = ((vaddr & mask) ^ (bigend << shift));
-	  GPR[rt] = EXTEND32 (memval >> (8 * byte));
-	  LLBIT = 1;
+	  if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+				  isTARGET, isREAL))
+	    {
+	      uint64_t memval = 0;
+	      uint64_t memval1 = 0;
+	      uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+	      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[rt] = EXTEND32 (memval >> (8 * byte));
+	      LLBIT = 1;
+	    }
 	}
     }
 }
@@ -875,8 +983,8 @@
   address_word offset = EXTEND16 (roffset);
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr = vaddr;
-
+    address_word paddr;
+    int uncached;
     if ((vaddr & 7) != 0)
       {
 	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
@@ -884,12 +992,16 @@
       }
     else
       {
-	uint64_t memval = 0;
-	uint64_t memval1 = 0;
-	LoadMemory (&memval, &memval1, AccessLength_DOUBLEWORD, paddr, vaddr,
-		    isDATA, isREAL);
-	GPR[rt] = memval;
-	LLBIT = 1;
+        if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+                                isTARGET, isREAL))
+          {
+            uint64_t memval = 0;
+            uint64_t memval1 = 0;
+            LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD,
+                        paddr, vaddr, isDATA, isREAL);
+            GPR[rt] = memval;
+            LLBIT = 1;
+          }
       }
   }
 }
@@ -1137,8 +1249,13 @@
   address_word offset = EXTEND16 (insn_offset);
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr = vaddr;
-    /* Prefetch (paddr, vaddr, isDATA, hint); */
+    address_word paddr;
+    int uncached;
+    {
+      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+			      isTARGET, isREAL))
+	Prefetch (uncached, paddr, vaddr, isDATA, hint);
+    }
   }
 }
 
@@ -1149,8 +1266,8 @@
   address_word offset = EXTEND16 (offsetarg);
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr = vaddr;
-
+    address_word paddr;
+    int uncached;
     if ((vaddr & 3) != 0)
       {
 	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
@@ -1158,23 +1275,27 @@
       }
     else
       {
-	uint64_t memval = 0;
-	uint64_t memval1 = 0;
-	uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-	address_word reverseendian =
-	  (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
-	address_word bigendiancpu =
-	  (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
-	unsigned int byte;
-	paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-	byte = ((vaddr & mask) ^ bigendiancpu);
-	memval = ((uint64_t) GPR[rt] << (8 * byte));
-	if (LLBIT)
-	  StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
-		        isREAL);
-	if (store_ll_bit)
-	  GPR[rt] = LLBIT;
-      }
+  if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+              isTARGET, isREAL))
+    {
+    uint64_t memval = 0;
+    uint64_t memval1 = 0;
+    uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+    address_word reverseendian =
+      (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+    address_word bigendiancpu =
+      (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+    unsigned int byte;
+    paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+    byte = ((vaddr & mask) ^ bigendiancpu);
+    memval = ((uint64_t) GPR[rt] << (8 * byte));
+    if (LLBIT)
+        StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr, vaddr,
+                     isREAL);
+    if (store_ll_bit)
+      GPR[rt] = LLBIT;
+    }
+  }
   }
 }
 
@@ -1184,8 +1305,8 @@
   address_word offset = EXTEND16 (roffset);
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr = vaddr;
-
+    address_word paddr;
+    int uncached;
     if ((vaddr & 7) != 0)
       {
 	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, write_transfer,
@@ -1193,15 +1314,19 @@
       }
     else
       {
+        if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+                    isTARGET, isREAL))
+          {
 	uint64_t memval = 0;
 	uint64_t memval1 = 0;
 	memval = GPR[rt];
 	if (LLBIT)
-	  StoreMemory (AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr,
+	  StoreMemory (uncached, AccessLength_DOUBLEWORD, memval, memval1, paddr, vaddr,
 		       isREAL);
 	if (store_ll_bit)
 	  GPR[rt] = LLBIT;
       }
+    }
   }
 }
 
@@ -1688,8 +1813,11 @@
   address_word index = GPR[rindex];
   {
     address_word vaddr = loadstore_ea (SD_, base, index);
-    address_word paddr = vaddr;
-    /* Prefetch (paddr, vaddr, isDATA, hint); */
+    address_word paddr;
+    int uncached;
+    if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+			    isREAL))
+      Prefetch (uncached, paddr, vaddr, isDATA, hint);
   }
 }
 
@@ -1753,8 +1881,8 @@
   check_fpu (SD_);
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
-    address_word paddr = vaddr;
-
+    address_word paddr;
+    int uncached;
     if ((vaddr & 3) != 0)
       {
 	SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
@@ -1762,18 +1890,23 @@
       }
     else
       {
-	uword64 memval = 0;
-	uword64 memval1 = 0;
-	uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-	address_word reverseendian =
-	  (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
-	address_word bigendiancpu =
-	  (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
-	unsigned int byte;
-	paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-	byte = ((vaddr & mask) ^ bigendiancpu);
-	memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
-	StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr, isREAL);
+	if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+			        isTARGET, isREAL))
+	  {
+	    uword64 memval = 0;
+	    uword64 memval1 = 0;
+	    uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+	    address_word reverseendian =
+	      (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
+	    address_word bigendiancpu =
+	      (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
+	    unsigned int byte;
+	    paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+	    byte = ((vaddr & mask) ^ bigendiancpu);
+	    memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
+	    StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
+			 vaddr, isREAL);
+	  }
       }
   }
 }
@@ -1786,8 +1919,8 @@
   check_u64 (SD_, instruction_0);
     {
       address_word vaddr = loadstore_ea (SD_, base, index);
-      address_word paddr = vaddr;
-
+      address_word paddr;
+      int uncached;
       if ((vaddr & 3) != 0)
 	{
 	  SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 4, vaddr, write_transfer,
@@ -1795,19 +1928,23 @@
 	}
       else
 	{
-	  uint64_t memval = 0;
-	  uint64_t memval1 = 0;
-	  uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
-	  address_word reverseendian =
-	    (ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
-	  address_word bigendiancpu =
-	    (BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
-	  unsigned int byte;
-	  paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-	  byte = ((vaddr & mask) ^ bigendiancpu);
-	  memval = (((uint64_t)COP_SW(1,fs)) << (8 * byte));
-	  StoreMemory (AccessLength_WORD, memval, memval1, paddr, vaddr,
-		       isREAL);
+	  if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+				 isTARGET, isREAL))
+	    {
+	      uint64_t memval = 0;
+	      uint64_t memval1 = 0;
+	      uint64_t mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+	      address_word reverseendian =
+		(ReverseEndian ? (mask ^ AccessLength_WORD) : 0);
+	      address_word bigendiancpu =
+		(BigEndianCPU ? (mask ^ AccessLength_WORD) : 0);
+	      unsigned int byte;
+	      paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+	      byte = ((vaddr & mask) ^ bigendiancpu);
+	      memval = (((uint64_t)COP_SW(1,fs)) << (8 * byte));
+	      StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
+			   vaddr, isREAL);
+	    }
 	}
   }
 }
@@ -1861,7 +1998,23 @@
 
 
 
-:function:::void:do_addiu:int rs, int rt, uint16_t immediate
+:function:::void:do_addiu:int rs, int rt, int immediate
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr5000:
+*r3900:
+*micromips32:
+*micromips64:
 {
   if (NotWordValue (GPR[rs]))
     Unpredictable ();
@@ -2595,6 +2748,14 @@
 
 
 :function:::void:do_ddiv:int rs, int rt
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips64:
+*mips64r2:
+*micromips64:
+*vr4100:
+*vr5000:
 {
   check_div_hilo (SD_, HIHISTORY, LOHISTORY);
   TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
@@ -2641,6 +2802,14 @@
 
 
 :function:::void:do_ddivu:int rs, int rt
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips64:
+*mips64r2:
+*micromips64:
+*vr4100:
+*vr5000:
 {
   check_div_hilo (SD_, HIHISTORY, LOHISTORY);
   TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
@@ -2680,6 +2849,20 @@
 }
 
 :function:::void:do_div:int rs, int rt
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*micromips32:
+*mips64:
+*mips64r2:
+*micromips64:
+*vr4100:
+*vr5000:
+*r3900:
 {
   check_div_hilo (SD_, HIHISTORY, LOHISTORY);
   TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
@@ -2726,6 +2909,20 @@
 
 
 :function:::void:do_divu:int rs, int rt
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*mips32:
+*mips32r2:
+*micromips32:
+*mips64:
+*mips64r2:
+*micromips64:
+*vr4100:
+*vr5000:
+*r3900:
 {
   check_div_hilo (SD_, HIHISTORY, LOHISTORY);
   TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
@@ -3277,16 +3474,18 @@
   address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
   unsigned int byte;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
   if ((vaddr & access) != 0)
     {
       SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map, access+1, vaddr, read_transfer, sim_core_unaligned_signal);
     }
+  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-  LoadMemory (&memval, NULL, access, paddr, vaddr, isDATA, isREAL);
+  LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isDATA, isREAL);
   byte = ((vaddr & mask) ^ bigendiancpu);
   return (memval >> (8 * byte));
 }
@@ -3299,6 +3498,7 @@
   unsigned int byte;
   unsigned int word;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
   int nr_lhs_bits;
@@ -3306,7 +3506,8 @@
   unsigned_word lhs_mask;
   unsigned_word temp;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
+  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem == 0)
     paddr = paddr & ~access;
@@ -3323,7 +3524,7 @@
 	   (long) ((uint64_t) paddr >> 32), (long) paddr,
 	   word, byte, nr_lhs_bits, nr_rhs_bits); */
 
-  LoadMemory (&memval, NULL, byte, paddr, vaddr, isDATA, isREAL);
+  LoadMemory (&memval, NULL, uncached, byte, paddr, vaddr, isDATA, isREAL);
   if (word == 0)
     {
       /* GPR{31..32-NR_LHS_BITS} = memval{NR_LHS_BITS-1..0} */
@@ -3352,17 +3553,19 @@
   address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
   unsigned int byte;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
+  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   /* NOTE: SPEC is wrong, has `BigEndianMem == 0' not `BigEndianMem != 0' */
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem != 0)
     paddr = paddr & ~access;
   byte = ((vaddr & mask) ^ (bigendiancpu & mask));
   /* NOTE: SPEC is wrong, had `byte' not `access - byte'.  See SW. */
-  LoadMemory (&memval, NULL, access - (access & byte), paddr, vaddr, isDATA, isREAL);
+  LoadMemory (&memval, NULL, uncached, access - (access & byte), paddr, vaddr, isDATA, isREAL);
   /* printf ("lr: 0x%08lx %d@0x%08lx 0x%08lx\n",
      (long) paddr, byte, (long) paddr, (long) memval); */
   {
@@ -3714,6 +3917,23 @@
 
 
 :function:::void:do_mfhi:int rd
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*vr4100:
+*vr5000:
+*r3900:
+*mips32:
+*mips64:
+*mips32r2:
+*mips64r2:
+*dsp:
+*micromips32:
+*micromips64:
+*micromipsdsp:
+*nanomipsdsp:
 {
   check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
   TRACE_ALU_INPUT1 (HI);
@@ -4175,18 +4395,20 @@
   address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
   unsigned int byte;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
   if ((vaddr & access) != 0)
     {
       SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map, access+1, vaddr, write_transfer, sim_core_unaligned_signal);
     }
+  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
   paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
   byte = ((vaddr & mask) ^ bigendiancpu);
   memval = (word << (8 * byte));
-  StoreMemory (access, memval, 0, paddr, vaddr, isREAL);
+  StoreMemory (uncached, access, memval, 0, paddr, vaddr, isREAL);
 }
 
 :function:::void:do_store_left:unsigned access, address_word base, address_word offset, unsigned_word rt
@@ -4197,12 +4419,14 @@
   unsigned int byte;
   unsigned int word;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
   int nr_lhs_bits;
   int nr_rhs_bits;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
+  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem == 0)
     paddr = paddr & ~access;
@@ -4229,7 +4453,7 @@
   /* fprintf (stderr, "s[wd]l: 0x%08lx%08lx -> 0x%08lx%08lx\n",
 	   (long) ((uint64_t) rt >> 32), (long) rt,
 	   (long) ((uint64_t) memval >> 32), (long) memval); */
-  StoreMemory (byte, memval, 0, paddr, vaddr, isREAL);
+  StoreMemory (uncached, byte, memval, 0, paddr, vaddr, isREAL);
 }
 
 :function:::void:do_store_right:unsigned access, address_word base, address_word offset, unsigned_word rt
@@ -4239,16 +4463,18 @@
   address_word bigendiancpu = (BigEndianCPU ? -1 : 0);
   unsigned int byte;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   address_word vaddr;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
+  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET, isREAL);
   paddr = (paddr ^ (reverseendian & mask));
   if (BigEndianMem != 0)
     paddr &= ~access;
   byte = ((vaddr & mask) ^ (bigendiancpu & mask));
   memval = (rt << (byte * 8));
-  StoreMemory (access - (access & byte), memval, 0, paddr, vaddr, isREAL);
+  StoreMemory (uncached, access - (access & byte), memval, 0, paddr, vaddr, isREAL);
 }
 
 
@@ -5225,6 +5451,8 @@
 *vr4100:
 *vr5000:
 *r3900:
+*nanomips32r6:
+*nanomips64r6:
 {
   /* None of these ISAs support Paired Single, so just fall back to
      the single/double check.  */
@@ -5273,6 +5501,8 @@
 *r3900:
 *micromips32:
 *micromips64:
+*nanomips32r6:
+*nanomips64r6:
 {
   if (! COP_Usable (1))
     SignalExceptionCoProcessorUnusable (1);
@@ -5316,20 +5546,24 @@
   int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
   address_word vaddr;
   address_word paddr;
+  int uncached;
   uint64_t memval;
   uint64_t v;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
   if ((vaddr & AccessLength_DOUBLEWORD) != 0)
     {
       SIM_CORE_SIGNAL (SD, STATE_CPU (SD, 0), cia, read_map,
 		       AccessLength_DOUBLEWORD + 1, vaddr, read_transfer,
 		       sim_core_unaligned_signal);
     }
-  LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA, isREAL);
+  AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached, isTARGET,
+		      isREAL);
+  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr, vaddr,
+	      isDATA, isREAL);
   v = (uint64_t)memval;
-  LoadMemory (&memval, NULL, AccessLength_WORD, paddr + 4, vaddr + 4, isDATA,
-	      isREAL);
+  LoadMemory (&memval, NULL, uncached, AccessLength_WORD, paddr + 4, vaddr + 4,
+	      isDATA, isREAL);
   return (bigendian ? ((v << 32) | memval) : (v | (memval << 32)));
 }
 
@@ -5351,19 +5585,24 @@
   int bigendian = (BigEndianCPU ? ! ReverseEndian : ReverseEndian);
   address_word vaddr;
   address_word paddr;
+  int uncached;
   uint64_t memval;
 
-  paddr = vaddr = loadstore_ea (SD_, base, offset);
+  vaddr = loadstore_ea (SD_, base, offset);
   if ((vaddr & AccessLength_DOUBLEWORD) != 0)
     {
       SIM_CORE_SIGNAL (SD, STATE_CPU(SD, 0), cia, read_map,
 		       AccessLength_DOUBLEWORD + 1, vaddr, write_transfer,
 		       sim_core_unaligned_signal);
     }
+  AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached, isTARGET,
+		      isREAL);
   memval = (bigendian ? (v >> 32) : (v & 0xFFFFFFFF));
-  StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr, isREAL);
+  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
+	       isREAL);
   memval = (bigendian ? (v & 0xFFFFFFFF) : (v >> 32));
-  StoreMemory (AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4, isREAL);
+  StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr + 4, vaddr + 4,
+	       isREAL);
 }
 
 
@@ -6628,7 +6867,10 @@
   {
     address_word vaddr = loadstore_ea (SD_, base, offset);
     address_word paddr = vaddr;
-    CacheOp(op, vaddr, paddr, instruction_0);
+
+    int uncached;
+    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))
+      CacheOp(op, vaddr, paddr, instruction_0);
   }
 }
 
@@ -6867,4 +7109,5 @@
 :include:::smartmips.igen
 :include:::micromips.igen
 :include:::micromipsdsp.igen
-
+:include:::nanomipsr6.igen
+:include:::nanomipsdsp.igen
diff --git a/sim/mips/nanomipsdsp.igen b/sim/mips/nanomipsdsp.igen
new file mode 100644
index 00000000000..65d0282f325
--- /dev/null
+++ b/sim/mips/nanomipsdsp.igen
@@ -0,0 +1,1116 @@
+// Simulator definition for the micromips ASE.
+// Copyright (C) 2018-2022 Free Software Foundation, Inc.
+// Contributed by Imagination Technologies, Ltd.
+// Written by Ali Lown <ali.lown@imgtec.com>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+001000,5.RT,5.RS,0001000100111111:POOL32A:32::ABSQ_S.PH
+"absq_s.ph r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_s_absq (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,0000000100111111:POOL32A:32::ABSQ_S.QB
+"absq_s.qb r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_s_absq (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,0010000100111111:POOL32A:32::ABSQ_S.W
+"absq_s.w r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_w_s_absq (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,5.RD,00000001101:POOL32A:32::ADDQ.PH
+"addq.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10000001101:POOL32A:32::ADDQ_S.PH
+"addq_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1100000101:POOL32A:32::ADDQ_S.W
+"addq_s.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_op (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,00001001101:POOL32A:32::ADDQH.PH
+"addqh.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10001001101:POOL32A:32::ADDQH_R.PH
+"addqh_r.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,00010001101:POOL32A:32::ADDQH.W
+"addqh.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10010001101:POOL32A:32::ADDQH_R.W
+"addqh_r.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1110000101:POOL32A:32::ADDSC
+"addsc r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_addsc (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,00100001101:POOL32A:32::ADDU.PH
+"addu.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10100001101:POOL32A:32::ADDU_S.PH
+"addu_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,00011001101:POOL32A:32::ADDU.QB
+"addu.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10011001101:POOL32A:32::ADDU_S.QB
+"addu_s.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1111000101:POOL32A:32::ADDWC
+"addwc r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_addwc (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,00101001101:POOL32A:32::ADDUH.QB
+"adduh.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10101001101:POOL32A:32::ADDUH_R.QB
+"adduh_r.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,5.SA,1.X,1000010101:POOL32A:32::APPEND
+"append r<RT>, r<RS>, <SA>"
+*nanomipsdsp:
+{
+  do_append (SD_, RT, RS, SA);
+}
+
+001000,5.RT,5.RS,2.BP,00100010111111:POOL32A:32::BALIGN
+"balign r<RT>, r<RS>, <BP>"
+*nanomipsdsp:
+{
+  do_balign (SD_, RT, RS, BP);
+}
+
+001000,5.RT,5.RS,0011000100111111:POOL32A:32::BITREV
+"bitrev r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_bitrev (SD_, RT, RS);
+}
+
+100010,5.X,0010001,14.IMMEDIATE:POOL32I:32::BPOSGE32C
+"bposge32c <IMMEDIATE>"
+*nanomipsdsp:
+{
+  uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
+  if (pos >= 32)
+    NIA = delayslot_micromips (SD_, NIA + (EXTEND12 (IMMEDIATE) << 1), NIA,
+			       MICROMIPS_DELAYSLOT_SIZE_ANY);
+}
+
+001000,5.RT,5.RS,6.X,0000000101:POOL32A:32::CMP.EQ.PH
+"cmp.eq.ph r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,0000000001,000101:POOL32A:32::CMP.LT.PH
+"cmp.lt.ph r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,0000000010,000101:POOL32A:32::CMP.LE.PH
+"cmp.le.ph r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_cmpu (SD_, RS, RT, 2);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0110000101:POOL32A:32::CMPGDU.EQ.QB
+"cmpgdu.eq.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0111000101:POOL32A:32::CMPGDU.LT.QB
+"cmpgdu.lt.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1000000101:POOL32A:32::CMPGDU.LE.QB
+"cmpgdu.le.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgdu (SD_, RD, RS, RT, 2);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0011000101:POOL32A:32::CMPGU.EQ.QB
+"cmpgu.eq.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0100000101:POOL32A:32::CMPGU.LT.QB
+"cmpgu.lt.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0101000101:POOL32A:32::CMPGU.LE.QB
+"cmpgu.le.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpgu (SD_, RD, RS, RT, 2);
+}
+
+001000,5.RT,5.RS,5.X1,1.X2,1001000101:POOL32A:32::CMPU.EQ.QB
+"cmpu.eq.qb r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.X1,1.X2,1010000101:POOL32A:32::CMPU.LT.QB
+"cmpu.lt.qb r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.X1,1.X2,1011000101:POOL32A:32::CMPU.LE.QB
+"cmpu.le.qb r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_cmpu (SD_, RS, RT, 2);
+}
+
+001000,5.RT,5.RS,2.AC,00000010111111:POOL32A:32::DPA.W.PH
+"dpa.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,2.AC,00001010111111:POOL32A:32::DPAQ_S.W.PH
+"dpaq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,2.AC,01001010111111:POOL32A:32::DPAQ_SA.L.W
+"dpaq_sa.l.w ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_dot_product (SD_, AC, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,2.AC,10001010111111:POOL32A:32::DPAQX_S.W.PH
+"dpaqx_s.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,2.AC,11001010111111:POOL32A:32::DPAQX_SA.W.PH
+"dpaqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10000010111111:POOL32A:32::DPAU.H.QBL
+"dpau.h.qbl ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,2.AC,11000010111111:POOL32A:32::DPAU.H.QBR
+"dpau.h.qbr ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,2.AC,01000010111111:POOL32A:32::DPAX.W.PH
+"dpax.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_x_w_ph_dot_product (SD_, AC, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,2.AC,00010010111111:POOL32A:32::DPS.W.PH
+"dps.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,2.AC,00011010111111:POOL32A:32::DPSQ_S.W.PH
+"dpsq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,2.AC,01011010111111:POOL32A:32::DPSQ_SA.L.W
+"dpsq_sa.l.w ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_dot_product (SD_, AC, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10011010111111:POOL32A:32::DPSQX_S.W.PH
+"dpsqx_s.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,2.AC,11011010111111:POOL32A:32::DPSQX_SA.W.PH
+"dpsqx_sa.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qx_w_ph_dot_product (SD_, AC, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10010010111111:POOL32A:32::DPSU.H.QBL
+"dpsu.h.qbl ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,2.AC,11010010111111:POOL32A:32::DPSU.H.QBR
+"dpsu.h.qbr ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_dot_product (SD_, AC, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,2.AC,01010010111111:POOL32A:32::DPSX.W.PH
+"dpsx.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_x_w_ph_dot_product (SD_, AC, RS, RT, 1);
+}
+
+001000,5.RT,5.SIZE,2.AC,10011001111111:POOL32A:32::EXTP
+"extp r<RT>, ac<AC>, <SIZE>"
+*nanomipsdsp:
+{
+  do_extp (SD_, RT, AC, SIZE, 0);
+}
+
+001000,5.RT,5.SIZE,2.AC,11011001111111:POOL32A:32::EXTPDP
+"extpdp r<RT>, ac<AC>, <SIZE>"
+*nanomipsdsp:
+{
+  do_extp (SD_, RT, AC, SIZE, 1);
+}
+
+001000,5.RT,5.RS,2.AC,11100010111111:POOL32A:32::EXTPDPV
+"extpdpv r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extpv (SD_, RT, AC, RS, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10100010111111:POOL32A:32::EXTPV
+"extpv r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extpv (SD_, RT, AC, RS, 0);
+}
+
+001000,5.RT,5.SHIFT,2.AC,00111001111111:POOL32A:32::EXTR.W
+"extr.w r<RT>, ac<AC>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 0);
+}
+
+001000,5.RT,5.SHIFT,2.AC,01111001111111:POOL32A:32::EXTR_R.W
+"extr_r.w r<RT>, ac<AC>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 1);
+}
+
+001000,5.RT,5.SHIFT,2.AC,10111001111111:POOL32A:32::EXTR_RS.W
+"extr_rs.w r<RT>, ac<AC>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_w_extr (SD_, RT, AC, SHIFT, 2);
+}
+
+001000,5.RT,5.SHIFT,2.AC,11111001111111:POOL32A:32::EXTR_S.H
+"extr_s.h r<RT>, ac<AC>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_h_extr (SD_, RT, AC, SHIFT);
+}
+
+001000,5.RT,5.RS,2.AC,00111010111111:POOL32A:32::EXTRV.W
+"extrv.w r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 0);
+}
+
+001000,5.RT,5.RS,2.AC,01111010111111:POOL32A:32::EXTRV_R.W
+"extrv_r.w r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10111010111111:POOL32A:32::EXTRV_RS.W
+"extrv_rs.w r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extrv (SD_, RT, AC, RS, 2);
+}
+
+001000,5.RT,5.RS,2.AC,11111010111111:POOL32A:32::EXTRV_S.H
+"extrv_s.h r<RT>, ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_extrv_s_h (SD_, RT, AC, RS);
+}
+
+001000,5.RT,5.RS,0100000100111111:POOL32A:32::INSV
+"insv r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_insv (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,2.AC,00101010111111:POOL32A:32::MADD_DSP
+"madd ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_madd (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,01101010111111:POOL32A:32::MADDU_DSP
+"maddu ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_maddu (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,01101001111111:POOL32A:32::MAQ_S.W.PHL
+"maq_s.w.phl ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 0, 0);
+}
+
+001000,5.RT,5.RS,2.AC,11101001111111:POOL32A:32::MAQ_SA.W.PHL
+"maq_sa.w.phl ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,2.AC,00101001111111:POOL32A:32::MAQ_S.W.PHR
+"maq_s.w.phr ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 0, 1);
+}
+
+001000,5.RT,5.RS,2.AC,10101001111111:POOL32A:32::MAQ_SA.W.PHR
+"maq_sa.w.phr ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_maq (SD_, AC, RS, RT, 1, 1);
+}
+
+001000,5.RS,5.X,2.AC,00000001111111:POOL32A:32::MFHI_DSP
+"mfhi r<RS>, ac<AC>"
+*nanomipsdsp:
+{
+  do_dsp_mfhi (SD_, AC, RS);
+}
+
+001000,5.RS,5.X,2.AC,01000001111111:POOL32A:32::MFLO_DSP
+"mflo r<RS>, ac<AC>"
+*nanomipsdsp:
+{
+  do_dsp_mflo (SD_, AC, RS);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1010010101:POOL32A:32::MODSUB
+"modsub r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_modsub (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,10101010111111:POOL32A:32::MSUB_DSP
+"msub ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_msub (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,11101010111111:POOL32A:32::MSUBU_DSP
+"msubu ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_msubu (SD_, AC, RS, RT);
+}
+
+001000,00000,5.RS,2.AC,10000001111111:POOL32A:32::MTHI_DSP
+"mthi r<RS>, ac<AC>"
+*nanomipsdsp:
+{
+  do_dsp_mthi (SD_, AC, RS);
+}
+
+001000,00000,5.RS,2.AC,00001001111111:POOL32A:32::MTHLIP
+"mthlip r<RS>, ac<AC>"
+*nanomipsdsp:
+{
+  do_mthlip (SD_, RS, AC);
+}
+
+001000,00000,5.RS,2.AC,11000001111111:POOL32A:32::MTLO_DSP
+"mtlo r<RS>, ac<AC>"
+*nanomipsdsp:
+{
+  do_dsp_mtlo (SD_, AC, RS);
+}
+
+001000,5.RT,5.RS,5.RD,00000101101:POOL32A:32::MUL.PH
+"mul.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 2, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10000101101:POOL32A:32::MUL_S.PH
+"mul_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 2, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0000100101:POOL32A:32::MULEQ_S.W.PHL
+"muleq_s.w.phl r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_muleq (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0001100101:POOL32A:32::MULEQ_S.W.PHR
+"muleq_s.w.phr r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_muleq (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0010010101:POOL32A:32::MULEU_S.PH.QBL
+"muleu_s.ph.qbl r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_muleu (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0011010101:POOL32A:32::MULEU_S.PH.QBR
+"muleu_s.ph.qbr r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_muleu (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0100010101:POOL32A:32::MULQ_RS.PH
+"mulq_rs.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_mulq (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0110010101:POOL32A:32::MULQ_RS.W
+"mulq_rs.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_mulq (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0101010101:POOL32A:32::MULQ_S.PH
+"mulq_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_mulq (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0111010101:POOL32A:32::MULQ_S.W
+"mulq_s.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_mulq (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,2.AC,10110010111111:POOL32A:32::MULSA.W.PH
+"mulsa.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_w_mulsa (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,11110010111111:POOL32A:32::MULSAQ_S.W.PH
+"mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_mulsaq_s_w_ph (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,00110010111111:POOL32A:32::MULT_DSP
+"mult ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_mult (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,2.AC,01110010111111:POOL32A:32::MULTU_DSP
+"multu ac<AC>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_dsp_multu (SD_, AC, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0110101101:POOL32A:32::PACKRL.PH
+"packrl.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_packrl (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1000101101:POOL32A:32::PICK.PH
+"pick.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_pick (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0111101101:POOL32A:32::PICK.QB
+"pick.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_pick (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,0101000100111111:POOL32A:32::PRECEQ.W.PHL
+"preceq.w.phl r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_w_preceq (SD_, RT, RS, 0);
+}
+
+001000,5.RT,5.RS,0110000100111111:POOL32A:32::PRECEQ.W.PHR
+"preceq.w.phr r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_w_preceq (SD_, RT, RS, 1);
+}
+
+001000,5.RT,5.RS,0111000100111111:POOL32A:32::PRECEQU.PH.QBL
+"precequ.ph.qbl r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 2);
+}
+
+001000,5.RT,5.RS,0111001100111111:POOL32A:32::PRECEQU.PH.QBLA
+"precequ.ph.qbla r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 3);
+}
+
+001000,5.RT,5.RS,1001000100111111:POOL32A:32::PRECEQU.PH.QBR
+"precequ.ph.qbr r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 0);
+}
+
+001000,5.RT,5.RS,1001001100111111:POOL32A:32::PRECEQU.PH.QBRA
+"precequ.ph.qbra r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_precequ (SD_, RT, RS, 1);
+}
+
+001000,5.RT,5.RS,1011000100111111:POOL32A:32::PRECEU.PH.QBL
+"preceu.ph.qbl r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 2);
+}
+
+001000,5.RT,5.RS,1011001100111111:POOL32A:32::PRECEU.PH.QBLA
+"preceu.ph.qbla r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 3);
+}
+
+001000,5.RT,5.RS,1101000100111111:POOL32A:32::PRECEU.PH.QBR
+"preceu.ph.qbr r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 0);
+}
+
+001000,5.RT,5.RS,1101001100111111:POOL32A:32::PRECEU.PH.QBRA
+"preceu.ph.qbra r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_ph_preceu (SD_, RT, RS, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0001101101:POOL32A:32::PRECR.QB.PH
+"precr.qb.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_qb_precr (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.SA,01111001101:POOL32A:32::PRECR_SRA.PH.W
+"precr_sra.ph.w r<RT>, r<RS>, <SA>"
+*nanomipsdsp:
+{
+  do_precr_sra (SD_, RT, RS, SA, 0);
+}
+
+001000,5.RT,5.RS,5.SA,11111001101:POOL32A:32::PRECR_SRA_R.PH.W
+"precr_sra_r.ph.w r<RT>, r<RS>, <SA>"
+*nanomipsdsp:
+{
+  do_precr_sra (SD_, RT, RS, SA, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0011101101:POOL32A:32::PRECRQ.PH.W
+"precrq.ph.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_ph_precrq (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0010101101:POOL32A:32::PRECRQ.QB.PH
+"precrq.qb.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_qb_precrq (SD_, RD, RS, RT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0101101101:POOL32A:32::PRECRQU_S.QB.PH
+"precrqu_s.qb.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_qb_precrq (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0100101101:POOL32A:32::PRECRQ_RS.PH.W
+"precrq_rs.ph.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_ph_rs_precrq (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.SA,1.X,1001010101:POOL32A:32::PREPEND
+"prepend r<RT>, r<RS>, <SA>"
+*nanomipsdsp:
+{
+  do_prepend (SD_, RT, RS, SA);
+}
+
+001000,5.RT,5.RS,1111000100111111:POOL32A:32::RADDU.W.QB
+"raddu.w.qb r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_w_raddu (SD_, RT, RS);
+}
+
+001000,5.RT,7.CONTROL_MASK,00011001111111:POOL32A:32::RDDSP
+"rddsp r<RT>":CONTROL_MASK == 1111111111
+"rddsp r<RT>, <CONTROL_MASK>"
+*nanomipsdsp:
+{
+  do_rddsp (SD_, RT, CONTROL_MASK);
+}
+
+001000,5.RT,10.IMMEDIATE,1.X,0000111101:POOL32A:32::REPL.PH
+"repl.ph r<RT>, <IMMEDIATE>"
+*nanomipsdsp:
+{
+  do_repl (SD_, RT, IMMEDIATE, 2);
+}
+
+001000,5.RT,8.IMMEDIATE,1.X,010111111111:POOL32A:32::REPL.QB
+"repl.qb r<RT>, <IMMEDIATE>"
+*nanomipsdsp:
+{
+  do_repl (SD_, RT, IMMEDIATE, 0);
+}
+
+001000,5.RT,5.RS,0000001100111111:POOL32A:32::REPLV.PH
+"replv.ph r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_repl (SD_, RT, RS, 3);
+}
+
+001000,5.RT,5.RS,0001001100111111:POOL32A:32::REPLV.QB
+"replv.qb r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_repl (SD_, RT, RS, 1);
+}
+
+001000,0000,6.IMMEDIATE,2.AC,00000000011101:POOL32A:32::SHILO
+"shilo ac<AC>, <IMMEDIATE>"
+*nanomipsdsp:
+{
+  do_shilo (SD_, AC, IMMEDIATE);
+}
+
+001000,00000,5.RS,2.AC,01001001111111:POOL32A:32::SHILOV
+"shilov ac<AC>, r<RS>"
+*nanomipsdsp:
+{
+  do_shilov (SD_, AC, RS);
+}
+
+001000,5.RT,5.RS,4.SHIFT,001110110101:POOL32A:32::SHLL.PH
+"shll.ph r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 0, 0);
+}
+
+001000,5.RT,5.RS,4.SHIFT,101110110101:POOL32A:32::SHLL_S.PH
+"shll_s.ph r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 0, 1);
+}
+
+001000,5.RT,5.RS,3.SHIFT,0100001111111:POOL32A:32::SHLL.QB
+"shll.qb r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_qb_shift (SD_, RT, RS, SHIFT, 0);
+}
+
+001000,5.RT,5.RS,5.RD,01110001101:POOL32A:32::SHLLV.PH
+"shllv.ph r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 0, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11110001101:POOL32A:32::SHLLV_S.PH
+"shllv_s.ph r<RD>, r<RD>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 0, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1110010101:POOL32A:32::SHLLV.QB
+"shllv.qb r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_shl (SD_, RD, RT, RS, 0);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1111010101:POOL32A:32::SHLLV_S.W
+"shllv_s.w r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_w_s_shllv (SD_, RD, RT, RS);
+}
+
+001000,5.RT,5.RS,5.SHIFT,1.X,1111110101:POOL32A:32::SHLL_S.W
+"shll_s.w r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_w_shll (SD_, RT, RS, SHIFT);
+}
+
+001000,5.RT,5.RS,3.SHIFT,0000111111111:POOL32A:32::SHRA.QB
+"shra.qb r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_qb_shra (SD_, RT, RS, SHIFT, 0);
+}
+
+001000,5.RT,5.RS,3.SHIFT,1000111111111:POOL32A:32::SHRA_R.QB
+"shra_r.qb r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_qb_shra (SD_, RT, RS, SHIFT, 1);
+}
+
+001000,5.RT,5.RS,4.SHIFT,1.X,01100110101:POOL32A:32::SHRA.PH
+"shra.ph r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 1, 0);
+}
+
+001000,5.RT,5.RS,4.SHIFT,1.X,11100110101:POOL32A:32::SHRA_R.PH
+"shra_r.ph r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_ph_shift (SD_, RT, RS, SHIFT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,00110001101:POOL32A:32::SHRAV.PH
+"shrav.ph r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10110001101:POOL32A:32::SHRAV_R.PH
+"shrav_r.ph r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_shl (SD_, RD, RT, RS, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,00111001101:POOL32A:32::SHRAV.QB
+"shrav.qb r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_shrav (SD_, RD, RT, RS, 0);
+}
+
+001000,5.RT,5.RS,5.RD,10111001101:POOL32A:32::SHRAV_R.QB
+"shrav_r.qb r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_shrav (SD_, RD, RT, RS, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1011010101:POOL32A:32::SHRAV_R.W
+"shrav_r.w r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_w_r_shrav (SD_, RD, RT, RS);
+}
+
+001000,5.RT,5.RS,5.SHIFT,1.X,1011110101:POOL32A:32::SHRA_R.W
+"shra_r.w r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_w_shra (SD_, RT, RS, SHIFT);
+}
+
+001000,5.RT,5.RS,4.SHIFT,001111111111:POOL32A:32::SHRL.PH
+"shrl.ph r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_ph_shrl (SD_, RT, RS, SHIFT);
+}
+
+001000,5.RT,5.RS,3.SHIFT,1100001111111:POOL32A:32::SHRL.QB
+"shrl.qb r<RT>, r<RS>, <SHIFT>"
+*nanomipsdsp:
+{
+  do_qb_shift (SD_, RT, RS, SHIFT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1100010101:POOL32A:32::SHRLV.PH
+"shrlv.ph r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_ph_shrlv (SD_, RD, RT, RS);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1101010101:POOL32A:32::SHRLV.QB
+"shrlv.qb r<RD>, r<RT>, r<RS>"
+*nanomipsdsp:
+{
+  do_qb_shl (SD_, RD, RT, RS, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01000001101:POOL32A:32::SUBQ.PH
+"subq.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11000001101:POOL32A:32::SUBQ_S.PH
+"subq_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1101000101:POOL32A:32::SUBQ_S.W
+"subq_s.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_w_op (SD_, RD, RS, RT, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01001001101:POOL32A:32::SUBQH.PH
+"subqh.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11001001101:POOL32A:32::SUBQH_R.PH
+"subqh_r.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01010001101:POOL32A:32::SUBQH.W
+"subqh.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11010001101:POOL32A:32::SUBQH_R.W
+"subqh_r.w r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qh_w_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01100001101:POOL32A:32::SUBU.PH
+"subu.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11100001101:POOL32A:32::SUBU_S.PH
+"subu_s.ph r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_u_ph_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01011001101:POOL32A:32::SUBU.QB
+"subu.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11011001101:POOL32A:32::SUBU_S.QB
+"subu_s.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_qb_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,5.RS,5.RD,01101001101:POOL32A:32::SUBUH.QB
+"subuh.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 1, 0);
+}
+
+001000,5.RT,5.RS,5.RD,11101001101:POOL32A:32::SUBUH_R.QB
+"subuh_r.qb r<RD>, r<RS>, r<RT>"
+*nanomipsdsp:
+{
+  do_uh_qb_op (SD_, RD, RS, RT, 1, 1);
+}
+
+001000,5.RT,7.CONTROL_MASK,01011001111111:POOL32A:32::WRDSP
+"wrdsp r<RT>":CONTROL_MASK == 1111111111
+"wrdsp r<RT>, <CONTROL_MASK>"
+*nanomipsdsp:
+{
+  do_wrdsp (SD_, RT, CONTROL_MASK);
+}
diff --git a/sim/mips/nanomipsr6.igen b/sim/mips/nanomipsr6.igen
new file mode 100644
index 00000000000..109fa1510f9
--- /dev/null
+++ b/sim/mips/nanomipsr6.igen
@@ -0,0 +1,3283 @@
+// Simulator definition for the nanoMIPS.
+// Copyright (C) 2018-2022 Free Software Foundation, Inc.
+// Contributed by Imagination Technologies, Ltd.
+// Written by Ali Lown <ali.lown@imgtec.com>
+//
+// 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 3 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, see <http://www.gnu.org/licenses/>.
+
+:compute:::int:U_SHIFT_1BIT:U:(U << 1)
+:compute:::int:U_SHIFT_2BIT:U:(U << 2)
+:compute:::int:U_SHIFT_3BIT:U:(U << 3)
+:compute:::int:U_SHIFT_4BIT:U:(U << 4)
+:compute:::int:EU_127:EU:((EU == 127) ? -1 \: EU)
+:compute:::int:U_LW4X4:U2,U3:((U3 << 3) | (U2 << 2))
+:compute:::int:AXUIPC_S_LO:S1,S2,S3:((EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12))) & 0x0000ffff)
+:compute:::int:AXUIPC_S_HI:S1,S2,S3:((EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12))) & 0xffff0000)
+:compute:::int:AXUIPC_S:S1,S2,S3:(EXTEND32((S3 << 31) | (S2 << 21) | (S1 << 12)))
+:compute:::int:TRD2:RD20,RD21:(compute_gpr2_dest1_reg (SD_, (RD21 << 1 | RD20)))
+:compute:::int:TRE2:RD20,RD21:(compute_gpr2_dest2_reg (SD_, (RD21 << 1 | RD20)))
+:compute:::int:TRS2:RS4,RS2_0:(compute_gpr4_zero (SD_, (RS4 << 3 | RS2_0)))
+:compute:::int:TRT2:RT4,RT2_0:(compute_gpr4_zero (SD_, (RT4 << 3 | RT2_0)))
+:compute:::int:TRD2_REV:RD4,RD2_0:(compute_gpr4 (SD_, (RD4 << 3) | RD2_0))
+:compute:::int:TRE2_REV:RE4,RE2_0:(compute_gpr4 (SD_, (RE4 << 3) | RE2_0))
+:compute:::int:TRS2_REV:RS20,RS21:(compute_gpr2_dest1_reg (SD_, (RS21 << 1 | RS20)))
+:compute:::int:TRT2_REV:RS20,RS21:(compute_gpr2_dest2_reg (SD_, (RS21 << 1 | RS20)))
+:compute:::address_word:ADDRESS8:S1,S2:(nia + EXTEND8((S2 << 7) | (S1 << 1)))
+:compute:::address_word:ADDRESS11:S1,S2:(nia + EXTEND11((S2 << 10) | (S1 << 1)))
+:compute:::address_word:ADDRESS15:S1,S2:(nia + EXTEND15((S2 << 14) | (S1 << 1)))
+:compute:::address_word:ADDRESS21:S1,S2:(nia + EXTEND21((S2 << 20) | (S1 << 1)))
+:compute:::address_word:ADDRESS22:S1,S2:(nia + EXTEND22((S2 << 21) | (S1 << 1)))
+:compute:::address_word:ADDRESS26:S1,S2:(nia + EXTEND26((S2 << 25) | (S1 << 1)))
+:compute:::int:INS_POS:LSB:(LSB)
+:compute:::int:INS_SIZE:LSB,MSBD:(1 + MSBD - LSB)
+:compute:::address_word:ADDRESS12:S1,S2:(nia + EXTEND12(S2 << 11 | S1 << 1))
+:compute:::int:S_14_BIT:S1,S2:(EXTEND14 ((S1 << 13) | S2))
+:compute:::int:S_4_BIT:S1,S2:(EXTEND4((S1 << 3) | S2))
+:compute:::int:S_9_BIT:S1,S2:(EXTEND9((S1 << 8) | S2))
+:compute:::int:S_9_BIT_LLSC:S1,S2:(EXTEND9((S1 << 8) | (S2 << 2)))
+:compute:::int:RD1:RD:(compute_gpr1_dest_reg (SD_, RD))
+:compute:::int:RT_5_BIT_NM_Z:RT1,RT2:(compute_gpr4_zero (SD_, (RT1 << 3) | RT2))
+:compute:::int:RT_5_BIT_NM:RT1,RT2:(compute_gpr4 (SD_, (RT1 << 3) | RT2))
+:compute:::int:RS_5_BIT_NM:RS1,RS2:(compute_gpr4 (SD_, (RS1 << 3) | RS2))
+:compute:::int:TRTZ:RTZ:((RTZ >= 1 && RTZ <= 3) ? (16 + RTZ) \: RTZ)
+:compute:::int:EU_12_13:EU:((EU == 12) ? 255 \: ((EU == 13) ? 65535 \: EU))
+:compute:::int:RS_MOVE:RS1,RS_CODE_1,RS_CODE_2:((RS1 << 3) | (RS_CODE_1 << 2) | RS_CODE_2)
+:compute:::int:CODE_BREAK:RS_CODE_1,RS_CODE_2:((RS_CODE_1 << 2) | RS_CODE_2)
+:compute:::int:TRD_NM:RD:((RD < 4) ? (16 + RD) \: RD)
+:compute:::int:TRS_NM:RS:((RS < 4) ? (16 + RS) \: RS)
+:compute:::int:TRT_NM:RT:((RT < 4) ? (16 + RT) \: RT)
+:compute:::int:COUNT:COUNT3:(COUNT3 == 0 ? 8 \: COUNT3)
+:compute:::int:SHIFTX_1BIT:SHIFTX:(SHIFTX << 1)
+
+:function:::void:do_msubf:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT3 (FGR[fd], FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, FusedMultiplySub (ValueFPR (fs, fmt),
+               ValueFPR (ft, fmt),
+               ValueFPR (fd, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_maddf:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT3 (FGR[fd], FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, FusedMultiplyAdd (ValueFPR (fs, fmt),
+               ValueFPR (ft, fmt),
+               ValueFPR (fd, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_rint:int fd, int fs, int fmt, instruction_word instruction_0
+{
+  uint64_t result = 0;
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT1 (FGR[fs]);
+  RoundToIntegralExact (ValueFPR (fs, fmt), &result, fmt);
+  StoreFPR (fd, fmt, result);
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_class:int fd, int fs, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  StoreFPR (fd, fmt, Classify (ValueFPR (fs, fmt), fmt));
+}
+
+:function:::void:do_seleqzf:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (ValueFPR(fs, fmt), FGR[ft]);
+  if ((FGR[ft] & 0x01) == 0)
+    StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+  else
+    StoreFPR (fd, fmt, 0);
+  TRACE_ALU_RESULT (ValueFPR(fd, fmt));
+}
+
+:function:::void:do_selnezf:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (ValueFPR(fs, fmt), FGR[ft]);
+  if ((FGR[ft] & 0x01) == 0x1)
+    StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+  else
+    StoreFPR (fd, fmt, 0);
+  TRACE_ALU_RESULT (ValueFPR(fd, fmt));
+}
+
+:function:::void:do_self:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT3 (FGR[fd], ValueFPR(fs, fmt), ValueFPR(ft, fmt));
+  if ((FGR[fd] & 0x01) != 0)
+    StoreFPR (fd, fmt, ValueFPR (ft, fmt));
+  else
+    StoreFPR (fd, fmt, ValueFPR (fs, fmt));
+  TRACE_ALU_RESULT (ValueFPR(fd, fmt));
+}
+
+:function:::void:do_mina:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, MinA (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_maxa:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, MaxA (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_max:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, Max (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_min:int fd, int fs, int ft, int fmt, instruction_word instruction_0
+{
+  check_fpu (SD_);
+  check_u64 (SD_, instruction_0);
+  check_fmt_p (SD_, fmt, instruction_0);
+  TRACE_ALU_INPUT2 (FGR[fs], FGR[ft]);
+  StoreFPR (fd, fmt, Min (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt));
+  TRACE_ALU_RESULT (FGR[fd]);
+}
+
+:function:::void:do_cmp:int fd, int fs, int ft, int fmt, int condition
+{
+  uint64_t result;
+  check_fpu (SD_);
+  TRACE_ALU_INPUT2 (ValueFPR (fs, fmt), ValueFPR (ft, fmt));
+  result = R6Compare (ValueFPR (fs, fmt), ValueFPR (ft, fmt), fmt, condition);
+  StoreFPR (fd, fmt, result);
+  TRACE_ALU_RESULT (result);
+}
+
+:function:::void:do_modu:int rd, int rs, int rt
+{
+  uint32_t n = GPR[rs];
+  uint32_t d = GPR[rt];
+  TRACE_ALU_INPUT2 (n,d);
+  if (d == 0)
+    GPR[rd] = EXTEND32 (0);
+  else
+    GPR[rd] = EXTEND32 (n % d);
+
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_mod:int rd, int rs, int rt
+{
+  int32_t n = GPR[rs];
+  int32_t d = GPR[rt];
+  TRACE_ALU_INPUT2 (n,d);
+  if (d == 0 || (n == SIGNED32 (0x80000000) && d == -1))
+    GPR[rd] = EXTEND32 (0);
+  else
+    GPR[rd] = EXTEND32 (n % d);
+
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_muhu:int rd, int rs, int rt
+{
+  uint64_t prod;
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = ((uint64_t)(uint32_t) GPR[rs])
+    * ((uint64_t)(uint32_t) GPR[rt]);
+  GPR[rd] = EXTEND32 (VH4_8 (prod));
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_mulu:int rd, int rs, int rt
+{
+  uint64_t prod;
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = ((uint64_t)(uint32_t) GPR[rs])
+    * ((uint64_t)(uint32_t) GPR[rt]);
+  GPR[rd] = EXTEND32 (VL4_8 (prod));
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_muh:int rd, int rs, int rt
+{
+  int64_t prod;
+  if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]);
+  prod = ((int64_t)(int32_t) GPR[rs])
+    * ((int64_t)(int32_t) GPR[rt]);
+  GPR[rd] = EXTEND32 (VH4_8 (prod));
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_lsa:int rd, int rs, int rt, unsigned immediate
+{
+  uint32_t t = GPR[rs] << immediate;
+  GPR[rd] = EXTEND32(GPR[rt] + t);
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_divu:int rd, int rs, int rt
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint32_t n = GPR[rs];
+  uint32_t d = GPR[rt];
+  TRACE_ALU_INPUT2 (n,d);
+  if (d == 0)
+    GPR[rd] = EXTEND32 (0x80000000);
+  else
+    GPR[rd] = EXTEND32 (n / d);
+
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_div:int rd, int rs, int rt
+*nanomips32r6:
+*nanomips64r6:
+{
+  int32_t n = GPR[rs];
+  int32_t d = GPR[rt];
+  TRACE_ALU_INPUT2 (n,d);
+  if (d == 0)
+    GPR[rd] = EXTEND32 (0x80000000);
+  else if (n == SIGNED32 (0x80000000) && d == -1)
+    GPR[rd] = EXTEND32 (0x80000000);
+  else
+    GPR[rd] = EXTEND32 (n / d);
+
+  TRACE_ALU_RESULT (GPR[rd]);
+}
+
+:function:::void:do_llwp:int rt, int ru, int roffset, int rbase
+{
+  address_word base = GPR[rbase];
+  address_word offset = EXTEND16 (roffset);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 7) != 0)
+      {
+  SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
+    sim_core_unaligned_signal);
+      }
+    else
+      {
+  if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
+             isTARGET, isREAL))
+    {
+      uint64_t memval = 0;
+      uint64_t memval1 = 0;
+      uint64_t data = memval;
+
+      LoadMemory (&memval, &memval1, uncached, AccessLength_DOUBLEWORD,
+            paddr, vaddr, isDATA, isREAL);
+
+      GPR[rt] = EXTEND32 (data & 0xFFFFFFFF);
+      GPR[ru] = EXTEND32 (data >> 32);
+
+      LLBIT = 1;
+      COP0_COUNT++;
+    }
+      }
+  }
+}
+
+:function:::void:do_rotx:int rt, int rs, int shift, int shiftx, int stripe
+{
+  int i;
+  uint64_t tmp0 = ((uint64_t)GPR[rs] << 32) | (GPR[rs] & 0xFFFFFFFF);
+  uint64_t tmp1, tmp2, tmp3, tmp4, tmp5;
+
+  tmp1 = tmp0;
+  for (i = 0; i <=46; i++) {
+    int s;
+
+    if (i & 0x8)
+      s = shift;
+    else
+      s = shiftx;
+
+    if (stripe != 0 && !(i & 0x4))
+      s = ~s;
+
+    if (s & 0x10) {
+      if (tmp0 & (1LL << (i + 16)))
+        tmp1 |= 1LL << i;
+      else
+        tmp1 &= ~(1LL << i);
+    }
+  }
+
+  tmp2 = tmp1;
+  for (i = 0; i <=38; i++) {
+    int s;
+
+    if (i & 0x4)
+      s = shift;
+    else
+      s = shiftx;
+
+    if (s & 0x8) {
+      if (tmp1 & (1LL << (i + 8)))
+        tmp2 |= 1LL << i;
+      else
+        tmp2 &= ~(1LL << i);
+    }
+  }
+
+  tmp3 = tmp2;
+  for (i = 0; i <=34; i++) {
+    int s;
+
+    if (i & 0x2)
+      s = shift;
+    else
+      s = shiftx;
+
+    if (s & 0x4) {
+      if (tmp2 & (1LL << (i + 4)))
+        tmp3 |= 1LL << i;
+      else
+        tmp3 &= ~(1LL << i);
+    }
+  }
+
+  tmp4 = tmp3;
+  for (i = 0; i <=32; i++) {
+    int s;
+
+    if (i & 0x1)
+      s = shift;
+    else
+      s = shiftx;
+
+    if (s & 0x2) {
+      if (tmp3 & (1LL << (i + 2)))
+        tmp4 |= 1LL << i;
+      else
+        tmp4 &= ~(1LL << i);
+    }
+  }
+
+  tmp5 = tmp4;
+  for (i = 0; i <=31; i++) {
+    int s;
+
+    s = shift;
+
+    if (s & 0x1) {
+      if (tmp4 & (1LL << (i + 1)))
+        tmp5 |= 1LL << i;
+      else
+        tmp5 &= ~(1LL << i);
+    }
+  }
+
+  GPR[rt] = EXTEND32 (tmp5);
+}
+
+:function:::void:do_lwc1xs:int ft, int rbase, int roffset
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  COP_LW (1, ft, do_load (SD_, AccessLength_WORD, GPR[rbase] << 2,
+        GPR[roffset]));
+}
+
+:function:::void:do_lwpc_nanomips:int rt, uint32_t offset, address_word nia
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, nia, offset));
+}
+
+:function:::void:check_nms_flag:
+*nanomips32r6:
+*nanomips64r6:
+{
+  if(nms_flag == 0)
+    sim_engine_abort (SD, CPU, CIA, "Error: NMS instruction generated\
+  (nanoMIPS Subset is disabled - use -march=32r6s option)\n");
+}
+
+:function:::void:do_swc1xs:int ft, int rbase, int roffset, address_word instruction_0
+*nanomips32r6:
+*nanomips64r6:
+{
+  address_word base = GPR[rbase] << 2;
+  address_word offset = GPR[roffset];
+  check_fpu (SD_);
+  {
+    address_word vaddr = loadstore_ea (SD_, base, offset);
+    address_word paddr;
+    int uncached;
+    if ((vaddr & 3) != 0)
+      {
+  SIM_CORE_SIGNAL (SD, CPU, cia, read_map, AccessLength_WORD+1, vaddr,
+       write_transfer, sim_core_unaligned_signal);
+      }
+    else
+      {
+  if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
+              isTARGET, isREAL))
+    {
+      uword64 memval = 0;
+      uword64 memval1 = 0;
+      uword64 mask = (WITH_TARGET_WORD_BITSIZE == 64 ? 0x7 : 0x3);
+      address_word reverseendian =
+        (ReverseEndian ?(mask ^ AccessLength_WORD): 0);
+      address_word bigendiancpu =
+        (BigEndianCPU ?(mask ^ AccessLength_WORD): 0);
+      unsigned int byte;
+      paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
+      byte = ((vaddr & mask) ^ bigendiancpu);
+      memval = (((uword64)COP_SW(1, ft)) << (8 * byte));
+      StoreMemory (uncached, AccessLength_WORD, memval, memval1, paddr,
+       vaddr, isREAL);
+    }
+      }
+  }
+}
+
+:function:::uint32_t:compute_gpr2_dest1_reg:int reg
+*nanomips32r6:
+*nanomips64r6:
+{
+  switch(reg)
+    {
+    case 0: return 4;
+    case 1: return 5;
+    case 2: return 6;
+    case 3: return 7;
+    default: return 4;
+    }
+}
+
+:function:::uint32_t:compute_gpr4_zero:int reg
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (reg == 3) return 0;
+  else if (reg >=4 && reg <= 7) return reg;
+  else return reg + 8;
+}
+
+:function:::uint32_t:compute_gpr4:int reg
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (reg >=4 && reg <= 7) return reg;
+  else return reg + 8;
+}
+
+:function:::uint32_t:compute_gpr2_dest2_reg:int reg
+*nanomips32r6:
+*nanomips64r6:
+{
+  switch(reg)
+    {
+    case 0: return 5;
+    case 1: return 6;
+    case 2: return 7;
+    case 3: return 8;
+    default: return 5;
+    }
+}
+
+:function:::uint32_t:compute_gpr1_dest_reg:int reg
+*nanomips32r6:
+*nanomips64r6:
+{
+  switch(reg)
+    {
+    case 0: return 4;
+    case 1: return 5;
+    default: return 4;
+    }
+}
+
+:function:::unsigned:zero_extend:signed_word value, uint32_t from_nbits
+{
+  uint32_t low_bits_mask = (1 << from_nbits) - 1;
+  return value & low_bits_mask;
+}
+
+:function:::void:do_save_gprs_to_stack_and_adjust_sp: int first_gpr, int count, int gp, int u
+*nanomips32r6:
+*nanomips64r6:
+{
+  int counter = 0;
+
+  while (counter != count) {
+    int gpr = (first_gpr & 0x10) | ((first_gpr + counter) & 0x1F);
+    int offset = - ( (counter + 1) << 2 );
+
+    if ( gp && (counter == count - 1))
+      gpr = 28;
+
+    do_store (SD_, AccessLength_WORD, GPR[SPIDX], offset, GPR[gpr]);
+
+    counter++;
+    COP0_COUNT++;
+  }
+
+  GPR[SPIDX] -= u;
+}
+
+:function:::void:do_restore_gprs_from_stack_and_adjust_sp: int first_gpr, int count, int gp, int u
+*nanomips32r6:
+*nanomips64r6:
+{
+  int counter = 0;
+
+  while (counter != count) {
+    int gpr = (first_gpr & 0x10) | ((first_gpr + counter) & 0x1F);
+    int offset;
+
+    if (gpr == 29)
+      Unpredictable();
+
+    offset = u - ((counter + 1) << 2);
+
+    if ( gp && (counter == count - 1))
+      gpr = 28;
+
+    GPR[gpr] = EXTEND32 (do_load(SD_, AccessLength_WORD, GPR[SPIDX], offset));
+
+    counter++;
+    COP0_COUNT++;
+  }
+
+  GPR[SPIDX] += u;
+}
+
+:function:::address_word:do_eret:int nc, address_word nia
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (SR & status_ERL)
+    {
+      /* Oops, not yet available */
+      sim_io_printf (SD, "Warning: ERET when SR[ERL] set not supported");
+      nia = EPC;
+      SR &= ~status_ERL;
+    }
+  else
+    {
+      nia = EPC;
+      SR &= ~status_EXL;
+      //if ( SRSCtl.HSS > 0 && Status.BEV == 0)
+      //  SRSCtl.CSS = SRSCtl.PSS
+  }
+
+  if (!nc)
+    LLBIT = 0;
+
+  //TODO: ClearHazards()
+  return nia;
+}
+
+:%s::::GPR_LIST_SAVE:int count
+*nanomips32r6:
+*nanomips64r6:
+{
+  int i;
+  static char gpr_list[100];
+
+  gpr_list[0] = '\0';
+
+  i = 0;
+
+  while (i<count)
+    {
+      char str1[32];
+      if (i == 0 || i==count-1) {
+        sprintf(str1, "%d", i);
+        strcat (gpr_list,"s");
+        strcat (gpr_list,str1);
+        if(i==0 && count > 1)
+          strcat (gpr_list,"-");
+      }
+      i++;
+    }
+  return (gpr_list);
+}
+
+:function:::void:do_break_nanomips:address_word instruction_0
+{
+  /* Check for some break instruction which are reserved for use by the
+     simulator.  */
+  unsigned int break_code = instruction_0 & HALT_INSTRUCTION_MASK_NANOMIPS;
+  if (break_code == (HALT_INSTRUCTION_NANOMIPS & HALT_INSTRUCTION_MASK_NANOMIPS))
+    {
+      sim_engine_halt (SD, CPU, NULL, cia,
+           sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
+    }
+  else if (break_code == (BREAKPOINT_INSTRUCTION_NANOMIPS & HALT_INSTRUCTION_MASK_NANOMIPS))
+    {
+      PC = cia;
+      SignalException (BreakPoint, instruction_0);
+    }
+
+  else
+    {
+    /* If we get this far, we're not an instruction reserved by the sim. Raise
+       the exception. */
+      SignalException (BreakPoint, instruction_0);
+    }
+}
+
+:function:::FP_formats:convert_fmt_micromips_mul:int fmt
+*nanomips32r6:
+*nanomips64r6:
+{
+  switch (fmt)
+    {
+    case 1: return fmt_single;
+    case 3: return fmt_double;
+    default: return fmt_unknown;
+    }
+}
+
+:%s::::GP_SAVE:int gp
+*nanomips32r6:
+*nanomips64r6:
+{
+  return (gp > 0) ? "gp" : "";
+}
+
+:%s::::FP_SAVE:int fp
+*nanomips32r6:
+*nanomips64r6:
+{
+  return (fp > 0) ? "fp" : "";
+}
+
+11111111111111111111111111111111:R6DUMMY:32,f::DUMMY0.fmt
+"dummy 0"
+*nanomips32r6:
+*nanomips64r6:
+{
+  /* Just needed so GNUSIM builds */
+}
+
+011100,3.RT,1,6.U:R6P16A1:16::ADDIUR1SP
+"addiu r<TRT_NM>, SP, <U_SHIFT_2BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, SPIDX, TRT_NM, U_SHIFT_2BIT);
+}
+
+100100,3.RT,3.RS,0,3.U:R6P16A2:16::ADDIUR2
+"addiu r<TRT_NM>, r<TRS_NM>, <U_SHIFT_2BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, TRS_NM, TRT_NM, U_SHIFT_2BIT);
+}
+
+100100,5.RT,1.S1,1,3.S2:R6P16ADDIURS5:16::ADDIURS5
+"nop":RT==0
+"addiu r<RT>, <S_4_BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (RT != 0)
+    do_addiu (SD_, RT, RT, S_4_BIT);
+}
+
+000001,5.RT,20.S1,1.S2:R6P32:32::ADDIUPC
+"addiu r<RT>, <ADDRESS22>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[RT] = ADDRESS22;
+}
+
+011000,5.RT,00011,16.IMM48:R6POOL48I:32::ADDIUPC48
+"addiu r<RT>, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t U2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = U2 << 16 | IMM48;
+  TRACE_ALU_INPUT2(GPR[RT], total);
+  GPR[RT] = CIA + 6 + EXTEND32(total);
+  TRACE_ALU_RESULT(GPR[RT]);
+  NIA = CIA + 6;
+}
+
+101100,3.RT,3.RS,3.RD,0:R6P16ADDU:16::ADDU16
+"addu r<TRD_NM>, r<TRS_NM>, r<TRT_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addu (SD_, TRS_NM, TRT_NM, TRD_NM);
+}
+
+001111,1.RT1,0,3.RT2,1.RS1,0,3.RS2:R6P164X4:16::ADDU4X4
+"addu r<RT_5_BIT_NM>, r<RS_5_BIT_NM>, r<RT_5_BIT_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_addu (SD_, RS_5_BIT_NM, RT_5_BIT_NM, RT_5_BIT_NM);
+}
+
+010100,3.RT,3.RS,10,0,0:R6POOL16C00:16::AND16
+"and r<TRT_NM>, r<TRS_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_and (SD_, TRS_NM, TRT_NM, TRT_NM);
+}
+
+111100,3.RT,3.RS,4.EU:R6P16:16::ANDI16
+"andi r<TRT_NM>, r<TRS_NM>, <EU_12_13>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_andi (SD_, TRS_NM, TRT_NM, EU_12_13);
+}
+
+001110,9.S1,1.S2:R6P16:16::BALC16
+"balc <ADDRESS11>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(RA);
+  RA = NIA;
+  NIA = ADDRESS11;
+  TRACE_ALU_RESULT(RA);
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+000110,9.S1,1.S2:R6P16:16::BC16
+"bc <ADDRESS11>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  NIA = ADDRESS11;
+}
+
+110110,3.RT,3.RS,4.U!0:R6P16BR1:16::BxxC16
+"beqc r<TRS_NM>, r<TRT_NM>, <U_SHIFT_1BIT>":RS<RT
+"bnec r<TRS_NM>, r<TRT_NM>, <U_SHIFT_1BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  TRACE_ALU_INPUT2(GPR[TRS_NM], GPR[TRT_NM]);
+  if (RS < RT && GPR[TRS_NM] == GPR[TRT_NM])
+    NIA = NIA + U_SHIFT_1BIT; //BEQC
+  else if (RS >= RT && GPR[TRS_NM] != GPR[TRT_NM])
+    NIA = NIA + U_SHIFT_1BIT; //BNEC
+}
+
+100110,3.RT,6.S1,1.S2:R6P16:16::BEQZC16
+"beqzc r<TRT_NM>, <ADDRESS8>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(GPR[TRT_NM]);
+  if(GPR[TRT_NM] == 0)
+    NIA = ADDRESS8;
+}
+
+101110,3.RT,6.S1,1.S2:R6P16:16::BNEZC16
+"bnezc r<TRT_NM>, <ADDRESS8>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(GPR[TRT_NM]);
+  if(GPR[TRT_NM] != 0)
+    NIA = ADDRESS8;
+}
+
+110110,5.RT,1,0000:R6P16JRC:16::JALRC16
+"jalrc r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], RA);
+  RA = NIA;
+  NIA = GPR[RT];
+  TRACE_ALU_RESULT(RA);
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+110110,5.RT,0,0000:R6P16JRC:16::JRC16
+"jrc r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(GPR[RT]);
+  NIA = GPR[RT];
+}
+
+010111,3.RT,3.RS,00,2.U:R6P16LB:16::LB16
+"lb r<TRT_NM>, <U>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lb (SD_, TRT_NM, U, TRS_NM);
+}
+
+010111,3.RT,3.RS,10,2.U:R6P16LB:16::LBU16
+"lbu r<TRT_NM>, <U>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2 (U, GPR[TRS_NM]);
+  do_lbu (SD_, TRT_NM, U, TRS_NM);
+  TRACE_ALU_RESULT (GPR[TRT_NM]);
+}
+
+011111,3.RT,3.RS,0,2.U,0:R6P16LH:16::LH16
+"lh r<TRT_NM>, <U_SHIFT_1BIT>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, TRT_NM, U_SHIFT_1BIT, TRS_NM);
+}
+
+011111,3.RT,3.RS,1,2.U,0:R6P16LH:16::LHU16
+"lhu r<TRT_NM>, <U_SHIFT_1BIT>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, TRT_NM, U_SHIFT_1BIT, TRS_NM);
+}
+
+110100,3.RT,7.EU:R6P16:16::LI16
+"li r<TRT_NM>, <EU_127>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(GPR[TRT_NM]);
+  GPR[TRT_NM] = EU_127;
+  TRACE_ALU_RESULT(GPR[TRT_NM]);
+}
+
+011101,1.RT1,1.U2,3.RT2,1.RS1,1.U3,3.RS2:R6P16:16::LW4X4
+"lw r<RT_5_BIT_NM>, <U_LW4X4>(r<RS_5_BIT_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_lw (SD_, RT_5_BIT_NM, U_LW4X4, RS_5_BIT_NM);
+}
+
+000101,3.RT,3.RS,4.U:R6P16:16::LW16
+"lw r<TRT_NM>, <U_SHIFT_2BIT>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, TRT_NM, U_SHIFT_2BIT, TRS_NM);
+}
+
+010101,3.RT,7.U:R6P16:16::LWGP16
+"lw r<TRT_NM>, <U_SHIFT_2BIT>(gp)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, TRT_NM, U_SHIFT_2BIT, GPIDX);
+}
+
+001101,5.RT,5.U:R6P16:16::LWSP
+"lw r<RT>, <U_SHIFT_2BIT>(sp)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, RT, U_SHIFT_2BIT, SPIDX);
+}
+
+010100,3.RT,3.RS,3.RD,1:R6P16C:16::LWXS16
+"lwxs r<TRD_NM>, r<TRS_NM>(r<TRT_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, TRD_NM, GPR[TRS_NM] << 2, TRT_NM);
+}
+
+// These four instructions are grouped together because of a bug in GNUSIM
+// pattern recognition
+000100,5.RT,2.RS1,1.RS_CODE_1,2.RS_CODE_2:R6P16MOVE:16::P16MOVE_P16RI
+"move r<RT>, r<RS_MOVE>": RT != 0
+"syscall <RS_CODE_2>": RS1 == 1
+"sdbbp <CODE_BREAK>": RS1 == 3
+"break <CODE_BREAK>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (RT == 0) {
+    if (RS1 == 1)
+      SignalException (SystemCall, instruction_0);
+    else if (RS1 == 3)
+      SignalException (DebugBreakPoint, instruction_0);
+    else
+      do_break_nanomips (SD_, instruction_0);
+  }
+  else {
+    TRACE_ALU_INPUT2 (GPR[RT], GPR[RS_MOVE]);
+    GPR[RT] = GPR[RS_MOVE];
+    TRACE_ALU_RESULT2 (GPR[RT], GPR[RS_MOVE]);
+  }
+}
+
+101111,1.RT4,1.RD20,3.RT2_0,1.RS4,1.RD21,3.RS2_0:R6P16:16::MOVEP
+"movep r<TRD2>, r<TRE2>, r<TRS2>, r<TRT2>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  TRACE_ALU_INPUT4 (GPR[TRD2], GPR[TRE2], GPR[TRS2], GPR[TRT2]);
+  GPR[TRD2] = GPR[TRS2];
+  GPR[TRE2] = GPR[TRT2];
+  TRACE_ALU_RESULT2 (GPR[TRD2], GPR[TRE2]);
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+111111,1.RE4,1.RS20,3.RE2_0,1.RD4,1.RS21,3.RD2_0:R6P16:16::MOVEPREV
+"movep r<TRD2_REV>, r<TRE2_REV>, r<TRS2_REV>, r<TRT2_REV>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  TRACE_ALU_INPUT4 (GPR[TRD2_REV], GPR[TRE2_REV], GPR[TRS2_REV], GPR[TRT2_REV]);
+  GPR[TRD2_REV] = GPR[TRS2_REV];
+  GPR[TRE2_REV] = GPR[TRT2_REV];
+  TRACE_ALU_RESULT2 (GPR[TRD2_REV], GPR[TRE2_REV]);
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+010100,3.RT,3.RS,00,0,0:R6POOL16C00:16::NOT16
+"not r<TRT_NM>, r<TRS_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_nor (SD_, 0, TRS_NM, TRT_NM);
+}
+
+010100,3.RT,3.RS,11,0,0:R6POOL16C00:16::OR16
+"or r<TRT_NM>, r<TRS_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_or (SD_, TRS_NM, TRT_NM, TRT_NM);
+}
+
+000111,1.RT1,1,4.U,4.GPR_LIST_SAVE:R6P16SR:16::RESTORE.JRC16
+"restore.jrc <U_SHIFT_4BIT>":GPR_LIST_SAVE==15
+"restore.jrc <U_SHIFT_4BIT>, ra, %s<GPR_LIST_SAVE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (RT1 == 0)
+    do_restore_gprs_from_stack_and_adjust_sp(SD_, 30, GPR_LIST_SAVE, 0,
+                                             U_SHIFT_4BIT);
+  else
+    do_restore_gprs_from_stack_and_adjust_sp(SD_, 31, GPR_LIST_SAVE, 0,
+                                             U_SHIFT_4BIT);
+  NIA = RA;
+}
+
+000111,1.RT1,0,4.U,4.GPR_LIST_SAVE:R6P16SR:16::SAVE16
+"save <U_SHIFT_4BIT>, ra": GPR_LIST_SAVE == 0
+"save <U_SHIFT_4BIT>, ra, %s<GPR_LIST_SAVE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (RT1 == 0)
+    do_save_gprs_to_stack_and_adjust_sp(SD_, 30, GPR_LIST_SAVE, 0, U_SHIFT_4BIT);
+  else
+    do_save_gprs_to_stack_and_adjust_sp(SD_, 31, GPR_LIST_SAVE, 0, U_SHIFT_4BIT);
+
+}
+
+010111,3.RTZ,3.RS,01,2.U:R6P16LB:16::SB16
+"sb r<TRTZ>, <U>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_BYTE, GPR[TRS_NM], U, GPR[TRTZ]);
+}
+
+011111,3.RTZ,3.RS,0,2.U,1:R6P16LH:16::SH16
+"sh r<TRTZ>, <U_SHIFT_1BIT>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_HALFWORD, GPR[TRS_NM], U_SHIFT_1BIT, GPR[TRTZ]);
+}
+
+001100,3.RT,3.RS,0,3.SHIFT:R6P16SHIFT:16::SLL16
+"sll r<TRT_NM>, r<TRS_NM>, <SHIFT_DEC>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sll (SD_, TRS_NM, TRT_NM, SHIFT_DEC);
+}
+
+001100,3.RT,3.RS,1,3.SHIFT:R6P16SHIFT:16::SRL16
+"srl r<TRT_NM>, r<TRS_NM>, <SHIFT_DEC>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_srl (SD_, TRS_NM, TRT_NM, SHIFT_DEC);
+}
+
+101100,3.RT,3.RS,3.RD,1:R6P16ADDU:16::SUBU16
+"subu r<TRD_NM>, r<TRS_NM>, r<TRT_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_subu (SD_, TRS_NM, TRT_NM, TRD_NM);
+}
+
+100101,3.RTZ,3.RS,4.U:R6P16:16::SW16
+"sw r<TRTZ>, <U_SHIFT_2BIT>(r<TRS_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, GPR[TRS_NM], U_SHIFT_2BIT, GPR[TRTZ]);
+}
+
+101101,5.RT,5.U:R6P16:16::SWSP
+"sw r<RT>, <U_SHIFT_2BIT>(sp)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, SP, U_SHIFT_2BIT, GPR[RT]);
+}
+
+010100,3.RT,3.RS,01,0,0:R6POOL16C00:16::XOR16
+"xor r<TRT_NM>, r<TRS_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_xor (SD_, TRT_NM, TRS_NM, TRT_NM);
+}
+
+// 32-bit instructions
+
+001000,5.RT,5.RS,5.RD,1.X,0100010,000:R6POOL32A0:32::ADD
+"add r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_add (SD_, RS, RT, RD);
+}
+
+000000,5.RT!0,5.RS,16.U:R6PPADDIU:32::ADDIU
+"addiu r<RT>, r<RS>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, RS, RT, U);
+}
+
+010001,5.RT,011,18.U:R6PGPBH:32::ADDIUGPB
+"addiu r<RT>, GP, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, GPIDX, RT, U);
+}
+
+010000,5.RT,19.U,00:R6PGPW:32::ADDIUGPW
+"addiu r<RT>, GP, <U_SHIFT_2BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, GPIDX, RT, U_SHIFT_2BIT);
+}
+
+111000,5.RT,9.S1,10.S2,1,1.S3:R6PLUI:32::ALUIPC
+"aluipc r<RT>, <AXUIPC_S_HI>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  address_word address = NIA + AXUIPC_S;
+
+  TRACE_ALU_INPUT2(GPR[RT], address);
+  GPR[RT] = address & ~0xfff;
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0101010,000:R6POOL32A0:32::ADDU
+"addu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addu (SD_, RS, RT, RD);
+}
+
+001000,5.RT,5.RS,5.RD,5.IMMEDIATE,011,111:R6POOL32A0:32::EXTW
+"prepend r<RT>, r<RS>, <IMMEDIATE>": RD == RS
+"align r<RD>, r<RS>, r<RT>, <IMMEDIATE>": IMMEDIATE != 0
+"extw r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (IMMEDIATE != 0) {
+    uint64_t tmp = ((uint64_t)GPR[RT] << 32) | (0xffffffff & GPR[RS]);
+    TRACE_ALU_INPUT4 (GPR[RD], GPR[RS], GPR[RT], tmp);
+    GPR[RD] = EXTEND32 (tmp >> IMMEDIATE);
+    TRACE_ALU_RESULT (GPR[RD]);
+  } else {
+    TRACE_ALU_INPUT2 (GPR[RD], GPR[RT]);
+    GPR[RD] = GPR[RT];
+    TRACE_ALU_RESULT (GPR[RD]);
+  }
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1001010,000:R6POOL32A0:32::AND
+"and r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_and (SD_, RS, RT, RD);
+}
+
+100000,5.RT,5.RS,0010,12.U:R6PU12:32::ANDI
+"andi r<RT>, r<RS>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_andi (SD_, RS, RT, U);
+}
+
+001010,1,24.S1,1.S2:R6PBAL:32::BALC
+"balc <ADDRESS26>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT1(RA);
+  RA = NIA;
+  NIA = ADDRESS26;
+  TRACE_ALU_RESULT(RA);
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+001010,0,24.S1,1.S2:R6PBAL:32::BC
+"bc <ADDRESS26>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  NIA = ADDRESS26;
+}
+
+100010,5.RT,5.RS,00,13.S1,1.S2:R6PBR1:32::BEQC
+"beqc r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if (GPR[RS] == GPR[RT])
+    NIA = ADDRESS15;
+}
+
+110010,5.RT,000,7.U,10.S1,1.S2:P7PBRI:32::BEQIC
+"beqic r<RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if (GPR[RT] == U) {
+    NIA = ADDRESS12;
+  }
+}
+
+100010,5.RT,5.RS,10,13.S1,1.S2:P7PBR1:32::BGEC
+"bgec r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
+    NIA = ADDRESS15;
+}
+
+110010,5.RT,010,7.U,10.S1,1.S2:P7PBRI:32::BGEIC
+"bgeic r<RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if ((signed_word) GPR[RT] >= U) {
+    NIA = ADDRESS12;
+  }
+}
+
+100010,5.RT,5.RS,11,13.S1,1.S2:P7PBR2:32::BGEUC
+"bgeuc r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if ((unsigned_word) (GPR[RS]) >= (unsigned_word)(GPR[RT])) {
+    NIA = ADDRESS15;
+  }
+}
+
+110010,5.RT,011,7.U,10.S1,1.S2:P7PBRI:32::BGEUIC
+"bgeuic r<RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if ((unsigned_word) GPR[RT] >= U) {
+    NIA = ADDRESS12;
+  }
+}
+
+101010,5.RT,5.RS,10,13.S1,1.S2:P7PBR2:32::BLTC
+"bltc r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
+    NIA = ADDRESS15;
+}
+
+110010,5.RT,110,7.U,10.S1,1.S2:P7PBRI:32::BLTIC
+"bltic r<RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if ((signed_word) GPR[RT] < U) {
+    NIA = ADDRESS12;
+  }
+}
+
+101010,5.RT,5.RS,11,13.S1,1.S2:P7PBR2:32::BLTUC
+"bltuc r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if ((unsigned_word) GPR[RS] < (unsigned_word) GPR[RT]) {
+    NIA = ADDRESS15;
+  }
+}
+
+110010,5.RT,111,7.U,10.S1,1.S2:P7PBRI:32::BLTIUC
+"bltiuc <RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if ((unsigned_word) GPR[RT] < U) {
+    NIA = ADDRESS12;
+  }
+}
+
+101010,5.RT,5.RS,00,13.S1,1.S2:R6PBR2:32::BNEC
+"bnec r<RS>, r<RT>, <ADDRESS15>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  if (GPR[RS] != GPR[RT])
+    NIA = ADDRESS15;
+}
+
+110010,5.RT,100,7.U,10.S1,1.S2:R6PBRI:32::BNEIC
+"bneic r<RT>, <U>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], U);
+  if (GPR[RT] != U) {
+    NIA = ADDRESS12;
+  }
+}
+
+000000,00000,10,19.CODE:R6PRI:32::BREAK
+"break %#lx<CODE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_break_nanomips (SD_, instruction_0);
+}
+
+101001,5.OP,5.RS,1.S1,0111,0,01,8.S2:R6PLSS1:32::CACHE
+"cache <OP>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_cache (SD_, OP, RS, S_9_BIT, instruction_0);
+}
+
+001000,5.RT,5.RS,0100101,100,111,111:R6POOL32AXF4:32::CLO
+"clo r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_clo (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,0101101,100,111,111:R6POOL32AXF4:32::CLZ
+"clz r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_clz (SD_, RT, RS);
+}
+
+001000,5.RT,5.X,01,00011,101,111,111:R6POOL32AXF5GROUP1:32::DI
+"di":RT == 0
+"di r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_di (SD_, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0100011,000:R6POOL32A0:32::DIV
+"div r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_div (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0110011,000:R6POOL32A0:32::DIVU
+"divu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_divu (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.X,01,01011,101,111,111:R6POOL32AXF5GROUP1:32::EI
+"ei":RT == 0
+"ei r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_ei (SD_, RT);
+}
+
+001000,9.X,0,11,11001,101,111,111:R6ERETX:32::ERET
+"eret"
+*nanomips32r6:
+*nanomips64r6:
+{
+  NIA = do_eret(SD_, 0, NIA);
+}
+
+001000,9.X,1,11,11001,101,111,111:R6ERETX:32::ERETNC
+"eretnc"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  SignalException (ReservedInstruction, instruction_0);
+  NIA = do_eret(SD_, 1, NIA);
+}
+
+100000,5.RT,5.RS,1111,0,5.MSBD,0,5.LSB:R6PEXT:32::EXT
+"ext r<RT>, r<RS>, <LSB>, <MSBD+1>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  if (LSB + MSBD + 1 > 32)
+    Unpredictable ();
+
+  do_ext (SD_, RT, RS, LSB, MSBD);
+}
+
+100000,5.RT,5.RS,1110,0,5.MSBD,0,5.LSB:R6PINS:32::INS
+"ins r<RT>, r<RS>, <INS_POS>, <INS_SIZE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  if ((1 + MSBD - LSB) < 1)
+    Unpredictable ();
+  do_ins (SD_, RT, RS, LSB, MSBD);
+}
+
+100000,5.RT,5.RS,1101,0,4.SHIFTX,1.STRIPE,0,5.SHIFT:R6PROTX:32::ROTX
+"bitrev r<RT>, r<RS>": SHIFT == 31 && SHIFTX_1BIT == 0
+"bitswap r<RT>, r<RS>": SHIFT == 7 && SHIFTX_1BIT == 8 && STRIPE == 1
+"bitswap.h r<RT>, r<RS>": SHIFT == 15 && SHIFTX_1BIT == 16
+"byteswap r<RT>, r<RS>": SHIFT == 24 && SHIFTX_1BIT == 8
+"wsbh r<RT>, r<RS>": SHIFT == 8 && SHIFTX_1BIT == 24
+"rotx r<RT>, r<RS>, <SHIFT>, <SHIFTX_1BIT>": STRIPE == 0
+"rotx r<RT>, r<RS>, <SHIFT>, <SHIFTX_1BIT>, <STRIPE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+
+  TRACE_ALU_INPUT4 (GPR[RT], GPR[RS], SHIFT, SHIFTX_1BIT);
+  do_rotx (SD_, RT, RS, SHIFT, SHIFTX_1BIT, STRIPE);
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+010010,5.RT,5.RS,0000,12.X:R6PJ:32::JALRC
+"jalrc r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  unsigned_word address;
+  TRACE_ALU_INPUT3(GPR[RT], GPR[RS], RA);
+  GPR[RT] = NIA;
+  address = GPR[RS];
+  NIA = address;
+
+  // For cycle counting
+  COP0_COUNT++;
+  TRACE_ALU_RESULT(NIA);
+
+}
+
+010010,5.RT,5.RS,0001,12.X:R6PJ:32::JALRC.HB
+"jalrc.hb r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  unsigned_word address;
+  GPR[RT] = NIA;
+  address = GPR[RS];
+  NIA = address;
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+100001,5.RT,5.RS,0000,12.U:R6PLSU12:32::LB
+"lb r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lb (SD_, RT, U, RS);
+}
+
+010001,5.RT,000,18.U:R6PLSGP:32::LBGP
+"lb r<RT>, <U>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lb (SD_, RT, U, GPIDX);
+}
+
+101001,5.RT,5.RS,1.S1,0000,0,00,8.S2:R6PLSS0:32::LBS9
+"lb r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lb (SD_, RT, S_9_BIT, RS);
+}
+
+100001,5.RT,5.RS,0010,12.U:R6PLSU12:32::LBU
+"lbu r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lbu (SD_, RT, U, RS);
+}
+
+010001,5.RT,010,18.U:R6GPBH:32::LBUGP
+"lbu r<RT>, <U>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2 (U, GP);
+  do_lbu (SD_, RT, U, GPIDX);
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,0010,0,00,8.S2:R6PLSS0:32::LBUS9
+"lbu r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lbu (SD_, RT, S_9_BIT, RS);
+}
+
+001000,5.RT,5.RS,5.RD,0010,0,000,111:R6PPLSX:32::LBUX
+"lbux r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lbu (SD_, RD, GPR[RS], RT);
+}
+
+001000,5.RT,5.RS,5.RD,0000,0,000,111:R6PPLSX:32::LBX
+"lbx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lb (SD_, RD, GPR[RS], RT);
+}
+
+100001,5.RT,5.RS,0100,12.U:R6PLSU12:32::LH
+"lh r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, RT, U, RS);
+}
+
+010001,5.RT,100,17.U,0:R6PGPLH:32::LHGP
+"lh r<RT>, <U_SHIFT_1BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, RT, U_SHIFT_1BIT, GPIDX);
+}
+
+101001,5.RT,5.RS,1.S1,0100,0,00,8.S2:R6PLSS0:32::LHS9
+"lh r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, RT, S_9_BIT, RS);
+}
+
+100001,5.RT,5.RS,0110,12.U:R6PLSU12:32::LHU
+"lhu r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, RT, U, RS);
+}
+
+010001,5.RT,100,17.U,1:R6PLSGP:32::LHUGP
+"lhu r<RT>, <U_SHIFT_1BIT>(gp)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, RT, U_SHIFT_1BIT, GPIDX);
+}
+
+101001,5.RT,5.RS,1.S1,0110,0,00,8.S2:R6PLSS0:32::LHUS9
+"lhu r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, RT, S_9_BIT, RS);
+}
+
+001000,5.RT,5.RS,5.RD,0110,0,000,111:R6PPLSX:32::LHUX
+"lhux r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, RD, GPR[RS], RT);
+}
+
+001000,5.RT,5.RS,5.RD,0110,1,000,111:R6PPLSXS:32::LHUXS
+"lhux r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lhu (SD_, RD, GPR[RS] << 1, RT);
+}
+
+001000,5.RT,5.RS,5.RD,0100,0,000,111:R6PPLSX:32::LHX
+"lhx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, RD, GPR[RS], RT);
+}
+
+001000,5.RT,5.RS,5.RD,0100,1,000,111:R6PPLSXS:32::LHXS
+"lhxs r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lh (SD_, RD, GPR[RS] << 1, RT);
+}
+
+101001,5.RT,5.RS,1.S1,1010,0,01,6.S2,00:R6PLL:32::LL
+"ll r<RT>, <S_9_BIT_LLSC>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(GPR[RT], S_9_BIT_LLSC, GPR[RS]);
+  do_ll (SD_, RT, S_9_BIT_LLSC, RS);
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.X1,1010,0,01,5.RU,1.X2,01:R6PLL:32::LLWP
+"llwp r<RT>, r<RU>, (r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_llwp (SD_, RT, RU, 0, RS);
+}
+
+001000,5.RT,5.RS,5.RD,2.U,3.X,001,111:R6POOL32A7:32::LSA
+"lsa r<RD>, r<RS>, r<RT>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lsa (SD_, RD, RS, RT, U);
+}
+
+111000,5.RT,9.S1,10.S2,0,1.S3:R6PLUI:32::LUI
+"lui r<RT>, <AXUIPC_S_HI>, <AXUIPC_S_LO>":AXUIPC_S_LO != 0
+"lui r<RT>, <AXUIPC_S_HI>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2 (GPR[RT], AXUIPC_S);
+  GPR[RT] = AXUIPC_S;
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+100001,5.RT,5.RS,1000,12.U:R6PLSU12:32::LW
+"lw r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3 (GPR[RT], U, GPR[RS]);
+  do_lw (SD_, RT, U, RS);
+  TRACE_ALU_RESULT (GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,1000000,8.S2:R6PLSS0:32::LWS9
+"lw r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, RT, S_9_BIT, RS);
+}
+
+101001,5.RT,5.RS,1.S1,3.COUNT3,0,1,00,8.S2:R6PLSWM:32::LWM
+"lwm r<RT>, <S_9_BIT>(r<RS>), <COUNT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int counter = 0;
+  int dest;
+  int this_offset;
+
+  check_nms_flag (SD_);
+
+  while (counter != COUNT)
+  {
+    dest = (RT & 0x10) | ((RT + counter) & 0x1F);
+
+    if ((dest == RS) && (counter != (COUNT - 1)))
+      Unpredictable ();
+
+    this_offset = S_9_BIT + (counter << 2);
+
+    do_lw (SD_, dest, this_offset, RS);
+
+    counter++;
+    if (counter != 0)
+      COP0_COUNT++;
+  }
+}
+
+010000,5.RT,19.U,10:R6PGPW:32::LWGP
+"lw r<RT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], GPR[RT]);
+  do_lw (SD_, RT, U_SHIFT_2BIT, GPIDX);
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+011000,5.RT,01011,16.IMM48:R6POOL48I:32::LWPC48
+"lwpc r<RT>, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t S2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = S2 << 16 | IMM48;
+
+  do_lwpc_nanomips (SD_, RT, total, CIA + 6);
+  NIA = CIA + 6;
+}
+
+001000,5.RT,5.RS,5.RD,1000,0,000,111:R6PPLSX:32::LWX
+"lwx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, RD, GPR[RS], RT);
+}
+
+001000,5.RT,5.RS,5.RD,1000,1,000,111:R6PPLSXS:32::LWXS
+"lwxs r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lw (SD_, RD, GPR[RS] << 2, RT);
+}
+
+001000,5.RT,5.C0S,5.SEL,1.X,0000110,000:R6POOL32A0:32::MFC0
+"mfc0 r<RT>, r<C0S>, <SEL>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  DecodeCoproc (instruction_0, 0, cp0_mfc0, RT, C0S, SEL);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0101011,000:R6POOL32A0:32::MOD
+"mod r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_mod (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0111011,000:R6POOL32A0:32::MODU
+"modu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_modu (SD_, RD, RS, RT);
+}
+
+000010,1.RT1,1.RD,3.RT2,20.S1,1.S2:R6MOVEBALC:32::MOVE.BALC
+"move.balc r<RD1>, r<RT_5_BIT_NM_Z>, <ADDRESS22>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  TRACE_ALU_INPUT2(GPR[RD1], GPR[RT_5_BIT_NM_Z]);
+  GPR[RD1] = GPR[RT_5_BIT_NM_Z];
+  RA = NIA;
+  NIA = ADDRESS22;
+  TRACE_ALU_RESULT(GPR[RD1]);
+
+  // For cycle counting
+  COP0_COUNT += 2;
+}
+
+001000,5.RT,5.RS,5.RD,1,1000010,000:R6PCMOVE:32::MOVN
+"movn r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RS], GPR[RT]);
+  do_movn (SD_, RD, RS, RT);
+  TRACE_ALU_RESULT(GPR[RD]);
+}
+
+001000,5.RT,5.RS,5.RD,0,1000010,000:R6PCMOVE:32::MOVZ
+"movz r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_movz (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.C0S,5.SEL,1.X,0001110,000:R6POOL32A0:32::MTC0
+"mtc0 r<RT>, r<C0S>, <SEL>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  DecodeCoproc (instruction_0, 0, cp0_mtc0, RT, C0S, SEL);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0001011,000:R6POOL32A0:32::MUH
+"muh r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_muh (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0011011,000:R6POOL32A0:32::MUHU
+"muhu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_muhu (SD_, RD, RS, RT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0000011,000:R6POOL32A0:32::MUL32
+"mul r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_mul (SD_, RD, RS, RT);
+}
+
+001111,1.RT1,0,3.RT2,1.RS1,1,3.RS2:R6P164X4:16::MUL4X4
+"mul r<RT_5_BIT_NM>, r<RS_5_BIT_NM>, r<RT_5_BIT_NM>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_mul (SD_, RT_5_BIT_NM, RS_5_BIT_NM, RT_5_BIT_NM);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0010011,000:R6POOL32A0:32::MULU
+"mulu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_mulu (SD_, RD, RS, RT);
+}
+
+100000,00000,5.X1,1100,3.X2,0000,00000:R6PSLL:32::NOP32
+"nop"
+*nanomips32r6:
+*nanomips64r6:
+{
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1011010,000:R6POOL32A0:32::NOR
+"nor r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_nor (SD_, RS, RT, RD);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1010010,000:R6POOL32A0:32::OR32
+"or r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_or (SD_, RS, RT, RD);
+}
+
+100000,5.RT,5.RS,0000,12.U:R6PU12:32::ORI
+"ori r<RT>, r<RS>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_ori (SD_, RS, RT, U);
+}
+
+100000,00000,5.X1,1100,3.X2,0000,00101:R6PSLL:32::PAUSE
+"pause"
+*nanomips32r6:
+*nanomips64r6:
+{
+  sim_io_printf (SD, "Not implemented");
+}
+
+101001,5.HINT!31,5.RS,1.S1,0011,0,00,8.S2:R6PPREFS9:32::PREFS9
+"pref <HINT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_pref (SD_, HINT, S_9_BIT, RS);
+}
+
+100001,5.HINT,5.RS,0011,12.U:R6PLSU12:32::PREFU12
+"pref <HINT>, <U>(r<RS>)": HINT != 31
+"synci <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (HINT != 31)
+   do_pref (SD_, HINT, U, RS);
+  else
+  {
+    // synci - nothing to do currently
+    sim_io_printf (SD, "Not implemented");
+  }
+}
+
+100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,10:R6PPSR:32::RESTORE
+"restore <U_SHIFT_3BIT>, r<RT>": GPR_LIST_SAVE == 0
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GPR_LIST_SAVE>": !GP_SAVE && GPR_LIST_SAVE != 0
+"restore <U_SHIFT_3BIT>, r<RT>": !GP_SAVE && GPR_LIST_SAVE < 2
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GPR_LIST_SAVE>" : !GP_SAVE && GPR_LIST_SAVE >=2
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 2
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>" : GP_SAVE && GPR_LIST_SAVE >=2
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 3
+"restore <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_restore_gprs_from_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE,
+                                           GP_SAVE, U_SHIFT_3BIT);
+}
+
+100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,11:R6PPSR:32::RESTORE.JRC
+"restore.jrc <U_SHIFT_3BIT>, r<RT>": GPR_LIST_SAVE == 0
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GPR_LIST_SAVE>": !GP_SAVE && GPR_LIST_SAVE != 0
+"restore.jrc <U_SHIFT_3BIT>, r<RT>": !GP_SAVE && GPR_LIST_SAVE < 2
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GPR_LIST_SAVE>" : !GP_SAVE && GPR_LIST_SAVE >=2
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 2
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>" : GP_SAVE && GPR_LIST_SAVE >=2
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 3
+"restore.jrc <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_restore_gprs_from_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE,
+                                           GP_SAVE, U_SHIFT_3BIT);
+
+  NIA = GPR[RAIDX];
+}
+
+100000,5.RT,5.RS,1100,3.X,0110,5.SHIFT:R6PSHIFT:32::ROTR
+"rotr r<RT>, r<RS>, <SHIFT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[RT] = do_ror (SD_, GPR[RS], SHIFT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0011010,000:R6POOL32A0:32::ROTRV
+"rotrv r<RD>, r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint32_t shift = GPR[RT] & 0x1f;
+  GPR[RD] = do_ror (SD_, GPR[RS], shift);
+}
+
+001000,5.RT,5.RS,5.RD,0,1100010,000:R6POOL32A0:32::XOR
+"xor r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_xor (SD_, RS, RT, RD);
+}
+
+100000,5.RT,5.RS,0001,12.U:R6PU12:32::XORI
+"xori r<RT>, r<RS>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_xori (SD_, RS, RT, U);
+}
+
+100000,5.RT,0,4.GPR_LIST_SAVE,0011,9.U,1.GP_SAVE,00:R6PPSR:32::SAVE
+"save <U_SHIFT_3BIT>, r<RT>": GPR_LIST_SAVE == 0
+"save <U_SHIFT_3BIT>, r<RT>, %s<GPR_LIST_SAVE>":  !GP_SAVE && GPR_LIST_SAVE != 0
+"save <U_SHIFT_3BIT>, r<RT>": !GP_SAVE && GPR_LIST_SAVE < 2
+"save <U_SHIFT_3BIT>, r<RT> %s<GPR_LIST_SAVE>" : !GP_SAVE && GPR_LIST_SAVE >=2
+"save <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 2
+"save <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>" : GP_SAVE && GPR_LIST_SAVE >=2
+"save <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>": GP_SAVE && GPR_LIST_SAVE < 3
+"save <U_SHIFT_3BIT>, r<RT>, %s<GP_SAVE>, %s<GPR_LIST_SAVE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_save_gprs_to_stack_and_adjust_sp(SD_, RT, GPR_LIST_SAVE,
+                                      GP_SAVE, U_SHIFT_3BIT);
+}
+
+100001,5.RT,5.RS,0001,12.U:R6PLSU12:32::SBU12
+"sb r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_BYTE, GPR[RS], U, GPR[RT]);
+}
+
+010001,5.RT,001,18.U:R6PGPBH:32::SBGP
+"sb r<RT>, <U>(gp)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_BYTE, GP, U, GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,0001,0,00,8.S2:R6PLSS0:32::SBS9
+"sb r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_BYTE, GPR[RS], S_9_BIT, GPR[RT]);
+}
+
+001000,5.RT,5.RS,5.RD,0001,0,000,111:R6PPLSX:32::SBX
+"sbx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_BYTE, GPR[RT], GPR[RS], GPR[RD]);
+}
+
+101001,5.RT,5.RS,1.S1,1011,0,01,6.S2,00:R6PSC:32::SC
+"sc r<RT>, <S_9_BIT_LLSC>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sc (SD_, RT, S_9_BIT_LLSC, RS, instruction_0, 1);
+}
+
+101001,5.RT,5.RS,1.X1,1011,0,01,5.RU,1.X,01:R6PSC:32::SCWP
+"scwp r<RT>, r<RU>, (r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int offset = BigEndianCPU ? 0 : 4;
+
+  do_sc (SD_, RU, offset, RS, instruction_0, 0);
+  do_sc (SD_, RT, offset ^ 4, RS, instruction_0, 1);
+}
+
+001000,5.RT,5.RS,6.X,0000001,000:R6POOL32A0:32::SEB
+"seb r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_seb (SD_, RT, RS);
+}
+
+001000,5.RT,5.RS,6.X,0001001,000:R6POOL32A0:32::SEH
+"seh r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_seh (SD_, RT, RS);
+}
+
+100000,5.RT,5.RS,0110,12.IMMEDIATE:R6PU12:32::SEQI
+"seqi r<RT>, r<RS>, <IMMEDIATE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(GPR[RT], GPR[RS], IMMEDIATE);
+  GPR[RT] = (GPR[RS] == IMMEDIATE) ? 1 : 0;
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+100001,5.RT,5.RS,0101,12.U:R6PLSU12:32::SHU12
+"sh r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_HALFWORD, GPR[RS], U, GPR[RT]);
+}
+
+010001,5.RT,101,17.U,0:R6PGPSH:32::SHGP
+"sh r<RT>, <U_SHIFT_1BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_HALFWORD, GP, U_SHIFT_1BIT, GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,0101,0,00,8.S2:R6PLSS0:32::SHS9
+"sh r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_HALFWORD, GPR[RS], S_9_BIT, GPR[RT]);
+}
+
+001000,5.RT,5.RS,5.RD,0101,0,000,111:R6PPLSX:32::SHX
+"shx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_HALFWORD, GPR[RT], GPR[RS], GPR[RD]);
+}
+
+001000,5.RT,5.RS,5.RD,0101,1,000,111:R6PPLSXS:32::SHXS
+"shxs r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_HALFWORD, GPR[RT], GPR[RS] << 1, GPR[RD]);
+}
+
+000000,00000,00,19.CODE:R6PRI:32::SIGRIE
+"sigrie %#lx<CODE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  SignalException (ReservedInstruction, instruction_0);
+}
+
+100000,5.RT!0,5.RS,1100,3.X,0000,5.SHIFT:R6PSLL:32::SLL32
+"sll r<RT>, r<RS>, <SHIFT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sll (SD_, RS, RT, SHIFT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0000010,000:R6POOL32A0:32::SLLV
+"sllv r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sllv (SD_, RT, RS, RD);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1101010,000:R6POOL32A0:32::SLT
+"slt r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_slt (SD_, RS, RT, RD);
+}
+
+100000,5.RT,5.RS,0100,12.IMMEDIATE:R6PU12:32::SLTI
+"slti r<RT>, r<RS>, <IMMEDIATE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_slti (SD_, RS, RT, EXTEND12(IMMEDIATE));
+}
+
+100000,5.RT,5.RS,0101,12.U:R6PU12:32::SLTIU
+"sltiu r<RT>, r<RS>, <U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sltiu (SD_, RS, RT, EXTEND12(U));
+}
+
+001000,5.RT,5.RS,5.RD!0,1.X,1110010,000:R6PSLTU:32::SLTU
+"sltu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sltu (SD_, RS, RT, RD);
+}
+
+100000,5.RT,5.RS,1100,3.X,0100,5.SHIFT:R6PSHIFT:32::SRA
+"sra r<RT>, r<RS>, <SHIFT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_sra (SD_, RS, RT, SHIFT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0010010,000:R6POOL32A0:32::SRAV
+"srav r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_srav (SD_, RT, RS, RD);
+}
+
+100000,5.RT,5.RS,1100,3.X,0010,5.SHIFT:R6PSHIFT:32::SRL32
+"srl r<RT>, r<RS>, <SHIFT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_srl (SD_, RS, RT, SHIFT);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0001010,000:R6POOL32A0:32::SRLV
+"srlv r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_srlv (SD_, RT, RS, RD);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0110010,000:R6POOL32A0:32::SUB
+"sub r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_sub (SD_, RS, RT, RD);
+}
+
+001000,5.RT,5.RS,5.RD,1.X,0111010,000:R6POOL32A0:32::SUBU32
+"subu r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_subu (SD_, RS, RT, RD);
+}
+
+100001,5.RT,5.RS,1001,12.U:R6PLSU12:32::SWU12
+"sw r<RT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, GPR[RS], U, GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,1001,0,00,8.S2:R6PLS0:32::SWS9
+"sw r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, GPR[RS], S_9_BIT, GPR[RT]);
+}
+
+010000,5.RT,19.U,11:R6PGPW:32::SWGP
+"sw r<RT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, GP, U_SHIFT_2BIT, GPR[RT]);
+}
+
+011000,5.RT,01111,16.IMM48:R6POOL48I:32::SWPC48
+"swpc r<RT>, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t U2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = U2 << 16 | IMM48;
+  TRACE_ALU_INPUT2(GPR[RT], total);
+  do_store(SD_, AccessLength_WORD, CIA + 6, total, GPR[RT]);
+  TRACE_ALU_RESULT(GPR[RT]);
+  NIA = CIA + 6;
+}
+
+
+110101,3.RTZ,7.U:R6P16:16::SWGP16
+"sw r<TRTZ>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_store (SD_, AccessLength_WORD, GP, U_SHIFT_2BIT, GPR[TRTZ]);
+}
+
+001000,5.RT,5.RS,5.RD,1001,0,000,111:R6PPLSX:32::SWX
+"swx r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_WORD, GPR[RT], GPR[RS], GPR[RD]);
+}
+
+001000,5.RT,5.RS,5.RD,1001,1,000,111:R6PPLSXS:32::SWXS
+"swxs r<RD>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_WORD, GPR[RT], GPR[RS] << 2, GPR[RD]);
+}
+
+111101,1.RT1,1.U2,3.RT2,1.RS1,1.U3,3.RS2:R6P16:16::SW4X4
+"sw r<RT_5_BIT_NM_Z>, <U_LW4X4>(r<RS_5_BIT_NM>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_store (SD_, AccessLength_WORD, GPR[RS_5_BIT_NM], U_LW4X4, GPR[RT_5_BIT_NM_Z]);
+}
+
+101001,5.RT,5.RS,1.S1,3.COUNT3,1,1,00,8.S2:R6PLSWM:32::SWM
+"swm r<RT>, <S_9_BIT>(r<RS>), <COUNT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int counter = 0;
+  int source;
+  int offsetm;
+
+  check_nms_flag (SD_);
+
+  while (counter != COUNT)
+  {
+    if (RT == 0)
+      source = 0;
+    else
+      source = (RT & 0x10) | ((RT + counter) & 0x1F);
+
+    offsetm = S_9_BIT + (counter << 2);
+
+    do_sw (SD_, source, offsetm, RS);
+
+    counter++;
+
+    if (counter != 0)
+      COP0_COUNT++;
+  }
+}
+
+100000,00000,5.STYPE,1100,3.X,0000,00110:R6PHB:32::SYNC
+"sync":STYPE==0
+"sync <STYPE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  SyncOperation (STYPE);
+}
+
+101001,11111,5.RS,1.S1,0011,0,00,8.S2:R6PPREFS:32::SYNCI
+"synci <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // sync i-cache - nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+000000,00000,11,19.CODE:R6PRI:32::SDBBP32
+"sdbbp %#lx<CODE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  SignalException (DebugBreakPoint, instruction_0);
+}
+
+001000,10.X,00,00001,101,111,111:R6POOL32AXF5GROUP0:32::TLBP
+"tlbp"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,10.X,00,10001,101,111,111:R6POOL32AXF5GROUP0:32::TLBWI
+"tlbwi"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,10.X,00,11001,101,111,111:R6POOL32AXF5GROUP0:32::TLBWR
+"tlbwr"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+
+001000,0000000000,01,00001,101,111,111:R6POOL32AXF5GROUP1:32::TLBINV
+"tlbinv"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // invalidate a set of TLB entries based on ASID and Index match - nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,0000000000,01,01001,101,111,111:R6POOL32AXF5GROUP1:32::TLBINVF
+"tlbinvf"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // invalidate a set of TLB entries based on Index match - nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,10.CODE,10,00101,101,111,111:R6PSYSCALL:32::SYSCALL
+"syscall %#lx<CODE>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  SignalException (SystemCall, instruction_0);
+}
+
+100000,00000,5.X1,1100,3.X2,0000,00011:R6PHB:32::EHB
+"ehb"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // Do nothing, there are no hazards to clear
+}
+
+001000,5.RT,5.RS,5.X,0,0000000,000:R6PTRAP:32::TEQ
+"teq r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+
+  if (GPR[RS] == GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+001000,5.RT,5.RS,5.X,1,0000000,000:R6PTRAP:32::TNE
+"tne r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+
+  if (GPR[RS] != GPR[RT])
+    SignalException(Trap, instruction_0);
+}
+
+101001,5.RT,5.RS,1.S1,0100,0,01,8.S2:R6PLSS1:32::UALH
+"ualh r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+
+  TRACE_ALU_INPUT3(GPR[RT], S_9_BIT, GPR[RS]);
+  do_lh (SD_, RT, S_9_BIT, RS);
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,3.COUNT3,0,1,01,8.S2:R6PLSUAWM:32::UALWM
+"ualwm r<RT>, <S_9_BIT>(r<RS>), <COUNT>":COUNT != 1
+"ualw r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int i;
+  int dest;
+  int this_offset;
+
+  address_word base = GPR[RS];
+  for(i = 0; i< COUNT; i++)
+  {
+    dest = (RT & 0x10) | ((RT + i) & 0x1F);
+
+    if (dest == RS && i != COUNT - 1)
+      Unpredictable ();
+
+    this_offset = S_9_BIT + (i << 2);
+
+    if(BigEndianCPU) {
+      GPR[dest] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, base,
+         EXTEND16 (this_offset), GPR[dest]));
+      GPR[dest] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, base,
+         EXTEND16 (this_offset + AccessLength_WORD), GPR[dest]));
+    } else {
+      GPR[dest] = EXTEND32 (do_load_right (SD_, AccessLength_WORD, base,
+         EXTEND16 (this_offset), GPR[dest]));
+      GPR[dest] = EXTEND32 (do_load_left (SD_, AccessLength_WORD, base,
+         EXTEND16 (this_offset + AccessLength_WORD), GPR[dest]));
+    }
+
+    if (i != 0)
+      COP0_COUNT++;
+  }
+}
+
+101001,5.RT,5.RS,1.S1,0101,0,01,8.S2:R6PLSS1:32::UASH
+"uash r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+
+  do_store (SD_, AccessLength_HALFWORD, GPR[RS], S_9_BIT, GPR[RT]);
+}
+
+101001,5.RT,5.RS,1.S1,3.COUNT3,1,1,01,8.S2:R6PLSUAWM:32::UASWM
+"uaswm r<RT>, <S_9_BIT>(r<RS>), <COUNT>":COUNT != 1
+"uasw r<RT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+
+  int i;
+  int source;
+  int offsetm;
+
+  for(i = 0; i< COUNT; i++)
+   {
+    if (RT == 0)
+      source = 0;
+    else
+      source = (RT & 0x10) | ((RT + i) & 0x1F);
+
+    offsetm = S_9_BIT + (i << 2);
+
+    if(BigEndianCPU) {
+      do_store_left (SD_, AccessLength_WORD, GPR[RS], EXTEND16 (offsetm), GPR[source]);
+      do_store_right (SD_, AccessLength_WORD, GPR[RS],
+                          EXTEND16 (offsetm + AccessLength_WORD), GPR[source]);
+    } else {
+      do_store_right (SD_, AccessLength_WORD, GPR[RS], EXTEND16 (offsetm), GPR[source]);
+      do_store_left (SD_, AccessLength_WORD, GPR[RS],
+                          EXTEND16 (offsetm + AccessLength_WORD), GPR[source]);
+    }
+
+    if (i != 0)
+      COP0_COUNT++;
+  }
+}
+
+001000,5.RT,5.X,00000,0,1110010,000:R6PDVP:32::DVP
+"dvp r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+
+001000,5.RT,5.HS,2.X1,3.SEL,1.X2,0111000,000:R6POOL32A0:32::RDHWR
+"rdhwr r<HS>, r<RT>, <SEL>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_nms_flag (SD_);
+  do_rdhwr (SD_, RT, HS);
+}
+
+001000,5.RT,5.RS,11,10000,101,111,111:R6POOL32AXF5GROUP3:32::RDPGPR
+"rdpgpr r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,5.RT,5.RS,11,11000,101,111,111:R6POOL32AXF5GROUP3:32::WRPGPR
+"wrpgpr r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // TODO: implement as given in the specification
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,5.RT,5.RS,5.RD,1.X,1111010,000:R6POOL32A0:32::SOV
+"SOV r<RD>, r<RS>, r<RT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
+  {
+    ALU32_BEGIN (GPR[RS]);
+    ALU32_ADD (GPR[RT]);
+    if (ALU32_HAD_OVERFLOW)
+      GPR[RD] = 1;
+    else
+      GPR[RD] = 0;
+  }
+  TRACE_ALU_RESULT (GPR[RD]);
+}
+
+001000,10.X,11,10001,101,111,111:R6POOL32A0:32::DERET
+"deret"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,5.RT,5.X,00000,1,1110010,000:R6PDVP:32::EVP
+"evp r<RT>" : RT!=0
+"evp"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+001000,10.CODE,110000110,1111111:R6POOL32AXF5GROUP2:32::WAIT
+"wait"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+011000,5.RT,00000,16.IMM48:R6POOL48I:32::LI48
+"li r<RT>, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t U2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  U2 = do_load (SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = U2 << 16 | IMM48;
+  TRACE_ALU_INPUT2(GPR[RT], total);
+  GPR[RT] = EXTEND32(total);
+  TRACE_ALU_RESULT(GPR[RT]);
+  NIA = CIA + 6;
+}
+
+011000,5.RT,00001,16.IMM48:R6POOL48I:32::ADDIU48
+"addiu r<RT>, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t S2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = S2 << 16 | IMM48;
+  do_addiu(SD_, RT, RT, total);
+  NIA = CIA + 6;
+}
+
+100000,5.RT,5.RS,1000,12.U:R6PU12:32::ADDIUNEG
+"addiu r<RT>, r<RS>, -<U>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_addiu (SD_, RS, RT, -U);
+}
+
+011000,5.RT,00010,16.IMM48:R6POOL48I:32::ADDIUGP48
+"addiu r<RT>, GP, <IMM48>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  uint16_t S2;
+  uint32_t total;
+  check_nms_flag (SD_);
+  S2 = do_load(SD_, AccessLength_HALFWORD, CIA + 4, 0);
+  total = S2 << 16 | IMM48;
+  do_addiu (SD_, GPIDX, RT, total);
+  NIA = CIA + 6;
+}
+
+010010,00000,5.RS,1000,12.X:R6BALRSC:32::BRSC
+"brsc r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  unsigned_word address = NIA + (GPR[RS] << 1);
+  NIA = address;
+}
+
+010010,5.RT!0,5.RS,1000,12.X:R6PBALRSC:32::BALRSC
+"balrsc r<RT>, r<RS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  unsigned_word address = NIA + (GPR[RS] << 1);
+
+  GPR[RT] = NIA;
+  NIA = address;
+
+  // For cycle counting
+  COP0_COUNT++;
+}
+
+110010,5.RT,001,1.X,6.BIT,10.S1,1.S2:R6PBRI:32::BBEQZC
+"bbeqzc r<RT>, <BIT>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int testbit = (GPR[RT] >> BIT) & 1;
+
+  check_nms_flag (SD_);
+
+  if (testbit == 0)
+      NIA = ADDRESS12;
+}
+
+110010,5.RT,101,1.X,6.BIT,10.S1,1.S2:R6PBRI:32::BBNEZC
+"bbnezc r<RT>, <BIT>, <ADDRESS12>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  int testbit = (GPR[RT] >> BIT) & 1;
+
+  check_nms_flag (SD_);
+
+  if (testbit == 1)
+      NIA = ADDRESS12;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Not yet in the specification.
+//////////////////////////////////////////////////////////////////////
+
+100001,5.FT,5.RS,1111,12.U:R6PLSU12:32::SDC1
+"sdc1 f<FT>, <U>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT3(FGR[FT], U, GPR[RS]);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], EXTEND16 (U), COP_SD (1, FT));
+}
+
+100001,5.FT,5.RS,1110,12.OFFSET:R6PLSU12:32::LDC1
+"ldc1 f<FT>, <OFFSET>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT3(FGR[FT], OFFSET, GPR[RS]);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], EXTEND16 (OFFSET)));
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+100001,5.FT,5.BASE,1010,12.OFFSET:R6PLSU12:32::LWC1
+"lwc1 f<FT>, <OFFSET>(r<BASE>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lwc1 (SD_, FT, OFFSET, BASE);
+}
+
+100001,5.FT,5.BASE,1011,12.OFFSET:R6PLSU12:32::SWC1
+"swc1 f<FT>, <OFFSET>(fp)": BASE == 30
+"swc1 f<FT>, <OFFSET>(r<BASE>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  if(BASE == 30)
+    do_swc1 (SD_, FT, OFFSET, 30, instruction_0);
+  else
+    do_swc1 (SD_, FT, OFFSET, BASE, instruction_0);
+}
+
+001000,10.X,00,01001,101,111,111:R6POOL32AXF5GROUP0:32::TLBR
+"tlbr"
+*nanomips32r6:
+*nanomips64r6:
+{
+  // nothing to do currently
+  sim_io_printf (SD, "Not implemented");
+}
+
+101000,5.RT,5.FS,2.X,101000,00,111,011:R6POOL32FXF0:32,f::MTC1
+"mtc1 r<RT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], FGR[FS]);
+  do_mtc1b (SD_, RT, FS);
+  TRACE_ALU_RESULT(FGR[FS]);
+}
+
+101000,5.RT,5.FS,2.X,111000,00,111,011:R6POOL32FXF0:32,f::MTHC1
+"mthc1 r<RT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+TRACE_ALU_INPUT2(GPR[RT],FGR[FS]);
+  do_mthc1 (SD_, RT, FS);
+  TRACE_ALU_RESULT(FGR[FS]);
+}
+
+101000,5.FT,5.FS,5.FD,1.X,0,1.FMT_MICROMIPS,00110,000:R6POOLADDFMT1:32,f::ADD.fmt1
+"add.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FT], FGR[FS]);
+  do_add_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT,
+        instruction_0);
+  TRACE_ALU_RESULT(FGR[FD]);
+}
+
+101000,5.FT,5.FS,5.FD,5.R6COND,0,1.FMT,0101:R6POOL32F5:32,f::CMP.cond.fmt
+"cmp.%s<R6COND>.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_cmp (SD_, FD, FS, FT, FMT, R6COND);
+}
+
+101000,5.FT,5.FS,1.X,0,1.FMT_MICROMIPS,00000,01,111,011:R6POOLMOVFMT:32,f::MOV.fmt
+"mov.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FT], FGR[FS]);
+  do_mov_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+        instruction_0);
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+010001,5.FT,110,16.U,00:R6PLSGPCP1:32::LWC1GP
+"lwc1 f<FT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_lwc1 (SD_, FT, U_SHIFT_2BIT, GPIDX);
+}
+
+010001,5.FT,110,16.U,01:R6PLSGPCP1:32::SWC1GP
+"swc1 f<FT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_swc1 (SD_, FT, U_SHIFT_2BIT, GPIDX, instruction_0);
+}
+
+101001,5.FT,5.RS,1.S1,1011000,8.S2:R6PLSGPCP1:32::SWC1S9
+"swc1 f<FT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_swc1 (SD_, FT, S_9_BIT, RS, instruction_0);
+}
+
+010001,5.FT,110,16.U,10:R6PLSGPCP1:32::LDC1GP
+"ldc1 f<FT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], U_SHIFT_2BIT, GP);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GP, U_SHIFT_2BIT));
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+100010,5.FT,00001,01,13.S2,1.S1:R6POOLPBR3A:32,f::BC1NEZC
+"bc1nezc f<FT>, <S_14_BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT2(NIA, S_14_BIT);
+  if ((FGR[FT] & 0x01) != 0)
+      NIA = NIA + (S_14_BIT << 1);
+  TRACE_ALU_RESULT(NIA);
+}
+
+100010,5.FT,00000,01,13.S2,1.S1:R6POOLPBR3A:32,f::BC1EQZC
+"bc1eqzc f<FT>, <S_14_BIT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT2(NIA, S_14_BIT);
+  if ((FGR[FT] & 0x01) == 0)
+      NIA = NIA + (S_14_BIT << 1);
+  TRACE_ALU_RESULT(NIA);
+}
+
+101000,5.RT,5.FS,2.X,100000,00,111,011:R6POOL32FXF0:32,f::MFC1
+"mfc1 r<RT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], FGR[FS]);
+  do_mfc1b (SD_, RT, FS);
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+101000,5.RT,5.FS,2.X,110000,00,111,011:R6POOL32FXF0:32,f::MFHC1
+"mfhc1 r<RT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(GPR[RT], FGR[FS]);
+  do_mfhc1 (SD_, RT, FS);
+  TRACE_ALU_RESULT(GPR[RT]);
+}
+
+101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS_CVT_D!3,10011,01,111,011:R6CVTDFMT:32,f::CVT.D.fmt
+"cvt.d.%s<FMT_MICROMIPS_CVT_D> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_cvt_d_fmt (SD_, convert_fmt_micromips_cvt_d (SD_, FMT_MICROMIPS_CVT_D),
+    FT, FS, instruction_0);
+}
+
+:%s::::FMT_MICROMIPS_MUL:int fmt
+{
+  switch (fmt)
+    {
+    case 1: return "s";
+    case 3: return "d";
+    default: return "?";
+    }
+}
+
+101000,5.FT,5.FS,5.FD,1.X,0,2.FMT_MICROMIPS_MUL!2!0,0110,000:R6MULFMT1:32,f::MUL.fmt
+"mul.%s<FMT_MICROMIPS_MUL> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FS], FGR[FT]);
+  do_mul_fmt (SD_, convert_fmt_micromips_mul (SD_, FMT_MICROMIPS_MUL), FD, FS, FT,
+        instruction_0);
+  TRACE_ALU_RESULT(FGR[FD]);
+}
+
+
+101000,5.FT,5.FS,5.FD,1.X,0,2.FMT_MICROMIPS_MUL!2!0,1110,000:R6DIVFMT1:32,f::DIV.fmt
+"div.%s<FMT_MICROMIPS_MUL> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FS], FGR[FT]);
+  if (FMT_MICROMIPS_MUL == 1)
+    do_div_fmt (SD_, 0, FD, FS, FT, instruction_0);
+  else
+    do_div_fmt (SD_, 1, FD, FS, FT, instruction_0);
+  TRACE_ALU_RESULT(FGR[FD]);
+}
+
+101000,5.FT,5.FS,1.X,1.FMT_MICROMIPS,101011,00,111,011:R6POOL32FXF0:32,f::TRUNC.W.fmt
+"trunc.w.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_trunc_fmt (SD_, fmt_word, FMT_MICROMIPS, FT, FS);
+}
+
+101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS_CVT_S!3,11011,01,111,011:R6CVTSFMT:32,f::CVT.S.dsw
+"cvt.s.%s<FMT_MICROMIPS_CVT_S> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_cvt_s_fmt (SD_, convert_fmt_micromips_cvt_s (SD_, FMT_MICROMIPS_CVT_S),
+    FT, FS, instruction_0);
+}
+
+010001,5.FT,110,16.U,11:R6PLSU12:32::SDC1GP
+"sdc1 f<FT>, <U_SHIFT_2BIT>(GP)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], U_SHIFT_2BIT, GP);
+  do_store (SD_, AccessLength_DOUBLEWORD, GP, U_SHIFT_2BIT, COP_SD (1, FT));
+}
+
+101000,5.FT,5.FS,5.FD,1.X,0,1.FMT_MICROMIPS,01110,000:R6SUBFMT1:32,f::SUB.fmt
+"sub.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FS], FGR[FT]);
+  do_sub_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FD, FS, FT,
+        instruction_0);
+  TRACE_ALU_RESULT(FGR[FD]);
+}
+
+101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS!3!2,00011,01,111,011:R6POOL32FXF1:32,f::::ABS.fmt
+"abs.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_abs_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+        instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,1.X,1.FMT_MICROMIPS,110111,000:R6POOL32F0:32,f::MADDF.fmt
+"maddf.%s<FMT_MICROMIPS> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT2(FGR[FS], FGR[FT]);
+  do_maddf (SD_, FD, FS, FT, convert_fmt_micromips (SD_, FMT_MICROMIPS), instruction_0);
+  TRACE_ALU_RESULT(FGR[FD]);
+}
+
+101000,5.FT,5.FS,1.X,2.FMT_MICROMIPS!3!2,01011,01,111,011:R6POOL32FXF1:32,f::NEG.fmt
+"neg.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_neg_fmt (SD_, convert_fmt_micromips (SD_, FMT_MICROMIPS), FT, FS,
+        instruction_0);
+}
+
+101000,5.FT,5.FS,1.X,1.FMT_MICROMIPS,100011,00,111,011:R6POOL32FXF0:32,f::TRUNC.L.fmt
+"trunc.l.%s<FMT_MICROMIPS> f<FT>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_trunc_fmt (SD_, fmt_long, FMT_MICROMIPS, FT, FS);
+}
+
+001000,5.RT,5.RS,5.FT,1011,1,000,111:R6POOLPPLSXS:32,f::SWC1XS
+"swc1xs f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_swc1xs(SD_, FT, RS, RT, instruction_0);
+}
+
+001000,5.RT,5.RS,5.FT,1111,0,000,111:R6POOLPPLSX:32,f::SDC1X
+"sdc1x f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], GPR[RT], COP_SD (1, FT));
+}
+
+001000,5.RT,5.RS,5.FT,1111,1,000,111:R6POOLPPLSXS:32,f::SDC1XS
+"sdc1xs f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  check_fpu (SD_);
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS] << 3, GPR[RT], COP_SD (1, FT));
+}
+
+001000,5.RT,5.RS,5.FT,1110,0,000,111:R6POOLPPLSXS:32::LDC1X
+"ldc1x f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], GPR[RT]));
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+001000,5.RT,5.RS,5.FT,1110,1,000,111:R6POOLPPLSXS:32::LDC1XS
+"ldc1xs f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS] << 3, GPR[RT]));
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+001000,5.RT,5.RS,5.FT,1010,1,000,111:R6POOLPPLSXS:32::LWC1XS
+"lwc1xs f<FT>, r<RS>(r<RT>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  do_lwc1xs (SD_, FT, RS, RT);
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+001000,5.RT,5.RS,5.FT,1010,0,000,111:R6PPLSX:32,f::LWC1X
+"lwc1x f<FT>, r<RT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(FGR[FT], GPR[RS], GPR[RT]);
+  do_lwxc1 (SD_, FT, RT, RS, instruction_0);
+  TRACE_ALU_RESULT(FGR[FT]);
+}
+
+001000,5.RT,5.RS,5.FT,1011,0,000,111:R6PPLSX:32,f::SWC1X
+"swc1x f<FT>, r<RT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_swxc1 (SD_, FT, RT, RS, instruction_0);
+}
+
+101001,5.FT,5.RS,1.S1,1110,0,00,8.S2:R6PLSS0:32,f::LDC1S9
+"ldc1 r<FT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]);
+  COP_LD (1, FT, do_load (SD_, AccessLength_DOUBLEWORD, GPR[RS], S_9_BIT));
+  TRACE_ALU_RESULT(GPR[FT]);
+}
+
+101001,5.FT,5.RS,1.S1,1111,0,00,8.S2:R6PLSS0:32,f::SDC1S9
+"sdc1 r<FT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]);
+  do_store (SD_, AccessLength_DOUBLEWORD, GPR[RS], S_9_BIT, COP_SD (1, FT));
+}
+
+101001,5.FT,5.RS,1.S1,1010,0,00,8.S2:R6PLSS0:32::LWC1S9
+"lwc1 f<FT>, <S_9_BIT>(r<RS>)"
+*nanomips32r6:
+*nanomips64r6:
+{
+  TRACE_ALU_INPUT3(GPR[FT], S_9_BIT, GPR[RS]);
+  do_lwc1 (SD_, FT, S_9_BIT, RS);
+  TRACE_ALU_RESULT(GPR[FT]);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,000000011:R6POOL32F3:32,f::MIN.fmt
+"min.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_min (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,000001,011:R6POOL32F3:32,f::MAX.fmt
+"max.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_max (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,000100,011:R6POOL32F3:32,f::MINA.fmt
+"mina.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_mina (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,000101,011:R6POOL32F3:32,f::MAXA.fmt
+"maxa.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_maxa (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,111111,000:R6POOL32F0:32,f::MSUBF.fmt
+"msubf.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_msubf (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FS,5.FD,00000,2.FMT,000100,000:R6POOL32F0:32,f::RINT.fmt
+"rint.%s<FMT> f<FD>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_rint (SD_, FD, FS, FMT, instruction_0);
+}
+
+101000,5.FS,5.FD,00000,2.FMT,001100,000:R6POOL32F0:32,f::CLASS.fmt
+"class.%s<FMT> f<FD>, f<FS>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_class (SD_, FD, FS, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,010111,000:R6POOL32F0:32,f::SEL.fmt
+"sel.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_self (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,000111,000:R6POOL32F0:32,f::SELEQZ.fmt
+"seleqz.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_seleqzf (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+101000,5.FT,5.FS,5.FD,2.FMT,001111,000:R6POOL32F0:32,f::SELNEZ.fmt
+"selnez.%s<FMT> f<FD>, f<FS>, f<FT>"
+*nanomips32r6:
+*nanomips64r6:
+{
+  do_selnezf (SD_, FD, FS, FT, FMT, instruction_0);
+}
+
+:function:::void:do_lb:int rt, int offset, int base
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[rt] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[base], offset));
+}
+
+:function:::void:do_lh:int rt, int offset, int base
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[rt] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], offset));
+}
+
+:function:::void:do_lw:int rt, int offset, int base
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[rt] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], offset));
+}
+
+:function:::void:do_lhu:int rt, int offset, int base
+*nanomips32r6:
+*nanomips64r6:
+{
+  GPR[rt] = do_load (SD_, AccessLength_HALFWORD, GPR[base], offset);
+}
+
+:function:::void:do_addiu:int rs, int rt, int immediate
+*nanomips32r6:
+*nanomips64r6:
+{
+  if (NotWordValue (GPR[rs]))
+    Unpredictable ();
+  TRACE_ALU_INPUT2 (GPR[rs], immediate);
+  GPR[rt] = EXTEND32 (GPR[rs] + immediate);
+  TRACE_ALU_RESULT (GPR[rt]);
+}
diff --git a/sim/mips/nanomipsrun.c b/sim/mips/nanomipsrun.c
new file mode 100644
index 00000000000..6321fd441ec
--- /dev/null
+++ b/sim/mips/nanomipsrun.c
@@ -0,0 +1,109 @@
+/*  Run function for the nanomips simulator
+
+    Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+    Written by Andrew Bennett <andrew.bennett@imgtec.com>.
+
+    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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "sim-main.h"
+#include "nanomips16_idecode.h"
+#include "nanomips32_idecode.h"
+#include "bfd.h"
+
+
+#define SD sd
+#define CPU cpu
+#define SIM_MONITOR_ADDRESS 0xBFC00000
+
+void
+sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int signal);
+
+address_word
+nanomips_instruction_decode (SIM_DESC sd, sim_cpu * cpu,
+            address_word cia,
+            int instruction_size);
+
+address_word
+nanomips_instruction_decode (SIM_DESC sd, sim_cpu * cpu,
+			      address_word cia,
+			      int instruction_size)
+{
+
+  nanomips16_instruction_word instruction_0 = IMEM16_NANOMIPS (cia);
+
+  if((cia & 0xFFF00000) == SIM_MONITOR_ADDRESS) {
+    nanomips32_instruction_word instruction_0 = IMEM32 (cia);
+    return nanomips32_idecode_issue (sd, instruction_0, cia);
+  } else if ((STATE_ARCHITECTURE (sd)->mach == bfd_mach_nanomipsisa32r6
+	  || STATE_ARCHITECTURE (sd)->mach == bfd_mach_nanomipsisa64r6)
+	     && (NANOMIPS_MAJOR_OPCODE_3_5 (instruction_0) & 0x4) == 4)
+	return nanomips16_idecode_issue (sd, instruction_0, cia);
+      else
+	{
+	  nanomips32_instruction_word instruction_0 = IMEM32_NANOMIPS (cia);
+	  return nanomips32_idecode_issue (sd, instruction_0, cia);
+	}
+}
+
+void
+sim_engine_run (SIM_DESC sd, int next_cpu_nr, int nr_cpus,
+		int signal)
+{
+  nanomips32_instruction_word instruction_0;
+  sim_cpu *cpu = STATE_CPU (sd, next_cpu_nr);
+  nanomips32_instruction_address cia = CIA_GET (cpu);
+  unsigned long bfdmach;
+  is_nanomips = 1;
+
+  bfdmach = STATE_ARCHITECTURE(SD)->mach;
+
+  if (is_nms_flag_set == 0 && (bfdmach == bfd_mach_nanomipsisa64r6
+      || bfdmach == bfd_mach_nanomipsisa32r6))
+    set_nms_flag (sd);
+
+  while (1)
+    {
+      nanomips32_instruction_address nia;
+
+	    cia = cia & ~0x1;
+
+#if defined (ENGINE_ISSUE_PREFIX_HOOK)
+      ENGINE_ISSUE_PREFIX_HOOK ();
+#endif
+
+    nia =
+      nanomips_instruction_decode (sd, cpu, cia,
+            MICROMIPS_DELAYSLOT_SIZE_ANY);
+
+#if defined (ENGINE_ISSUE_POSTFIX_HOOK)
+      ENGINE_ISSUE_POSTFIX_HOOK ();
+#endif
+      // Cycle counting
+      COP0_COUNT++;
+
+      /* Update the instruction address */
+      cia = nia;
+
+      /* process any events */
+      if (sim_events_tick (sd))
+	{
+	  CIA_SET (CPU, cia);
+	  sim_events_process (sd);
+	  cia = CIA_GET (CPU);
+	}
+    }
+}
diff --git a/sim/mips/nms.c b/sim/mips/nms.c
new file mode 100644
index 00000000000..fd957d69e8b
--- /dev/null
+++ b/sim/mips/nms.c
@@ -0,0 +1,44 @@
+/*  Run function for the nanomips simulator
+
+    Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+    Written by Andrew Bennett <andrew.bennett@imgtec.com>.
+
+    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 3 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, see <http://www.gnu.org/licenses/>.  */
+
+#include "sim-main.h"
+#include "elf/mips-common.h"
+#include "elf/nanomips.h"
+
+/* NMS Flag */
+int nms_flag = -1;
+
+int is_nms_flag_set = 0;
+
+void
+set_nms_flag (SIM_DESC sd)
+{
+  Elf_Internal_ABIFlags_v0 *abiflags;
+  abiflags = bfd_nanomips_elf_get_abiflags (STATE_PROG_BFD(sd));
+
+  nms_flag = 0;
+
+  if (abiflags != NULL
+      && ((abiflags->ases & NANOMIPS_ASE_xNMS) != 0))
+    nms_flag = 1;
+
+  is_nms_flag_set = 1;
+}
diff --git a/sim/mips/sim-main.c b/sim/mips/sim-main.c
index 250310eceb3..183082ab7c7 100644
--- a/sim/mips/sim-main.c
+++ b/sim/mips/sim-main.c
@@ -32,6 +32,81 @@
 /*---------------------------------------------------------------------------*/
 
 
+/* 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. */
+
+INLINE_SIM_MAIN
+(int)
+address_translation (SIM_DESC sd,
+		     sim_cpu * cpu,
+		     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. */
+
+INLINE_SIM_MAIN (void)
+prefetch (SIM_DESC sd,
+	  sim_cpu *cpu,
+	  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
@@ -266,13 +341,15 @@ ifetch32 (SIM_DESC SD,
   address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
   address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
   unsigned int byte;
-  address_word paddr = vaddr;
+  address_word paddr;
+  int uncached;
   uint64_t memval;
 
   if ((vaddr & access) != 0)
     SignalExceptionInstructionFetch ();
+  AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-  LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL);
+  LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
   byte = ((vaddr & mask) ^ bigendiancpu);
   return (memval >> (8 * byte));
 }
@@ -290,13 +367,15 @@ ifetch16 (SIM_DESC SD,
   address_word reverseendian = (ReverseEndian ? (mask ^ access) : 0);
   address_word bigendiancpu = (BigEndianCPU ? (mask ^ access) : 0);
   unsigned int byte;
-  address_word paddr = vaddr;
+  address_word paddr;
+  int uncached;
   uint64_t memval;
 
   if ((vaddr & access) != 0)
     SignalExceptionInstructionFetch ();
+  AddressTranslation (vaddr, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL);
   paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverseendian));
-  LoadMemory (&memval, NULL, access, paddr, vaddr, isINSTRUCTION, isREAL);
+  LoadMemory (&memval, NULL, uncached, access, paddr, vaddr, isINSTRUCTION, isREAL);
   byte = ((vaddr & mask) ^ bigendiancpu);
   return (memval >> (8 * byte));
 }
diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h
index 418c6599118..1397202c787 100644
--- a/sim/mips/sim-main.h
+++ b/sim/mips/sim-main.h
@@ -262,6 +262,8 @@ struct _sim_cpu {
 
 
   /* The following are internal simulator state variables: */
+#define CIA_GET(CPU) ((CPU)->registers[PCIDX] + 0)
+#define CIA_SET(CPU,CIA) ((CPU)->registers[PCIDX] = (CIA))
   address_word dspc;  /* delay-slot PC */
 #define DSPC ((CPU)->dspc)
 
@@ -318,9 +320,9 @@ struct _sim_cpu {
 #define LAST_EMBED_REGNUM (96)
 #define NUM_REGS (LAST_EMBED_REGNUM + 1)
 
-#define FP0_REGNUM 38           /* Floating point register 0 (single float) */
-#define FCRCS_REGNUM 70         /* FP control/status */
-#define FCRIR_REGNUM 71         /* FP implementation/revision */
+#define FP0_REGNUM 36           /* Floating point register 0 (single float) */
+#define FCRCS_REGNUM 68         /* FP control/status */
+#define FCRIR_REGNUM 69         /* FP implementation/revision */
 #endif
 
 
@@ -336,16 +338,16 @@ struct _sim_cpu {
 #define GPR     (&REGISTERS[0])
 #define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL))
 
-#define LO      (REGISTERS[33])
-#define HI      (REGISTERS[34])
-#define PCIDX	37
+#define HI      (REGISTERS[70])
+#define LO      (REGISTERS[71])
+#define PCIDX	(is_nanomips?32:35)
 #define PC      (REGISTERS[PCIDX])
-#define CAUSE   (REGISTERS[36])
+#define CAUSE   (REGISTERS[34])
 #define SRIDX   (32)
 #define SR      (REGISTERS[SRIDX])      /* CPU status register */
-#define FCR0IDX  (71)
+#define FCR0IDX  (69)
 #define FCR0    (REGISTERS[FCR0IDX])    /* really a 32bit register */
-#define FCR31IDX (70)
+#define FCR31IDX (68)
 #define FCR31   (REGISTERS[FCR31IDX])   /* really a 32bit register */
 #define FCSR    (FCR31)
 #define Debug	(REGISTERS[86])
@@ -353,19 +355,19 @@ struct _sim_cpu {
 #define EPC	(REGISTERS[88])
 #define ACX	(REGISTERS[89])
 
-#define AC0LOIDX	(33)	/* Must be the same register as LO */
-#define AC0HIIDX	(34)	/* Must be the same register as HI */
-#define AC1LOIDX	(90)
-#define AC1HIIDX	(91)
-#define AC2LOIDX	(92)
-#define AC2HIIDX	(93)
-#define AC3LOIDX	(94)
-#define AC3HIIDX	(95)
+#define AC0HIIDX	(70)	/* Must be the same register as HI */
+#define AC0LOIDX	(71)	/* Must be the same register as LO */
+#define AC1HIIDX	(72)
+#define AC1LOIDX	(73)
+#define AC2HIIDX	(74)
+#define AC2LOIDX	(75)
+#define AC3HIIDX	(76)
+#define AC3LOIDX	(77)
 
 #define DSPLO(N)	(REGISTERS[DSPLO_REGNUM[N]])
 #define DSPHI(N)	(REGISTERS[DSPHI_REGNUM[N]])
 
-#define DSPCRIDX	(96)	/* DSP control register */
+#define DSPCRIDX	(79)	/* DSP control register */
 #define DSPCR		(REGISTERS[DSPCRIDX])
 
 #define DSPCR_POS_SHIFT		(0)
@@ -420,6 +422,8 @@ struct _sim_cpu {
 #define A3      (REGISTERS[7])
 #define T8IDX   24
 #define T8	(REGISTERS[T8IDX])
+#define GPIDX   28
+#define GP      (REGISTERS[GPIDX])
 #define SPIDX   29
 #define SP      (REGISTERS[SPIDX])
 #define RAIDX   31
@@ -433,6 +437,7 @@ struct _sim_cpu {
   unsigned_word cop0_gpr[NR_COP0_GPR];
 #define COP0_GPR	((CPU)->cop0_gpr)
 #define COP0_BADVADDR	(COP0_GPR[8])
+#define COP0_COUNT (COP0_GPR[9])
 
   /* While space is allocated for the floating point registers in the
      main registers array, they are stored separatly.  This is because
@@ -476,6 +481,17 @@ struct _sim_cpu {
   sim_cpu_base base;
 };
 
+extern int is_nanomips;
+
+#define SET_RV0(VAL)             \
+  do {                 \
+    if (is_nanomips)             \
+      A0 = VAL;                \
+    else               \
+      V0 = VAL;                \
+  } while (0)
+
+
 extern void mips_sim_close (SIM_DESC sd, int quitting);
 #define SIM_CLOSE_HOOK(...) mips_sim_close (__VA_ARGS__)
 
@@ -643,13 +659,16 @@ enum ExceptionCause {
    is used by gdb for break-points.  NOTE: Care must be taken, since
    this value may be used in later revisions of the MIPS ISA. */
 #define HALT_INSTRUCTION_MASK   (0x03FFFFC0)
+#define HALT_INSTRUCTION_MASK_NANOMIPS (0x0007FFFF)
 
 #define HALT_INSTRUCTION        (0x03ff000d)
 #define HALT_INSTRUCTION2       (0x0000ffcd)
+#define HALT_INSTRUCTION_NANOMIPS      (0x001003FF)
 
 
 #define BREAKPOINT_INSTRUCTION  (0x0005000d)
 #define BREAKPOINT_INSTRUCTION2 (0x0000014d)
+#define BREAKPOINT_INSTRUCTION_NANOMIPS  (0x00101400)
 
 
 
@@ -728,6 +747,44 @@ void store_fcr (SIM_STATE, int fcr, unsigned_word value);
 void test_fcsr (SIM_STATE);
 #define TestFCSR() test_fcsr (SIM_ARGS)
 
+/* FPU operations.  */
+/* Non-signalling */
+#define FP_R6CMP_AF  0x0
+#define FP_R6CMP_EQ  0x2
+#define FP_R6CMP_LE  0x6
+#define FP_R6CMP_LT  0x4
+#define FP_R6CMP_NE  0x13
+#define FP_R6CMP_OR  0x11
+#define FP_R6CMP_UEQ 0x3
+#define FP_R6CMP_ULE 0x7
+#define FP_R6CMP_ULT 0x5
+#define FP_R6CMP_UN  0x1
+#define FP_R6CMP_UNE 0x12
+
+/* Signalling */
+#define FP_R6CMP_SAF  0x8
+#define FP_R6CMP_SEQ  0xa
+#define FP_R6CMP_SLE  0xe
+#define FP_R6CMP_SLT  0xc
+#define FP_R6CMP_SNE  0x1b
+#define FP_R6CMP_SOR  0x19
+#define FP_R6CMP_SUEQ 0xb
+#define FP_R6CMP_SULE 0xf
+#define FP_R6CMP_SULT 0xd
+#define FP_R6CMP_SUN  0x9
+#define FP_R6CMP_SUNE 0x1a
+
+/* FPU Class */
+#define FP_R6CLASS_SNAN    (1<<0)
+#define FP_R6CLASS_QNAN    (1<<1)
+#define FP_R6CLASS_NEGINF  (1<<2)
+#define FP_R6CLASS_NEGNORM (1<<3)
+#define FP_R6CLASS_NEGSUB  (1<<4)
+#define FP_R6CLASS_NEGZERO (1<<5)
+#define FP_R6CLASS_POSINF  (1<<6)
+#define FP_R6CLASS_POSNORM (1<<7)
+#define FP_R6CLASS_POSSUB  (1<<8)
+#define FP_R6CLASS_POSZERO (1<<9)
 
 /* FPU operations.  */
 /* Non-signalling */
@@ -812,21 +869,21 @@ uint64_t fp_fmadd (SIM_STATE, uint64_t op1, uint64_t op2,
 		     uint64_t op3, FP_formats fmt);
 #define FusedMultiplySub(op1,op2,op3,fmt) fp_fmsub(SIM_ARGS, op1, op2, op3, fmt)
 uint64_t fp_fmsub (SIM_STATE, uint64_t op1, uint64_t op2,
-		     uint64_t op3, FP_formats fmt);
+         uint64_t op3, FP_formats fmt);
 #define MultiplyAdd(op1,op2,op3,fmt) fp_madd(SIM_ARGS, op1, op2, op3, fmt)
 uint64_t fp_msub (SIM_STATE, uint64_t op1, uint64_t op2,
-		    uint64_t op3, FP_formats fmt);
+         uint64_t op3, FP_formats fmt);
 #define MultiplySub(op1,op2,op3,fmt) fp_msub(SIM_ARGS, op1, op2, op3, fmt)
 uint64_t fp_nmadd (SIM_STATE, uint64_t op1, uint64_t op2,
-		     uint64_t op3, FP_formats fmt);
+         uint64_t op3, FP_formats fmt);
 #define NegMultiplyAdd(op1,op2,op3,fmt) fp_nmadd(SIM_ARGS, op1, op2, op3, fmt)
 uint64_t fp_nmsub (SIM_STATE, uint64_t op1, uint64_t op2,
-		     uint64_t op3, FP_formats fmt);
+         uint64_t op3, FP_formats fmt);
 #define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt)
 uint64_t convert (SIM_STATE, int rm, uint64_t op, FP_formats from, FP_formats to);
 #define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to)
 uint64_t convert_ps (SIM_STATE, int rm, uint64_t op, FP_formats from,
-		       FP_formats to);
+           FP_formats to);
 #define ConvertPS(rm,op,from,to) convert_ps (SIM_ARGS, rm, op, from, to)
 
 
@@ -959,6 +1016,12 @@ uint64_t mdmx_shuffle (SIM_STATE, int, uint64_t, uint64_t);
 /* 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 */
@@ -985,13 +1048,17 @@ uint64_t mdmx_shuffle (SIM_STATE, int, uint64_t, uint64_t);
 		    ? AccessLength_DOUBLEWORD /*7*/ \
 		    : AccessLength_WORD /*3*/)
 
+INLINE_SIM_MAIN (int) address_translation (SIM_DESC sd, sim_cpu *, 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, CPU, cia, vAddr, IorD, LorS, pAddr, CCA, raw)
+
 INLINE_SIM_MAIN (void) load_memory (SIM_DESC sd, sim_cpu *cpu, address_word cia, uword64* memvalp, uword64* memval1p, int CCA, unsigned int AccessLength, address_word pAddr, address_word vAddr, int IorD);
-#define LoadMemory(memvalp,memval1p,AccessLength,pAddr,vAddr,IorD,raw) \
-load_memory (SD, CPU, cia, memvalp, memval1p, 0, AccessLength, pAddr, vAddr, IorD)
+#define LoadMemory(memvalp,memval1p,CCA,AccessLength,pAddr,vAddr,IorD,raw) \
+load_memory (SD, CPU, cia, memvalp, memval1p, CCA, AccessLength, pAddr, vAddr, IorD)
 
 INLINE_SIM_MAIN (void) store_memory (SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, unsigned int AccessLength, uword64 MemElem, uword64 MemElem1, address_word pAddr, address_word vAddr);
-#define StoreMemory(AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
-store_memory (SD, CPU, cia, 0, AccessLength, MemElem, MemElem1, pAddr, vAddr)
+#define StoreMemory(CCA,AccessLength,MemElem,MemElem1,pAddr,vAddr,raw) \
+store_memory (SD, CPU, cia, CCA, AccessLength, MemElem, MemElem1, pAddr, vAddr)
 
 INLINE_SIM_MAIN (void) cache_op (SIM_DESC sd, sim_cpu *cpu, address_word cia, int op, address_word pAddr, address_word vAddr, unsigned int instruction);
 #define CacheOp(op,pAddr,vAddr,instruction) \
@@ -1001,6 +1068,10 @@ INLINE_SIM_MAIN (void) sync_operation (SIM_DESC sd, sim_cpu *cpu, address_word c
 #define SyncOperation(stype) \
 sync_operation (SD, CPU, cia, (stype))
 
+INLINE_SIM_MAIN (void) prefetch (SIM_DESC sd, sim_cpu *cpu, address_word cia, int CCA, address_word pAddr, address_word vAddr, int DATA, int hint);
+#define Prefetch(CCA,pAddr,vAddr,DATA,hint) \
+prefetch (SD, CPU, cia, CCA, pAddr, vAddr, DATA, hint)
+
 void unpredictable_action (sim_cpu *cpu, address_word cia);
 #define NotWordValue(val)	not_word_value (SD_, (val))
 #define Unpredictable()		unpredictable (SD_)
@@ -1022,6 +1093,16 @@ INLINE_SIM_MAIN (uint16_t) ifetch16 (SIM_DESC sd, sim_cpu *cpu, address_word cia
 #define MICROMIPS_DELAYSLOT_SIZE_16 2
 #define MICROMIPS_DELAYSLOT_SIZE_32 4
 
+#define IMEM32_NANOMIPS(CIA) \
+  (ifetch16 (SD, CPU, (CIA), (CIA)) << 16 | ifetch16 (SD, CPU, (CIA + 2), \
+                  (CIA + 2)))
+#define IMEM16_NANOMIPS(CIA) ifetch16 (SD, CPU, (CIA), ((CIA)))
+
+
+#define NANOMIPS_MAJOR_OPCODE_3_5(INSN) ((INSN & 0x1c00) >> 10)
+
+#define NANOMIPS_DELAYSLOT_SIZE_ANY 0
+
 extern int isa_mode;
 
 #define ISA_MODE_MIPS32 0
@@ -1041,6 +1122,13 @@ extern FILE *tracefh;
 extern int DSPLO_REGNUM[4];
 extern int DSPHI_REGNUM[4];
 
+/* NMS Flag */
+extern int nms_flag;
+extern int is_nms_flag_set;
+
+void
+set_nms_flag (SIM_DESC sd);
+
 INLINE_SIM_MAIN (void) pending_tick (SIM_DESC sd, sim_cpu *cpu, address_word cia);
 extern SIM_CORE_SIGNAL_FN mips_core_signal;
 
@@ -1055,10 +1143,16 @@ 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)
+extern address_word micromips_instruction_decode_multi(SIM_DESC sd,
+                   sim_cpu* cpu,
+                   address_word cia,
+                   int instruction_size);
+#define MICROMIPS_INSTRUCTION_DECODE(SD, cpu, cia, size) \
+  micromips_instruction_decode_multi (SD, cpu, cia, size);
 #else
-#define	MIPS_MACH(SD)	MIPS_MACH_DEFAULT
+#define MIPS_MACH(SD) MIPS_MACH_DEFAULT
+#define MICROMIPS_INSTRUCTION_DECODE(SD, cpu, cia, size) \
+  micromips_instruction_decode (SD, cpu, cia, size);
 #endif
 
 /* Macros for determining whether a MIPS IV or MIPS V part is subject
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-12-13 16:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-13 16:09 [PATCH v3 1/2] sim: Add nanoMIPS port Aleksandar Rikalo
  -- strict thread matches above, loose matches on Subject: below --
2022-04-29 15:58 [PATCH 2/3] " Aleksandar Rikalo
2022-11-21 11:06 ` [PATCH v3 1/2] " Aleksandar Rikalo
2022-11-25 12:11   ` Mike Frysinger
2022-11-25 15:36     ` Aleksandar Rikalo
2022-12-12 11:11       ` Mike Frysinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).