* [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 (®ISTERS[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
* [PATCH v3 1/2] sim: Add nanoMIPS port
@ 2022-11-21 11:06 ` Aleksandar Rikalo
2022-11-25 12:11 ` Mike Frysinger
0 siblings, 1 reply; 5+ messages in thread
From: Aleksandar Rikalo @ 2022-11-21 11:06 UTC (permalink / raw)
To: gdb-patches; +Cc: aleksandar.rikalo, arikalo
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 | 2 +-
sim/configure.ac | 2 +-
sim/mips/Makefile.in | 28 +
sim/mips/configure | 28 +
sim/mips/configure.ac | 28 +
sim/mips/interp.c | 21 +-
sim/mips/micromips16.dc | 3 +
sim/mips/mips.igen | 193 ++-
sim/mips/nanomipsdsp.igen | 1115 +++++++++++++++
sim/mips/nanomipsr6.igen | 2744 +++++++++++++++++++++++++++++++++++++
sim/mips/nanomipsrun.c | 109 ++
sim/mips/nms.c | 44 +
sim/mips/sim-main.h | 61 +-
14 files changed, 4358 insertions(+), 24 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 57c4fcf6972..aa9e21a2923 100755
--- a/sim/configure
+++ b/sim/configure
@@ -15157,7 +15157,7 @@ fi
sim_enable_arch_mips=false
case "${targ}" in
- all|mips*-*-*)
+ all|mips*-*-*|nanomips*-*-*)
if test "${targ}" = "${target}"; then
SIM_PRIMARY_TARGET=mips
fi
diff --git a/sim/configure.ac b/sim/configure.ac
index 675fa1bb44d..3f606ac5b64 100644
--- a/sim/configure.ac
+++ b/sim/configure.ac
@@ -143,7 +143,7 @@ if test "${enable_sim}" != no; then
SIM_TARGET([m68hc11-*-*|m6811-*-*], [m68hc11])
SIM_TARGET([mcore-*-*], [mcore])
SIM_TARGET([microblaze*-*-*], [microblaze])
- SIM_TARGET([mips*-*-*], [mips], [true], [sim_igen=yes])
+ SIM_TARGET([mips*-*-*|nanomips*-*-*], [mips], [true], [sim_igen=yes])
SIM_TARGET([mn10300*-*-*], [mn10300], [], [sim_igen=yes])
SIM_TARGET([moxie-*-*], [moxie])
SIM_TARGET([msp430*-*-*], [msp430])
diff --git a/sim/mips/Makefile.in b/sim/mips/Makefile.in
index 75438be5a18..8637b46b186 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 \
@@ -99,6 +100,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 +466,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 +585,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 b0ba7ba7470..493547fc97b 100755
--- a/sim/mips/configure
+++ b/sim/mips/configure
@@ -2028,6 +2028,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
;;
@@ -2226,6 +2232,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.
@@ -2238,6 +2255,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/configure.ac b/sim/mips/configure.ac
index f1d9f3d2410..e8153b0c5ac 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 ab20f079939..3612956bb2b 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -356,6 +356,8 @@ sim_open (SIM_OPEN_KIND kind, host_callback *cb,
cpu = STATE_CPU (sd, 0); /* FIXME */
+ IS_NANOMIPS = 0;
+
/* FIXME: watchpoints code shouldn't need this */
STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
@@ -672,10 +674,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 +1205,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 +1215,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, buf, nr);
free (buf);
}
@@ -1222,7 +1227,7 @@ sim_monitor (SIM_DESC sd,
int nr = A2;
char *buf = zalloc (nr);
sim_read (sd, A1, 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 +1238,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 +1257,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;
}
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 0746a52d5ab..e9110c44f2f 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,33 @@
// 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:
+*mips32r6:
+*mips64:
+*mips64r2:
+*mips64r6:
+*vr4100:
+*vr4120:
+*vr5000:
+*vr5400:
+*vr5500:
+*r3900:
+*mips16:
+*mips16e:
+*mips3d:
+*mdmx:
+*dsp:
+*dsp2:
+*smartmips:
+*micromips32:
+*micromips64:
+*micromipsdsp:
{
SignalException (ReservedInstruction, instruction_0);
}
@@ -192,6 +222,7 @@
*vr5000:
*r3900:
*micromips32:
+*nanomips32r6:
{
return base + offset;
}
@@ -201,6 +232,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 +269,8 @@
*micromips32:
*micromips64:
*mips64r6:
+*nanomips32r6:
+*nanomips64r6:
{
#if WITH_TARGET_WORD_BITSIZE == 64
return value != (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
@@ -274,6 +308,8 @@
*micromips32:
*micromips64:
*mips64r6:
+*nanomips32r6:
+*nanomips64r6:
{
unpredictable_action (CPU, CIA);
}
@@ -369,6 +405,7 @@
*r3900:
*micromips32:
*micromips64:
+*nanomipsdsp:
{
int64_t time = sim_events_time (SD);
history->mt.timestamp = time;
@@ -399,6 +436,7 @@
*r3900:
*micromips32:
*micromips64:
+*nanomipsdsp:
{
int64_t time = sim_events_time (SD);
int ok = 1;
@@ -473,6 +511,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 +609,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 +822,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 +884,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 +912,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));
}
@@ -1861,7 +1966,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 +2716,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 +2770,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 +2817,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 +2877,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]);
@@ -3714,6 +3879,25 @@
:function:::void:do_mfhi:int rd
+*mipsI:
+*mipsII:
+*mipsIII:
+*mipsIV:
+*mipsV:
+*vr4100:
+*vr5000:
+*r3900:
+*mips32:
+*mips64:
+*mips32r2:
+*mips32r6:
+*mips64r2:
+*mips64r6:
+*dsp:
+*micromips32:
+*micromips64:
+*micromipsdsp:
+*nanomipsdsp:
{
check_mf_hilo (SD_, HIHISTORY, LOHISTORY);
TRACE_ALU_INPUT1 (HI);
@@ -5225,6 +5409,8 @@
*vr4100:
*vr5000:
*r3900:
+*nanomips32r6:
+*nanomips64r6:
{
/* None of these ISAs support Paired Single, so just fall back to
the single/double check. */
@@ -5273,6 +5459,8 @@
*r3900:
*micromips32:
*micromips64:
+*nanomips32r6:
+*nanomips64r6:
{
if (! COP_Usable (1))
SignalExceptionCoProcessorUnusable (1);
@@ -6867,4 +7055,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..07fd26b6ad0
--- /dev/null
+++ b/sim/mips/nanomipsdsp.igen
@@ -0,0 +1,1115 @@
+// 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,13.S1,1.S2:POOL32I:32::BPOSGE32C
+"bposge32c <ADDRESS15>"
+*nanomipsdsp:
+{
+ uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK;
+ if (pos >= 32)
+ NIA = ADDRESS15;
+}
+
+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..bef5c04c3b3
--- /dev/null
+++ b/sim/mips/nanomipsr6.igen
@@ -0,0 +1,2744 @@
+// 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 = vaddr;
+ int uncached;
+ if ((vaddr & 7) != 0)
+ {
+ SIM_CORE_SIGNAL (SD, CPU, cia, read_map, 8, vaddr, read_transfer,
+ sim_core_unaligned_signal);
+ }
+ else
+ {
+ uint64_t memval = 0;
+ uint64_t memval1 = 0;
+ uint64_t data = memval;
+
+ LoadMemory (&memval, &memval1, 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:::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);
+ }
+}
+
+:%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:
+{
+ // nothing to do currently
+ 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;
+}
+
+: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..8698726a9fa
--- /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 = CPU_PC_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))
+ {
+ CPU_PC_SET (CPU, cia);
+ sim_events_process (sd);
+ cia = CPU_PC_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.h b/sim/mips/sim-main.h
index 418c6599118..e6b2b47ede7 100644
--- a/sim/mips/sim-main.h
+++ b/sim/mips/sim-main.h
@@ -318,9 +318,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 ((CPU)->is_nanomips ? 36 : 38) /* Floating point register 0 (single float) */
+#define FCRCS_REGNUM ((CPU)->is_nanomips ? 68 : 70) /* FP control/status */
+#define FCRIR_REGNUM ((CPU)->is_nanomips ? 69 : 71) /* FP implementation/revision */
#endif
@@ -336,16 +336,19 @@ struct _sim_cpu {
#define GPR (®ISTERS[0])
#define GPR_SET(N,VAL) (REGISTERS[(N)] = (VAL))
-#define LO (REGISTERS[33])
-#define HI (REGISTERS[34])
-#define PCIDX 37
+#define HIIDX ((CPU)->is_nanomips ? 70 : 33)
+#define LOIDX ((CPU)->is_nanomips ? 71 : 34)
+#define HI (REGISTERS[HIIDX])
+#define LO (REGISTERS[LOIDX])
+#define PCIDX ((CPU)->is_nanomips ? 32 : 37)
#define PC (REGISTERS[PCIDX])
-#define CAUSE (REGISTERS[36])
+#define COUSEIDX ((CPU)->is_nanomips ? 34 : 36)
+#define CAUSE (REGISTERS[COUSEIDX])
#define SRIDX (32)
#define SR (REGISTERS[SRIDX]) /* CPU status register */
-#define FCR0IDX (71)
+#define FCR0IDX ((CPU)->is_nanomips ? 69 : 71)
#define FCR0 (REGISTERS[FCR0IDX]) /* really a 32bit register */
-#define FCR31IDX (70)
+#define FCR31IDX ((CPU)->is_nanomips ? 68 : 70)
#define FCR31 (REGISTERS[FCR31IDX]) /* really a 32bit register */
#define FCSR (FCR31)
#define Debug (REGISTERS[86])
@@ -362,10 +365,10 @@ struct _sim_cpu {
#define AC3LOIDX (94)
#define AC3HIIDX (95)
-#define DSPLO(N) (REGISTERS[DSPLO_REGNUM[N]])
-#define DSPHI(N) (REGISTERS[DSPHI_REGNUM[N]])
+#define DSPLO(N) (REGISTERS[((CPU)->is_nanomips ? (LOIDX + 2 * N) : DSPLO_REGNUM[N])])
+#define DSPHI(N) (REGISTERS[((CPU)->is_nanomips ? (HIIDX + 2 * N) : DSPHI_REGNUM[N])])
-#define DSPCRIDX (96) /* DSP control register */
+#define DSPCRIDX ((CPU)->is_nanomips ? 79 : 96) /* DSP control register */
#define DSPCR (REGISTERS[DSPCRIDX])
#define DSPCR_POS_SHIFT (0)
@@ -420,6 +423,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 +438,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
@@ -472,10 +478,21 @@ struct _sim_cpu {
hilo_history lo_history;
#define LOHISTORY (&(CPU)->lo_history)
+ int is_nanomips;
+#define IS_NANOMIPS ((CPU)->is_nanomips)
sim_cpu_base base;
};
+#define SET_RV0(VAL) \
+ do { \
+ if ((CPU)->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 +660,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)
@@ -1022,6 +1042,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 +1071,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;
--
2.25.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] sim: Add nanoMIPS port
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
0 siblings, 1 reply; 5+ messages in thread
From: Mike Frysinger @ 2022-11-25 12:11 UTC (permalink / raw)
To: Aleksandar Rikalo; +Cc: gdb-patches, arikalo
[-- Attachment #1: Type: text/plain, Size: 336 bytes --]
this patch is large, and you haven't explicitly responded to the previous
review, or documented how you've incorporated (or not) the feedback. please
be clear as to what you've done rather than keep throwing patches up without
any response. i'm not inclined to go through the feedback myself and figure
out what you've changed.
-mike
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] sim: Add nanoMIPS port
@ 2022-11-25 15:36 ` Aleksandar Rikalo
2022-12-12 11:11 ` Mike Frysinger
0 siblings, 1 reply; 5+ messages in thread
From: Aleksandar Rikalo @ 2022-11-25 15:36 UTC (permalink / raw)
To: Mike Frysinger; +Cc: gdb-patches, arikalo
[-- Attachment #1: Type: text/plain, Size: 885 bytes --]
Hello Mike,
Compared to the first version, all of your comments have been addressed and patches are re-based onto the current master branch.
These changes depend on the patches(*) for Binutils, which we just updated, so I'm also preparing a new version (v4) for sim and gdb.
The changes will be minor, so the review can be done on this version (v3) as well.
(*) https://sourceware.org/pipermail/binutils/2022-November/124640.html
> is everyone's copyright papers in place ?
As far as I know, everyone's copyright papers are in place.
> seems odd that you're using a new "nanomips*" tuple instead of existing
> "mips*" space. but i guess if you've convinced everyone else that this
> isn't wrong, then sim/ will just follow.
I think all the other tools use "nanomips*" tuple. I'm sure about GCC, QEMU, and Valgrind.
Thank you for your time.
Aleksandar
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] sim: Add nanoMIPS port
2022-11-25 15:36 ` Aleksandar Rikalo
@ 2022-12-12 11:11 ` Mike Frysinger
0 siblings, 0 replies; 5+ messages in thread
From: Mike Frysinger @ 2022-12-12 11:11 UTC (permalink / raw)
To: Aleksandar Rikalo; +Cc: gdb-patches, arikalo
[-- Attachment #1: Type: text/plain, Size: 642 bytes --]
On 25 Nov 2022 15:36, Aleksandar Rikalo wrote:
> Compared to the first version, all of your comments have been addressed and patches are re-based onto the current master branch.
>
> These changes depend on the patches(*) for Binutils, which we just updated, so I'm also preparing a new version (v4) for sim and gdb.
> The changes will be minor, so the review can be done on this version (v3) as well.
>
> (*) https://sourceware.org/pipermail/binutils/2022-November/124640.html
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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ 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).