All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU
@ 2018-08-13 17:52 Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 01/87] MAINTAINERS: Update target/mips maintainer's email addresses Aleksandar Markovic
                   ` (88 more replies)
  0 siblings, 89 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

v7->v8:

  - the series is slightly reorganized so that:
      - patches 1-19 are fixes and improvements that are not
      dependent on the existence of nanoMIPS (even though most
      of them are logicaly connected to (and necessary for)
      nanoMIPS support) - they fix and improve pre-nanoMIPS code
      - patches 20-65 introduce core nanoMIPS functionality, but
      do not contain any dependence on or reference to nanoMIPS
      Linux ABI
      - patches 66-87 mostly deal with Linux user mode-related
      nanoMIPS functionality, therefore dependent on nanoMIPS
      Linux ABI
  - the series will probably be split into three (corresponding
      to the organization mentioned above) in near future

  - added support for availability control via bit config XNP
  - fixed availabitily control for LLWP/SCWP
  - added support for availability control via bit config MT
  - fixed availabitily control for pre-nanoMIPS MT ASE
  - fixed availabitily control for nanoMIPS MT ASE
  - completely removed case-statements defined by integer range
      from translate.c
  - patch on nanoMIPS specifics in ELF headers split into two
  - patch on GT64120-related functionality in nanoMIPS bootloader
      updated with comments and reorganizes with respect to
      endianness
  - replaced one instance of shift/mask with extract32()
  - fixed one instance of missing default case in decoding engine
  - removed several instances of unnecessary default case in
    decoding engine
  - minor tweaks related to variable scope and naming
  - fixed several spelling mistakes in commit messages
  - rebased to the latest code

v6->v7:

  - found a better place for MIPS_ARCH in elf.h
  - improved patch for LLWP and SCWP
  - fixed missing availability control, alignment, usage
    of extract32() in DSP patches
  - added disassembler support for microMIPS and nanoMIPS
  - removed unnecessary addition of one empty line in the
    patch on WR bit
  - improved statx() syscall translation
  - improved nanoMIPS items in binfmt script
  - amended pre-nanoMIPS items in qemu-doc.texi
  - added nanoMIPS items in qemu-doc.texi
  - changed slightly patch order to be logicaly more
    comprehensive 
  - rebased to the latest code
  - NOTE: there will be some sheckpatch.pl errors and warning
    for this series; however, we think those are flase positives
    in these particular circumstances - therefore we will not
    change any patch related to these checkpatch.pl messages

v5->v6:

  - used names offset and imm instead of rd and rs when
    appropriate
  - used gen_op_addr_addi when appropriate in one more place
  - avoided usage of tcg_temp_local_new
  - avoided unnecessary sign extension related to addr_add
  - fixed unprotected storing to cpu_gpr[0]
  - removed some unnecessary testing for ISA_NANOMIPS
  - updated patch for LLWP and SCWP
  - extract32 inserted instead of shift/mask in DSP patches
  - removed useless casts from DSP patches
  - reorganized functions to eliminated duplicated loading of
    gpr values into tcg variables in DSP patches
  - check Config1.WR bit for Watch registers only when using
    in runtime
  - removed duplicated check for bad address in PC register
  - added support for statx system call
  - updated script qemu-binfmt-conf.sh for nanoMIPS
  - rebased to the latest code

v4->v5:

  - merged series "Mips maintenance and misc fixes and improvements"
    and this one for easier handling (there are build dependencies)
  - eliminated shadow variables from translate.c
  - replaced shift/mask combination with extract32()
  - added new function gen_op_addr_addi()
  - added patch for LLWP and SCWP
  - added "fall through" comments at appropriate places
  - eliminated micromips flag from I7200 definition
  - numerous other enhancements originating from reviewer's
    comments
  - some of the patches split into two or more for easier
    handling and review
  - rebased to the latest code

v3->v4:

  - added support for nanoMIPS user mode functionality and
    configuration
  - DSP patch split into three for easier review and handling
  - corrected indentation in all decoding engine patches
  - shift/mask replaced with equivalent extract32() in some
    patches
  - added missing default cases in some patches
  - refactored invocation logic aroung decode_nanomips_opc()
  - improved comments before decode_gpr_XXX() utilities
  - all four decode_gpr_XXX() are now in a single patch
  - two patches on updating BadInstr and related registers
    are now merged, and execution logic improved
  - minor formatting corrections
  - rebased to the latest code

v2->v3:

  - added support for nanoMIPS-specifics in ELF headers
  - added support for CP0 Config0.WR bit
  - updated I7200 definition
  - improved indentation of some switch statements
  - slight reorganization of patches (splitting, order)
  - rebased to the latest code

v1->v2:

  - added DSP ASE support
  - added MT ASE support
  - added GDB XML support
  - order of patches changed
  - commit messages and patch title improved across the board
  - obsolete email addresses for authors and cosigners replaced
    with the right ones
  - some functions renamed to reflect better the documentation
  - some macros renamed to reflect better their nanoMIPS nature
  - streamlined formatting
  - some of other reviewer's comments addressed, but the majority
    was not; this is because the focus of this version was on
    completing the functionality as much as possible; remaining
    comments will be addressed in the subsequent versions of this
    series

This series of patches implements recently announced nanoMIPS on QEMU.
nanoMIPS is a variable length ISA containing 16, 32 and 48-bit wide
instructions. It is designed to be portable at assembly level with
other MIPS and microMIPS code, but contains a number of changes that
enhance code density and efficiency. The largest portion of patches
is nanoMIPS decoding engine.

For more information, please refer to the following link:

https://www.mips.com/products/architectures/nanomips/
Aleksandar Markovic (16):
  MAINTAINERS: Update target/mips maintainer's email addresses
  target/mips: Avoid case statements formulated by ranges - part 1
  target/mips: Mark switch fallthroughs with interpretable comments
  target/mips: Fix two instances of shadow variables
  target/mips: Update some CP0 registers bit definitions
  elf: Remove duplicate preprocessor constant definition
  elf: Add ELF flags for MIPS machine variants
  linux-user: Update MIPS syscall numbers up to kernel 4.18 headers
  qemu-doc: Amend MIPS-related items
  target/mips: Add preprocessor constants for nanoMIPS
  target/mips: Add placeholder and invocation of decode_nanomips_opc()
  target/mips: Add nanoMIPS decoding and extraction utilities
  elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too
  elf: Don't check FCR31_NAN2008 bit for nanoMIPS
  linux-user: Update syscall_defs.h header for nanoMIPS
  qemu-doc: Add nanoMIPS-related items

Aleksandar Rikalo (20):
  target/mips: Avoid case statements formulated by ranges - part 2
  target/mips: Add support for availability control via bit XNP
  target/mips: Add support for availability control via bit MT
  target/mips: Fix MT ASE instructions' availability control
  linux-user: Add preprocessor availability control to some syscalls
  target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
  elf: Add EM_NANOMIPS value as a valid one for e_machine field
  elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for
    MIPS
  elf: Add nanoMIPS specific variations in ELF header fields
  linux-user: Add syscall numbers for nanoMIPS
  linux-user: Add target_signal.h header for nanoMIPS
  linux-user: Add termbits.h header for nanoMIPS
  linux-user: Add target_fcntl.h header for nanoMIPS
  linux-user: Add sockbits.h header for nanoMIPS
  linux-user: Add target_syscall.h header for nanoMIPS
  linux-user: Add support for nanoMIPS signal trampoline
  linux-user: Amend support for sigaction() syscall for nanoMIPS
  linux-user: Add support for statx() syscall for all platforms
  linux-user: Add support for nanoMIPS core files
  linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh

Dimitrije Nikolic (5):
  linux-user: Add target_cpu.h header for nanoMIPS
  linux-user: Add target_structs.h header for nanoMIPS
  linux-user: Add target_elf.h header for nanoMIPS
  linux-user: Add signal.c for nanoMIPS
  linux-user: Add cpu_loop.c for nanoMIPS

James Hogan (5):
  target/mips: Implement emulation of nanoMIPS EXTW instruction
  target/mips: Adjust exception_resume_pc() for nanoMIPS
  target/mips: Adjust set_hflags_for_handler() for nanoMIPS
  target/mips: Adjust set_pc() for nanoMIPS
  gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub

Matthew Fortune (5):
  target/mips: Add emulation of nanoMIPS 16-bit save and restore
    instructions
  target/mips: Implement emulation of nanoMIPS ROTX instruction
  disas: Add support for microMIPS and nanoMIPS
  target/mips: Add handling of branch delay slots for nanoMIPS
  mips_malta: Add basic nanoMIPS boot code for Malta board

Paul Burton (1):
  mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader

Stefan Markovic (16):
  target/mips: Add CP0 BadInstrX register
  target/mips: Implement CP0 Config1.WR bit functionality
  target/mips: Add gen_op_addr_addi()
  target/mips: Add nanoMIPS DSP ASE opcodes
  target/mips: Implement MT ASE support for nanoMIPS
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 1
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 2
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 3
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 5
  target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
  target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS
  mips_malta: Fix semihosting argument passing for nanoMIPS bare metal
  target/mips: Add definition of nanoMIPS I7200 CPU
  linux-user: Add nanoMIPS linux user mode configuration support
  gdbstub: Add XML support for GDB for nanoMIPS

Yongbok Kim (19):
  target/mips: Don't update BadVAddr register in Debug Mode
  target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0
  target/mips: Add nanoMIPS base instruction set opcodes
  target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions
  target/mips: Add emulation of nanoMIPS 16-bit branch instructions
  target/mips: Add emulation of nanoMIPS 16-bit shift instructions
  target/mips: Add emulation of nanoMIPS 16-bit misc instructions
  target/mips: Add emulation of nanoMIPS 16-bit load and store
    instructions
  target/mips: Add emulation of nanoMIPS 16-bit logic instructions
  target/mips: Add emulation of some common nanoMIPS 32-bit instructions
  target/mips: Add emulation of nanoMIPS instructions MOVE.P and
    MOVE.PREV
  target/mips: Add emulation of nanoMIPS 48-bit instructions
  target/mips: Add emulation of nanoMIPS FP instructions
  target/mips: Add emulation of misc nanoMIPS instructions (pool32a0)
  target/mips: Add emulation of misc nanoMIPS instructions (pool32axf)
  target/mips: Add emulation of misc nanoMIPS instructions (p_lsx)
  target/mips: Add emulation of nanoMIPS 32-bit load and store
    instructions
  target/mips: Add emulation of nanoMIPS 32-bit branch instructions
  target/mips: Fix ERET/ERETNC behavior related to ADEL exception

 .mailmap                                |     7 +-
 MAINTAINERS                             |    12 +-
 configure                               |    13 +-
 default-configs/nanomips-linux-user.mak |     1 +
 disas/Makefile.objs                     |     1 +
 disas/mips.c                            |   358 +-
 disas/nanomips.cpp                      | 15752 ++++++++++++++++++++++++++++++
 disas/nanomips.h                        |  1208 +++
 gdb-xml/nanomips-cp0.xml                |    13 +
 gdb-xml/nanomips-cpu.xml                |    44 +
 gdb-xml/nanomips-dsp.xml                |    20 +
 gdb-xml/nanomips-fpu.xml                |    45 +
 gdb-xml/nanomips-linux.xml              |    20 +
 hw/mips/mips_malta.c                    |   212 +-
 include/disas/bfd.h                     |     1 +
 include/elf.h                           |    44 +-
 include/hw/elf_ops.h                    |     8 +
 linux-user/elfload.c                    |    12 +-
 linux-user/mips/cpu_loop.c              |    36 +-
 linux-user/mips/signal.c                |    36 +-
 linux-user/mips/syscall_nr.h            |     9 +
 linux-user/mips/termbits.h              |     4 +
 linux-user/mips64/syscall_nr.h          |    18 +
 linux-user/nanomips/cpu_loop.c          |     1 +
 linux-user/nanomips/signal.c            |     1 +
 linux-user/nanomips/sockbits.h          |     1 +
 linux-user/nanomips/syscall_nr.h        |   275 +
 linux-user/nanomips/target_cpu.h        |    21 +
 linux-user/nanomips/target_elf.h        |    14 +
 linux-user/nanomips/target_fcntl.h      |    38 +
 linux-user/nanomips/target_signal.h     |    22 +
 linux-user/nanomips/target_structs.h    |     1 +
 linux-user/nanomips/target_syscall.h    |    30 +
 linux-user/nanomips/termbits.h          |     1 +
 linux-user/strace.c                     |    14 +-
 linux-user/syscall.c                    |   150 +-
 linux-user/syscall_defs.h               |    95 +-
 qemu-doc.texi                           |    15 +-
 scripts/qemu-binfmt-conf.sh             |    16 +-
 target/mips/cpu.c                       |    12 +-
 target/mips/cpu.h                       |   164 +-
 target/mips/gdbstub.c                   |    13 +-
 target/mips/helper.c                    |    35 +-
 target/mips/helper.h                    |     2 +
 target/mips/internal.h                  |     9 +-
 target/mips/machine.c                   |     5 +-
 target/mips/mips-defs.h                 |     4 +
 target/mips/op_helper.c                 |   113 +-
 target/mips/translate.c                 |  4997 +++++++++-
 target/mips/translate_init.inc.c        |    39 +
 50 files changed, 23718 insertions(+), 244 deletions(-)
 create mode 100644 default-configs/nanomips-linux-user.mak
 create mode 100644 disas/nanomips.cpp
 create mode 100644 disas/nanomips.h
 create mode 100644 gdb-xml/nanomips-cp0.xml
 create mode 100644 gdb-xml/nanomips-cpu.xml
 create mode 100644 gdb-xml/nanomips-dsp.xml
 create mode 100644 gdb-xml/nanomips-fpu.xml
 create mode 100644 gdb-xml/nanomips-linux.xml
 create mode 100644 linux-user/nanomips/cpu_loop.c
 create mode 100644 linux-user/nanomips/signal.c
 create mode 100644 linux-user/nanomips/sockbits.h
 create mode 100644 linux-user/nanomips/syscall_nr.h
 create mode 100644 linux-user/nanomips/target_cpu.h
 create mode 100644 linux-user/nanomips/target_elf.h
 create mode 100644 linux-user/nanomips/target_fcntl.h
 create mode 100644 linux-user/nanomips/target_signal.h
 create mode 100644 linux-user/nanomips/target_structs.h
 create mode 100644 linux-user/nanomips/target_syscall.h
 create mode 100644 linux-user/nanomips/termbits.h

-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 01/87] MAINTAINERS: Update target/mips maintainer's email addresses
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 02/87] target/mips: Avoid case statements formulated by ranges - part 1 Aleksandar Markovic
                   ` (87 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Update email addresses of Aleksandar Markovic and Paul Burton in the
MAINTAINERS file. Also, add corresponding items in the .mailmap file.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 .mailmap    | 7 +++++--
 MAINTAINERS | 9 +++++----
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/.mailmap b/.mailmap
index 778a4d4..2c2b9b1 100644
--- a/.mailmap
+++ b/.mailmap
@@ -12,8 +12,11 @@ Fabrice Bellard <fabrice@bellard.org> bellard <bellard@c046a42c-6fe2-441c-8c8c-7
 James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
 Jocelyn Mayer <l_indien@magic.fr> j_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
 Paul Brook <paul@codesourcery.com> pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
-Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com>
-Paul Burton <paul.burton@mips.com> <paul@archlinuxmips.org>
+Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@mips.com>
+Aleksandar Markovic <amarkovic@wavecomp.com> <aleksandar.markovic@imgtec.com>
+Paul Burton <pburton@wavecomp.com> <paul.burton@mips.com>
+Paul Burton <pburton@wavecomp.com> <paul.burton@imgtec.com>
+Paul Burton <pburton@wavecomp.com> <paul@archlinuxmips.org>
 Thiemo Seufer <ths@networkno.de> ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
 malc <av1474@comtv.ru> malc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 666e936..7130807 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -187,7 +187,7 @@ F: disas/microblaze.c
 
 MIPS
 M: Aurelien Jarno <aurelien@aurel32.net>
-M: Aleksandar Markovic <aleksandar.markovic@mips.com>
+M: Aleksandar Markovic <amarkovic@wavecomp.com>
 S: Maintained
 F: target/mips/
 F: hw/mips/
@@ -718,7 +718,7 @@ S: Maintained
 F: hw/mips/mips_malta.c
 
 Mipssim
-M: Aleksandar Markovic <aleksandar.markovic@mips.com>
+M: Aleksandar Markovic <amarkovic@wavecomp.com>
 S: Odd Fixes
 F: hw/mips/mips_mipssim.c
 F: hw/net/mipsnet.c
@@ -729,14 +729,15 @@ S: Maintained
 F: hw/mips/mips_r4k.c
 
 Fulong 2E
-M: Aleksandar Markovic <aleksandar.markovic@mips.com>
+M: Aleksandar Markovic <amarkovic@wavecomp.com>
 S: Odd Fixes
 F: hw/mips/mips_fulong2e.c
 F: hw/isa/vt82c686.c
+
 F: include/hw/isa/vt82c686.h
 
 Boston
-M: Paul Burton <paul.burton@mips.com>
+M: Paul Burton <pburton@wavecomp.com>
 S: Maintained
 F: hw/core/loader-fit.c
 F: hw/mips/boston.c
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 02/87] target/mips: Avoid case statements formulated by ranges - part 1
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 01/87] MAINTAINERS: Update target/mips maintainer's email addresses Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2 Aleksandar Markovic
                   ` (86 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Remove "range style" case statements to make code analysis easier.

This is needed also for some upcoming nanoMIPS-related refactorings.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/translate.c | 249 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 200 insertions(+), 49 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 20b43c0..051dda5 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -5494,7 +5494,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 18:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_1e0i(mfc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -5504,7 +5511,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 19:
         switch (sel) {
-        case 0 ...7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_1e0i(mfc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -5630,7 +5644,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 27:
         switch (sel) {
-        case 0 ... 3:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
             tcg_gen_movi_tl(arg, 0); /* unimplemented */
             rn = "CacheErr";
             break;
@@ -5701,7 +5718,12 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
-        case 2 ... 7:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             CP0_CHECK(ctx->kscrexist & (1 << sel));
             tcg_gen_ld_tl(arg, cpu_env,
                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
@@ -6167,7 +6189,14 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 18:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_0e1i(mtc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -6177,7 +6206,14 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 19:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_0e1i(mtc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -6315,7 +6351,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 27:
         switch (sel) {
-        case 0 ... 3:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
             /* ignored */
             rn = "CacheErr";
             break;
@@ -6381,7 +6420,12 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
-        case 2 ... 7:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             CP0_CHECK(ctx->kscrexist & (1 << sel));
             tcg_gen_st_tl(arg, cpu_env,
                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
@@ -6842,7 +6886,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 18:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -6852,7 +6903,14 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 19:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_1e0i(mfc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -6975,7 +7033,10 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     case 27:
         switch (sel) {
         /* ignored */
-        case 0 ... 3:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
             tcg_gen_movi_tl(arg, 0); /* unimplemented */
             rn = "CacheErr";
             break;
@@ -7040,7 +7101,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
-        case 2 ... 7:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             CP0_CHECK(ctx->kscrexist & (1 << sel));
             tcg_gen_ld_tl(arg, cpu_env,
                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
@@ -7497,7 +7563,14 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 18:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_0e1i(mtc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -7507,7 +7580,14 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 19:
         switch (sel) {
-        case 0 ... 7:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             gen_helper_0e1i(mtc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -7641,7 +7721,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         break;
     case 27:
         switch (sel) {
-        case 0 ... 3:
+        case 0:
+        case 1:
+        case 2:
+        case 3:
             /* ignored */
             rn = "CacheErr";
             break;
@@ -7707,7 +7790,12 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
             rn = "DESAVE";
             break;
-        case 2 ... 7:
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
             CP0_CHECK(ctx->kscrexist & (1 << sel));
             tcg_gen_st_tl(arg, cpu_env,
                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
@@ -7843,7 +7931,14 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
             break;
         case 16:
             switch (sel) {
-            case 0 ... 7:
+            case 0:
+            case 1:
+            case 2:
+            case 3:
+            case 4:
+            case 5:
+            case 6:
+            case 7:
                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
                 break;
             default:
@@ -17231,7 +17326,10 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
     case OPC_LSA:
         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
         break;
-    case OPC_MULT ... OPC_DIVU:
+    case OPC_MULT:
+    case OPC_MULTU:
+    case OPC_DIV:
+    case OPC_DIVU:
         op2 = MASK_R6_MULDIV(ctx->opcode);
         switch (op2) {
         case R6_OPC_MUL:
@@ -17291,7 +17389,11 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
             generate_exception_end(ctx, EXCP_RI);
         }
         break;
-    case OPC_DMULT ... OPC_DDIVU:
+    case OPC_DMULT:
+    case OPC_DMULTU:
+    case OPC_DDIV:
+    case OPC_DDIVU:
+
         op2 = MASK_R6_MULDIV(ctx->opcode);
         switch (op2) {
         case R6_OPC_DMUL:
@@ -17370,7 +17472,10 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
         gen_muldiv(ctx, op1, 0, rs, rt);
         break;
 #if defined(TARGET_MIPS64)
-    case OPC_DMULT ... OPC_DDIVU:
+    case OPC_DMULT:
+    case OPC_DMULTU:
+    case OPC_DDIV:
+    case OPC_DDIVU:
         check_insn(ctx, ISA_MIPS3);
         check_mips_64(ctx);
         gen_muldiv(ctx, op1, 0, rs, rt);
@@ -17437,7 +17542,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
             break;
         }
         break;
-    case OPC_ADD ... OPC_SUBU:
+    case OPC_ADD:
+    case OPC_ADDU:
+    case OPC_SUB:
+    case OPC_SUBU:
         gen_arith(ctx, op1, rd, rs, rt);
         break;
     case OPC_SLLV:         /* Shifts */
@@ -17473,7 +17581,11 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
     case OPC_JALR:
         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
         break;
-    case OPC_TGE ... OPC_TEQ: /* Traps */
+    case OPC_TGE: /* Traps */
+    case OPC_TGEU:
+    case OPC_TLT:
+    case OPC_TLTU:
+    case OPC_TEQ:
     case OPC_TNE:
         check_insn(ctx, ISA_MIPS2);
         gen_trap(ctx, op1, rs, rt, -1);
@@ -17549,7 +17661,10 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
             break;
         }
         break;
-    case OPC_DADD ... OPC_DSUBU:
+    case OPC_DADD:
+    case OPC_DADDU:
+    case OPC_DSUB:
+    case OPC_DSUBU:
         check_insn(ctx, ISA_MIPS3);
         check_mips_64(ctx);
         gen_arith(ctx, op1, rd, rs, rt);
@@ -17607,8 +17722,10 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
 
     op1 = MASK_SPECIAL2(ctx->opcode);
     switch (op1) {
-    case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
-    case OPC_MSUB ... OPC_MSUBU:
+    case OPC_MADD: /* Multiply and add/sub */
+    case OPC_MADDU:
+    case OPC_MSUB:
+    case OPC_MSUBU:
         check_insn(ctx, ISA_MIPS32);
         gen_muldiv(ctx, op1, rd & 3, rs, rt);
         break;
@@ -17705,7 +17822,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
             }
             op2 = MASK_BSHFL(ctx->opcode);
             switch (op2) {
-            case OPC_ALIGN ... OPC_ALIGN_END:
+            case OPC_ALIGN:
+            case OPC_ALIGN_END:
                 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
                 break;
             case OPC_BITSWAP:
@@ -17730,7 +17848,8 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
             }
             op2 = MASK_DBSHFL(ctx->opcode);
             switch (op2) {
-            case OPC_DALIGN ... OPC_DALIGN_END:
+            case OPC_DALIGN:
+            case OPC_DALIGN_END:
                 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
                 break;
             case OPC_DBITSWAP:
@@ -17759,9 +17878,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
 
     op1 = MASK_SPECIAL3(ctx->opcode);
     switch (op1) {
-    case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
-    case OPC_MOD_G_2E ... OPC_MODU_G_2E:
-    case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
+    case OPC_DIV_G_2E:
+    case OPC_DIVU_G_2E:
+    case OPC_MOD_G_2E:
+    case OPC_MODU_G_2E:
+    case OPC_MULT_G_2E:
+    case OPC_MULTU_G_2E:
         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
          * the same mask and op1. */
         if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
@@ -18025,9 +18147,12 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
 #if defined(TARGET_MIPS64)
-    case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
-    case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
-    case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
+    case OPC_DDIV_G_2E:
+    case OPC_DDIVU_G_2E:
+    case OPC_DMULT_G_2E:
+    case OPC_DMULTU_G_2E:
+    case OPC_DMOD_G_2E:
+    case OPC_DMODU_G_2E:
         check_insn(ctx, INSN_LOONGSON2E);
         gen_loongson_integer(ctx, op1, rd, rs, rt);
         break;
@@ -18289,18 +18414,25 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
      */
     if (ctx->eva) {
         switch (op1) {
-        case OPC_LWLE ... OPC_LWRE:
+        case OPC_LWLE:
+        case OPC_LWRE:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             /* fall through */
-        case OPC_LBUE ... OPC_LHUE:
-        case OPC_LBE ... OPC_LWE:
+        case OPC_LBUE:
+        case OPC_LHUE:
+        case OPC_LBE:
+        case OPC_LHE:
+        case OPC_LLE:
+        case OPC_LWE:
             check_cp0_enabled(ctx);
             gen_ld(ctx, op1, rt, rs, imm);
             return;
-        case OPC_SWLE ... OPC_SWRE:
+        case OPC_SWLE:
+        case OPC_SWRE:
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
             /* fall through */
-        case OPC_SBE ... OPC_SHE:
+        case OPC_SBE:
+        case OPC_SHE:
         case OPC_SWE:
             check_cp0_enabled(ctx);
             gen_st(ctx, op1, rt, rs, imm);
@@ -18332,7 +18464,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
     case OPC_BSHFL:
         op2 = MASK_BSHFL(ctx->opcode);
         switch (op2) {
-        case OPC_ALIGN ... OPC_ALIGN_END:
+        case OPC_ALIGN:
+        case OPC_ALIGN_END:
         case OPC_BITSWAP:
             check_insn(ctx, ISA_MIPS32R6);
             decode_opc_special3_r6(env, ctx);
@@ -18344,8 +18477,12 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
 #if defined(TARGET_MIPS64)
-    case OPC_DEXTM ... OPC_DEXT:
-    case OPC_DINSM ... OPC_DINS:
+    case OPC_DEXTM:
+    case OPC_DEXTU:
+    case OPC_DEXT:
+    case OPC_DINSM:
+    case OPC_DINSU:
+    case OPC_DINS:
         check_insn(ctx, ISA_MIPS64R2);
         check_mips_64(ctx);
         gen_bitops(ctx, op1, rt, rs, sa, rd);
@@ -18353,7 +18490,8 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
     case OPC_DBSHFL:
         op2 = MASK_DBSHFL(ctx->opcode);
         switch (op2) {
-        case OPC_DALIGN ... OPC_DALIGN_END:
+        case OPC_DALIGN:
+        case OPC_DALIGN_END:
         case OPC_DBITSWAP:
             check_insn(ctx, ISA_MIPS32R6);
             decode_opc_special3_r6(env, ctx);
@@ -19584,7 +19722,12 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
             }
             break;
-        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
+        case OPC_TGEI: /* REGIMM traps */
+        case OPC_TGEIU:
+        case OPC_TLTI:
+        case OPC_TLTIU:
+        case OPC_TEQI:
+
         case OPC_TNEI:
             check_insn(ctx, ISA_MIPS2);
             check_insn_opc_removed(ctx, ISA_MIPS32R6);
@@ -19759,7 +19902,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
     case OPC_XORI:
          gen_logic_imm(ctx, op, rt, rs, imm);
          break;
-    case OPC_J ... OPC_JAL: /* Jump */
+    case OPC_J: /* Jump */
+    case OPC_JAL:
          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
          break;
@@ -19826,15 +19970,20 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
     case OPC_LWR:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
          /* Fallthrough */
-    case OPC_LB ... OPC_LH:
-    case OPC_LW ... OPC_LHU:
+    case OPC_LB:
+    case OPC_LH:
+    case OPC_LW:
+    case OPC_LWPC:
+    case OPC_LBU:
+    case OPC_LHU:
          gen_ld(ctx, op, rt, rs, imm);
          break;
     case OPC_SWL:
     case OPC_SWR:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
         /* fall through */
-    case OPC_SB ... OPC_SH:
+    case OPC_SB:
+    case OPC_SH:
     case OPC_SW:
          gen_st(ctx, op, rt, rs, imm);
          break;
@@ -20105,7 +20254,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
 
 #if defined(TARGET_MIPS64)
     /* MIPS64 opcodes */
-    case OPC_LDL ... OPC_LDR:
+    case OPC_LDL:
+    case OPC_LDR:
     case OPC_LLD:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
         /* fall through */
@@ -20115,7 +20265,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         check_mips_64(ctx);
         gen_ld(ctx, op, rt, rs, imm);
         break;
-    case OPC_SDL ... OPC_SDR:
+    case OPC_SDL:
+    case OPC_SDR:
         check_insn_opc_removed(ctx, ISA_MIPS32R6);
         /* fall through */
     case OPC_SD:
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 01/87] MAINTAINERS: Update target/mips maintainer's email addresses Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 02/87] target/mips: Avoid case statements formulated by ranges - part 1 Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-14 11:13   ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
                   ` (85 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Remove "range style" case statements to make code analysis easier.
This patch handles cases when the values in the range in question
were not properly defined.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <amarkovic@wavecomp.com>
---
 target/mips/translate.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 71 insertions(+), 7 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 051dda5..b944ea2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -902,8 +902,21 @@ enum {
     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
     OPC_C0       = (0x10 << 21) | OPC_CP0,
-    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
-    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
+    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
+    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
+    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
+    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
+    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
+    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
+    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
+    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
+    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
+    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
+    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
+    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
+    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
+    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
+    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 };
 
 /* MFMC0 opcodes */
@@ -12490,10 +12503,22 @@ enum {
 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
 enum {
     ADDIUPC_00 = 0x00,
+    ADDIUPC_01 = 0x01,
+    ADDIUPC_02 = 0x02,
+    ADDIUPC_03 = 0x03,
+    ADDIUPC_04 = 0x04,
+    ADDIUPC_05 = 0x05,
+    ADDIUPC_06 = 0x06,
     ADDIUPC_07 = 0x07,
     AUIPC = 0x1e,
     ALUIPC = 0x1f,
     LWPC_08 = 0x08,
+    LWPC_09 = 0x09,
+    LWPC_0A = 0x0A,
+    LWPC_0B = 0x0B,
+    LWPC_0C = 0x0C,
+    LWPC_0D = 0x0D,
+    LWPC_0E = 0x0E,
     LWPC_0F = 0x0F,
 };
 
@@ -12928,12 +12953,16 @@ enum {
     R6_LWM16    = 0x02,
     R6_JRC16    = 0x03,
     MOVEP       = 0x04,
+    MOVEP_05    = 0x05,
+    MOVEP_06    = 0x06,
     MOVEP_07    = 0x07,
     R6_XOR16    = 0x08,
     R6_OR16     = 0x09,
     R6_SWM16    = 0x0a,
     JALRC16     = 0x0b,
     MOVEP_0C    = 0x0c,
+    MOVEP_0D    = 0x0d,
+    MOVEP_0E    = 0x0e,
     MOVEP_0F    = 0x0f,
     JRCADDIUSP  = 0x13,
     R6_BREAK16  = 0x1b,
@@ -13251,8 +13280,14 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
         }
         break;
-    case MOVEP ... MOVEP_07:
-    case MOVEP_0C ... MOVEP_0F:
+    case MOVEP:
+    case MOVEP_05:
+    case MOVEP_06:
+    case MOVEP_07:
+    case MOVEP_0C:
+    case MOVEP_0D:
+    case MOVEP_0E:
+    case MOVEP_0F:
         {
             int enc_dest = uMIPS_RD(ctx->opcode);
             int enc_rt = uMIPS_RS2(ctx->opcode);
@@ -15230,7 +15265,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         if (ctx->insn_flags & ISA_MIPS32R6) {
             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
             switch ((ctx->opcode >> 16) & 0x1f) {
-            case ADDIUPC_00 ... ADDIUPC_07:
+            case ADDIUPC_00:
+            case ADDIUPC_01:
+            case ADDIUPC_02:
+            case ADDIUPC_03:
+            case ADDIUPC_04:
+            case ADDIUPC_05:
+            case ADDIUPC_06:
+            case ADDIUPC_07:
                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
                 break;
             case AUIPC:
@@ -15239,7 +15281,14 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             case ALUIPC:
                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
                 break;
-            case LWPC_08 ... LWPC_0F:
+            case LWPC_08:
+            case LWPC_09:
+            case LWPC_0A:
+            case LWPC_0B:
+            case LWPC_0C:
+            case LWPC_0D:
+            case LWPC_0E:
+            case LWPC_0F:
                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
                 break;
             default:
@@ -19790,7 +19839,22 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
             gen_cp0(env, ctx, op1, rt, rd);
 #endif /* !CONFIG_USER_ONLY */
             break;
-        case OPC_C0_FIRST ... OPC_C0_LAST:
+        case OPC_C0:
+        case OPC_C0_1:
+        case OPC_C0_2:
+        case OPC_C0_3:
+        case OPC_C0_4:
+        case OPC_C0_5:
+        case OPC_C0_6:
+        case OPC_C0_7:
+        case OPC_C0_8:
+        case OPC_C0_9:
+        case OPC_C0_A:
+        case OPC_C0_B:
+        case OPC_C0_C:
+        case OPC_C0_D:
+        case OPC_C0_E:
+        case OPC_C0_F:
 #ifndef CONFIG_USER_ONLY
             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
 #endif /* !CONFIG_USER_ONLY */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (2 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2 Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2019-07-07 20:26   ` [Qemu-devel] Handling of fall through code (was: " Stefan Weil
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 05/87] target/mips: Fix two instances of shadow variables Aleksandar Markovic
                   ` (84 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Mark switch fallthroughs with comments, in cases fallthroughs
are intentional.

The comments "/* fall through */" are interpreted by compilers and
other tools, and they will not issue warnings in such cases. For gcc,
the warning is turnend on by -Wimplicit-fallthrough. With this patch,
there will be no such warnings in target/mips directory. If such
warning appears in future, it should be checked if it is intentional,
and, if yes, marked with a comment similar to those from this patch.

The comment must be just before next "case", otherwise gcc won't
understand it.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index b944ea2..3dd66b6 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -14290,8 +14290,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         case SDP:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
-            /* Fallthrough */
 #endif
+            /* fall through */
         case LWP:
         case SWP:
             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
@@ -14301,8 +14301,8 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         case SDM:
             check_insn(ctx, ISA_MIPS3);
             check_mips_64(ctx);
-            /* Fallthrough */
 #endif
+            /* fall through */
         case LWM32:
         case SWM32:
             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
@@ -20087,6 +20087,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         case OPC_MTHC1:
             check_cp1_enabled(ctx);
             check_insn(ctx, ISA_MIPS32R2);
+            /* fall through */
         case OPC_MFC1:
         case OPC_CFC1:
         case OPC_MTC1:
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 05/87] target/mips: Fix two instances of shadow variables
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (3 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 06/87] target/mips: Update some CP0 registers bit definitions Aleksandar Markovic
                   ` (83 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Fix two instances of shadow variables. This cleans up entire file
translate.c from shadow variables.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 3dd66b6..2b70d1b 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -13276,7 +13276,7 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
         } else {
             /* JRC16 */
-            int rs = extract32(ctx->opcode, 5, 5);
+            rs = extract32(ctx->opcode, 5, 5);
             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
         }
         break;
@@ -15298,7 +15298,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
         } else {
             /* ADDIUPC */
             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
-            int offset = SIMM(ctx->opcode, 0, 23) << 2;
+            offset = SIMM(ctx->opcode, 0, 23) << 2;
 
             gen_addiupc(ctx, reg, offset, 0, 0);
         }
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 06/87] target/mips: Update some CP0 registers bit definitions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (4 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 05/87] target/mips: Fix two instances of shadow variables Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 07/87] target/mips: Add CP0 BadInstrX register Aleksandar Markovic
                   ` (82 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Update CP0 registers Config0, Config1, Config2, Config3,
Config4, and Config5 bit definitions.

Some of these bits will be utilized by upcoming nanoMIPS changes.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/cpu.h | 157 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 88 insertions(+), 69 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index cfe1735..77c638c 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -388,26 +388,27 @@ struct CPUMIPSState {
     target_ulong CP0_CMGCRBase;
     int32_t CP0_Config0;
 #define CP0C0_M    31
-#define CP0C0_K23  28
-#define CP0C0_KU   25
+#define CP0C0_K23  28    /* 30..28 */
+#define CP0C0_KU   25    /* 27..25 */
 #define CP0C0_MDU  20
 #define CP0C0_MM   18
 #define CP0C0_BM   16
+#define CP0C0_Impl 16    /* 24..16 */
 #define CP0C0_BE   15
-#define CP0C0_AT   13
-#define CP0C0_AR   10
-#define CP0C0_MT   7
+#define CP0C0_AT   13    /* 14..13 */
+#define CP0C0_AR   10    /* 12..10 */
+#define CP0C0_MT   7     /*  9..7  */
 #define CP0C0_VI   3
-#define CP0C0_K0   0
+#define CP0C0_K0   0     /*  2..0  */
     int32_t CP0_Config1;
 #define CP0C1_M    31
-#define CP0C1_MMU  25
-#define CP0C1_IS   22
-#define CP0C1_IL   19
-#define CP0C1_IA   16
-#define CP0C1_DS   13
-#define CP0C1_DL   10
-#define CP0C1_DA   7
+#define CP0C1_MMU  25    /* 30..25 */
+#define CP0C1_IS   22    /* 24..22 */
+#define CP0C1_IL   19    /* 21..19 */
+#define CP0C1_IA   16    /* 18..16 */
+#define CP0C1_DS   13    /* 15..13 */
+#define CP0C1_DL   10    /* 12..10 */
+#define CP0C1_DA   7     /*  9..7  */
 #define CP0C1_C2   6
 #define CP0C1_MD   5
 #define CP0C1_PC   4
@@ -417,67 +418,85 @@ struct CPUMIPSState {
 #define CP0C1_FP   0
     int32_t CP0_Config2;
 #define CP0C2_M    31
-#define CP0C2_TU   28
-#define CP0C2_TS   24
-#define CP0C2_TL   20
-#define CP0C2_TA   16
-#define CP0C2_SU   12
-#define CP0C2_SS   8
-#define CP0C2_SL   4
-#define CP0C2_SA   0
+#define CP0C2_TU   28    /* 30..28 */
+#define CP0C2_TS   24    /* 27..24 */
+#define CP0C2_TL   20    /* 23..20 */
+#define CP0C2_TA   16    /* 19..16 */
+#define CP0C2_SU   12    /* 15..12 */
+#define CP0C2_SS   8     /* 11..8  */
+#define CP0C2_SL   4     /*  7..4  */
+#define CP0C2_SA   0     /*  3..0  */
     int32_t CP0_Config3;
-#define CP0C3_M    31
-#define CP0C3_BPG  30
-#define CP0C3_CMGCR 29
-#define CP0C3_MSAP  28
-#define CP0C3_BP 27
-#define CP0C3_BI 26
-#define CP0C3_SC 25
-#define CP0C3_IPLW 21
-#define CP0C3_MMAR 18
-#define CP0C3_MCU  17
-#define CP0C3_ISA_ON_EXC 16
-#define CP0C3_ISA  14
-#define CP0C3_ULRI 13
-#define CP0C3_RXI  12
-#define CP0C3_DSP2P 11
-#define CP0C3_DSPP 10
-#define CP0C3_LPA  7
-#define CP0C3_VEIC 6
-#define CP0C3_VInt 5
-#define CP0C3_SP   4
-#define CP0C3_CDMM 3
-#define CP0C3_MT   2
-#define CP0C3_SM   1
-#define CP0C3_TL   0
+#define CP0C3_M            31
+#define CP0C3_BPG          30
+#define CP0C3_CMGCR        29
+#define CP0C3_MSAP         28
+#define CP0C3_BP           27
+#define CP0C3_BI           26
+#define CP0C3_SC           25
+#define CP0C3_PW           24
+#define CP0C3_VZ           23
+#define CP0C3_IPLV         21    /* 22..21 */
+#define CP0C3_MMAR         18    /* 20..18 */
+#define CP0C3_MCU          17
+#define CP0C3_ISA_ON_EXC   16
+#define CP0C3_ISA          14    /* 15..14 */
+#define CP0C3_ULRI         13
+#define CP0C3_RXI          12
+#define CP0C3_DSP2P        11
+#define CP0C3_DSPP         10
+#define CP0C3_CTXTC        9
+#define CP0C3_ITL          8
+#define CP0C3_LPA          7
+#define CP0C3_VEIC         6
+#define CP0C3_VInt         5
+#define CP0C3_SP           4
+#define CP0C3_CDMM         3
+#define CP0C3_MT           2
+#define CP0C3_SM           1
+#define CP0C3_TL           0
     int32_t CP0_Config4;
     int32_t CP0_Config4_rw_bitmask;
-#define CP0C4_M    31
-#define CP0C4_IE   29
-#define CP0C4_AE   28
-#define CP0C4_KScrExist 16
-#define CP0C4_MMUExtDef 14
-#define CP0C4_FTLBPageSize 8
-#define CP0C4_FTLBWays 4
-#define CP0C4_FTLBSets 0
-#define CP0C4_MMUSizeExt 0
+#define CP0C4_M            31
+#define CP0C4_IE           29    /* 30..29 */
+#define CP0C4_AE           28
+#define CP0C4_VTLBSizeExt  24    /* 27..24 */
+#define CP0C4_KScrExist    16
+#define CP0C4_MMUExtDef    14
+#define CP0C4_FTLBPageSize 8     /* 12..8  */
+/* bit layout if MMUExtDef=1 */
+#define CP0C4_MMUSizeExt   0     /*  7..0  */
+/* bit layout if MMUExtDef=2 */
+#define CP0C4_FTLBWays     4     /*  7..4  */
+#define CP0C4_FTLBSets     0     /*  3..0  */
     int32_t CP0_Config5;
     int32_t CP0_Config5_rw_bitmask;
-#define CP0C5_M          31
-#define CP0C5_K          30
-#define CP0C5_CV         29
-#define CP0C5_EVA        28
-#define CP0C5_MSAEn      27
-#define CP0C5_XNP        13
-#define CP0C5_UFE        9
-#define CP0C5_FRE        8
-#define CP0C5_VP         7
-#define CP0C5_SBRI       6
-#define CP0C5_MVH        5
-#define CP0C5_LLB        4
-#define CP0C5_MRP        3
-#define CP0C5_UFR        2
-#define CP0C5_NFExists   0
+#define CP0C5_M            31
+#define CP0C5_K            30
+#define CP0C5_CV           29
+#define CP0C5_EVA          28
+#define CP0C5_MSAEn        27
+#define CP0C5_PMJ          23    /* 25..23 */
+#define CP0C5_WR2          22
+#define CP0C5_NMS          21
+#define CP0C5_ULS          20
+#define CP0C5_XPA          19
+#define CP0C5_CRCP         18
+#define CP0C5_MI           17
+#define CP0C5_GI           15    /* 16..15 */
+#define CP0C5_CA2          14
+#define CP0C5_XNP          13
+#define CP0C5_DEC          11
+#define CP0C5_L2C          10
+#define CP0C5_UFE          9
+#define CP0C5_FRE          8
+#define CP0C5_VP           7
+#define CP0C5_SBRI         6
+#define CP0C5_MVH          5
+#define CP0C5_LLB          4
+#define CP0C5_MRP          3
+#define CP0C5_UFR          2
+#define CP0C5_NFExists     0
     int32_t CP0_Config6;
     int32_t CP0_Config7;
     uint64_t CP0_MAAR[MIPS_MAAR_MAX];
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 07/87] target/mips: Add CP0 BadInstrX register
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (5 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 06/87] target/mips: Update some CP0 registers bit definitions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP Aleksandar Markovic
                   ` (81 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add CP0 BadInstrX register. This register will be used in nanoMIPS.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/cpu.h       |  1 +
 target/mips/machine.c   |  5 +++--
 target/mips/translate.c | 22 +++++++++++++++++++++-
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 77c638c..009202c 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -323,6 +323,7 @@ struct CPUMIPSState {
     target_ulong CP0_BadVAddr;
     uint32_t CP0_BadInstr;
     uint32_t CP0_BadInstrP;
+    uint32_t CP0_BadInstrX;
     int32_t CP0_Count;
     target_ulong CP0_EntryHi;
 #define CP0EnHi_EHINV 10
diff --git a/target/mips/machine.c b/target/mips/machine.c
index 20100d5..5ba78ac 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -212,8 +212,8 @@ const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
-    .version_id = 10,
-    .minimum_version_id = 10,
+    .version_id = 11,
+    .minimum_version_id = 11,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         /* Active TC */
@@ -266,6 +266,7 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_UINTTL(env.CP0_BadVAddr, MIPSCPU),
         VMSTATE_UINT32(env.CP0_BadInstr, MIPSCPU),
         VMSTATE_UINT32(env.CP0_BadInstrP, MIPSCPU),
+        VMSTATE_UINT32(env.CP0_BadInstrX, MIPSCPU),
         VMSTATE_INT32(env.CP0_Count, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_EntryHi, MIPSCPU),
         VMSTATE_INT32(env.CP0_Compare, MIPSCPU),
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 2b70d1b..ae3aaab 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -5328,7 +5328,13 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
             rn = "BadInstrP";
             break;
-        default:
+        case 3:
+            CP0_CHECK(ctx->bi);
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
+            tcg_gen_andi_tl(arg, arg, ~0xffff);
+            rn = "BadInstrX";
+            break;
+       default:
             goto cp0_unimplemented;
         }
         break;
@@ -6019,6 +6025,10 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             /* ignored */
             rn = "BadInstrP";
             break;
+        case 3:
+            /* ignored */
+            rn = "BadInstrX";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -6724,6 +6734,12 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
             rn = "BadInstrP";
             break;
+        case 3:
+            CP0_CHECK(ctx->bi);
+            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
+            tcg_gen_andi_tl(arg, arg, ~0xffff);
+            rn = "BadInstrX";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -7398,6 +7414,10 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             /* ignored */
             rn = "BadInstrP";
             break;
+        case 3:
+            /* ignored */
+            rn = "BadInstrX";
+            break;
         default:
             goto cp0_unimplemented;
         }
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (6 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 07/87] target/mips: Add CP0 BadInstrX register Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-14 12:23   ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT Aleksandar Markovic
                   ` (80 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add a field in hflags for XNP bit, and a function check_xnp().

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/cpu.h       |  3 ++-
 target/mips/internal.h  |  5 ++++-
 target/mips/translate.c | 12 ++++++++++++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 009202c..02ea91e 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -554,7 +554,7 @@ struct CPUMIPSState {
 #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0x1F5807FF
+#define MIPS_HFLAG_TMASK  0x3F5807FF
 #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
     /* The KSU flags must be the lowest bits in hflags. The flag order
        must be the same as defined for CP0 Status. This allows to use
@@ -605,6 +605,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_ELPA  0x4000000
 #define MIPS_HFLAG_ITC_CACHE  0x8000000 /* CACHE instr. operates on ITC tag */
 #define MIPS_HFLAG_ERL   0x10000000 /* error level flag */
+#define MIPS_HFLAG_XNP   0x20000000
     target_ulong btarget;        /* Jump / branch target               */
     target_ulong bcond;          /* Branch condition (if needed)       */
 
diff --git a/target/mips/internal.h b/target/mips/internal.h
index e41051f..97485da 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -308,7 +308,7 @@ static inline void compute_hflags(CPUMIPSState *env)
                      MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
                      MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
                      MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
-                     MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL);
+                     MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL | MIPS_HFLAG_XNP);
     if (env->CP0_Status & (1 << CP0St_ERL)) {
         env->hflags |= MIPS_HFLAG_ERL;
     }
@@ -402,6 +402,9 @@ static inline void compute_hflags(CPUMIPSState *env)
             env->hflags |= MIPS_HFLAG_ELPA;
         }
     }
+    if (env->CP0_Config5 & (1 << CP0C5_XNP)) {
+        env->hflags |= MIPS_HFLAG_XNP;
+    }
 }
 
 void cpu_mips_tlb_flush(CPUMIPSState *env);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index ae3aaab..35342e2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1902,6 +1902,18 @@ static inline void check_mvh(DisasContext *ctx)
 }
 #endif
 
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 XNP bit is set.
+ */
+static inline void check_xnp(DisasContext *ctx)
+{
+    if (unlikely(ctx->hflags & MIPS_HFLAG_XNP)) {
+        generate_exception_end(ctx, EXCP_RI);
+    }
+}
+
+
 /* Define small wrappers for gen_load_fpr* so that we have a uniform
    calling interface for 32 and 64-bit FPRs.  No sense in changing
    all callers for gen_load_fpr32 when we need the CTX parameter for
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (7 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 18:13   ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control Aleksandar Markovic
                   ` (79 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add a field in hflags for MT bit, and functions check_mt() and
check_cp0_mt().

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/cpu.h       |  3 ++-
 target/mips/internal.h  |  6 +++++-
 target/mips/translate.c | 29 +++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 02ea91e..8a8782b 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -554,7 +554,7 @@ struct CPUMIPSState {
 #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0x3F5807FF
+#define MIPS_HFLAG_TMASK  0x7F5807FF
 #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
     /* The KSU flags must be the lowest bits in hflags. The flag order
        must be the same as defined for CP0 Status. This allows to use
@@ -606,6 +606,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_ITC_CACHE  0x8000000 /* CACHE instr. operates on ITC tag */
 #define MIPS_HFLAG_ERL   0x10000000 /* error level flag */
 #define MIPS_HFLAG_XNP   0x20000000
+#define MIPS_HFLAG_MT    0x40000000
     target_ulong btarget;        /* Jump / branch target               */
     target_ulong bcond;          /* Branch condition (if needed)       */
 
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 97485da..c0e447b 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -308,7 +308,8 @@ static inline void compute_hflags(CPUMIPSState *env)
                      MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
                      MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
                      MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
-                     MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL | MIPS_HFLAG_XNP);
+                     MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL | MIPS_HFLAG_XNP |
+                     MIPS_HFLAG_MT);
     if (env->CP0_Status & (1 << CP0St_ERL)) {
         env->hflags |= MIPS_HFLAG_ERL;
     }
@@ -405,6 +406,9 @@ static inline void compute_hflags(CPUMIPSState *env)
     if (env->CP0_Config5 & (1 << CP0C5_XNP)) {
         env->hflags |= MIPS_HFLAG_XNP;
     }
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        env->hflags |= MIPS_HFLAG_MT;
+    }
 }
 
 void cpu_mips_tlb_flush(CPUMIPSState *env);
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 35342e2..b73f434 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1913,6 +1913,35 @@ static inline void check_xnp(DisasContext *ctx)
     }
 }
 
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 MT bit is NOT set.
+ */
+static inline void check_mt(DisasContext *ctx)
+{
+    if (unlikely(!(ctx->hflags & MIPS_HFLAG_MT))) {
+        generate_exception_end(ctx, EXCP_RI);
+    }
+}
+
+/*
+ * This code generates a "coprocessor unusable" if CP) is not
+ * available, and, if that is not the case, generates a "reserved
+ * instruction" exception if the Config5 MT bit is NOT set.
+ * This is used for some of instructions in MT ASE.
+ */
+static inline void check_cp0_mt(DisasContext *ctx)
+{
+    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
+        generate_exception_err(ctx, EXCP_CpU, 0);
+    } else {
+        if (unlikely(!(ctx->hflags & MIPS_HFLAG_MT))) {
+            generate_exception_err(ctx, EXCP_RI, 0);
+        }
+    }
+}
+
+
 
 /* Define small wrappers for gen_load_fpr* so that we have a uniform
    calling interface for 32 and 64-bit FPRs.  No sense in changing
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (8 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 18:23   ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 11/87] target/mips: Implement CP0 Config1.WR bit functionality Aleksandar Markovic
                   ` (78 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Use bits from configuration registers for availability control
of MT ASE instructions, rather than only ISA_MT bit in insn_flags.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index b73f434..af9714b 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -8393,7 +8393,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
         opn = "mthc0";
         break;
     case OPC_MFTR:
-        check_insn(ctx, ASE_MT);
+        check_cp0_enabled(ctx);
         if (rd == 0) {
             /* Treat as NOP. */
             return;
@@ -8403,7 +8403,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
         opn = "mftr";
         break;
     case OPC_MTTR:
-        check_insn(ctx, ASE_MT);
+        check_cp0_enabled(ctx);
         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
         opn = "mttr";
@@ -18619,7 +18619,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
         break;
     case OPC_FORK:
-        check_insn(ctx, ASE_MT);
+        check_mt(ctx);
         {
             TCGv t0 = tcg_temp_new();
             TCGv t1 = tcg_temp_new();
@@ -18632,7 +18632,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case OPC_YIELD:
-        check_insn(ctx, ASE_MT);
+        check_mt(ctx);
         {
             TCGv t0 = tcg_temp_new();
 
@@ -19929,22 +19929,22 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
                 op2 = MASK_MFMC0(ctx->opcode);
                 switch (op2) {
                 case OPC_DMT:
-                    check_insn(ctx, ASE_MT);
+                    check_cp0_mt(ctx);
                     gen_helper_dmt(t0);
                     gen_store_gpr(t0, rt);
                     break;
                 case OPC_EMT:
-                    check_insn(ctx, ASE_MT);
+                    check_cp0_mt(ctx);
                     gen_helper_emt(t0);
                     gen_store_gpr(t0, rt);
                     break;
                 case OPC_DVPE:
-                    check_insn(ctx, ASE_MT);
+                    check_cp0_mt(ctx);
                     gen_helper_dvpe(t0, cpu_env);
                     gen_store_gpr(t0, rt);
                     break;
                 case OPC_EVPE:
-                    check_insn(ctx, ASE_MT);
+                    check_cp0_mt(ctx);
                     gen_helper_evpe(t0, cpu_env);
                     gen_store_gpr(t0, rt);
                     break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 11/87] target/mips: Implement CP0 Config1.WR bit functionality
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (9 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 12/87] target/mips: Don't update BadVAddr register in Debug Mode Aleksandar Markovic
                   ` (77 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add testing Config1.WR bit into watch exception handling logic.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index af9714b..219de72 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -5562,6 +5562,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_1e0i(mfc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -5579,6 +5580,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_1e0i(mfc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -6261,6 +6263,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_0e1i(mtc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -6278,6 +6281,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_0e1i(mtc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -6964,6 +6968,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -6981,6 +6986,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_1e0i(mfc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
@@ -7645,6 +7651,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_0e1i(mtc0_watchlo, arg, sel);
             rn = "WatchLo";
             break;
@@ -7662,6 +7669,7 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
         case 5:
         case 6:
         case 7:
+            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
             gen_helper_0e1i(mtc0_watchhi, arg, sel);
             rn = "WatchHi";
             break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 12/87] target/mips: Don't update BadVAddr register in Debug Mode
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (10 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 11/87] target/mips: Implement CP0 Config1.WR bit functionality Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 13/87] target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0 Aleksandar Markovic
                   ` (76 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

BadVAddr should not be updated if (env->hflags & MIPS_HFLAG_DM) is
set.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/helper.c    |  4 +++-
 target/mips/op_helper.c | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index 8cf91ce..e215af9 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -502,7 +502,9 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
         break;
     }
     /* Raise exception */
-    env->CP0_BadVAddr = address;
+    if (!(env->hflags & MIPS_HFLAG_DM)) {
+        env->CP0_BadVAddr = address;
+    }
     env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
                        ((address >> 9) & 0x007ffff0);
     env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) |
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 41d3634..0b2663b 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -271,7 +271,9 @@ static inline hwaddr do_translate_address(CPUMIPSState *env,
 target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
 {                                                                             \
     if (arg & almask) {                                                       \
-        env->CP0_BadVAddr = arg;                                              \
+        if (!(env->hflags & MIPS_HFLAG_DM)) {                                 \
+            env->CP0_BadVAddr = arg;                                          \
+        }                                                                     \
         do_raise_exception(env, EXCP_AdEL, GETPC());                          \
     }                                                                         \
     env->lladdr = do_translate_address(env, arg, 0, GETPC());                 \
@@ -291,7 +293,9 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \
     target_long tmp;                                                          \
                                                                               \
     if (arg2 & almask) {                                                      \
-        env->CP0_BadVAddr = arg2;                                             \
+        if (!(env->hflags & MIPS_HFLAG_DM)) {                                 \
+            env->CP0_BadVAddr = arg2;                                         \
+        }                                                                     \
         do_raise_exception(env, EXCP_AdES, GETPC());                          \
     }                                                                         \
     if (do_translate_address(env, arg2, 1, GETPC()) == env->lladdr) {         \
@@ -2437,7 +2441,9 @@ void mips_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
     int error_code = 0;
     int excp;
 
-    env->CP0_BadVAddr = addr;
+    if (!(env->hflags & MIPS_HFLAG_DM)) {
+        env->CP0_BadVAddr = addr;
+    }
 
     if (access_type == MMU_DATA_STORE) {
         excp = EXCP_AdES;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 13/87] target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (11 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 12/87] target/mips: Don't update BadVAddr register in Debug Mode Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 14/87] target/mips: Add gen_op_addr_addi() Aleksandar Markovic
                   ` (75 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

MFHC0 and MTHC0 used to handle EntryLo0 and EntryLo1 registers only,
and placing ELPA flag checks before switch statement were technically
correct. However, after adding handling more registers, these checks
should be moved to act only in cases of handling EntryLo0 and
EntryLo1.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 219de72..6740764 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4938,12 +4938,11 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
 {
     const char *rn = "invalid";
 
-    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
-
     switch (reg) {
     case 2:
         switch (sel) {
         case 0:
+            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
             rn = "EntryLo0";
             break;
@@ -4954,6 +4953,7 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     case 3:
         switch (sel) {
         case 0:
+            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
             rn = "EntryLo1";
             break;
@@ -5006,12 +5006,11 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     const char *rn = "invalid";
     uint64_t mask = ctx->PAMask >> 36;
 
-    CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
-
     switch (reg) {
     case 2:
         switch (sel) {
         case 0:
+            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
             tcg_gen_andi_tl(arg, arg, mask);
             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
             rn = "EntryLo0";
@@ -5023,6 +5022,7 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
     case 3:
         switch (sel) {
         case 0:
+            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
             tcg_gen_andi_tl(arg, arg, mask);
             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
             rn = "EntryLo1";
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 14/87] target/mips: Add gen_op_addr_addi()
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (12 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 13/87] target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0 Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 15/87] elf: Remove duplicate preprocessor constant definition Aleksandar Markovic
                   ` (74 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add gen_op_addr_addi(). This function will be used in emulation of
some nanoMIPS instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6740764..e2ffdb0 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1746,6 +1746,18 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv
 #endif
 }
 
+static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
+                                    target_long ofs)
+{
+    tcg_gen_addi_tl(ret, base, ofs);
+
+#if defined(TARGET_MIPS64)
+    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
+        tcg_gen_ext32s_i64(ret, ret);
+    }
+#endif
+}
+
 /* Addresses computation (translation time) */
 static target_long addr_add(DisasContext *ctx, target_long base,
                             target_long offset)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 15/87] elf: Remove duplicate preprocessor constant definition
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (13 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 14/87] target/mips: Add gen_op_addr_addi() Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 16/87] elf: Add ELF flags for MIPS machine variants Aleksandar Markovic
                   ` (73 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Remove duplicate preprocessor constant definition for EF_MIPS_ARCH.

The duplicate was introduced in commit 45506bdd. It placed the
constant EF_MIPS_ARCH in a better place, however it did not remove
the original. This patch removes the original occurrence.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 include/elf.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/elf.h b/include/elf.h
index 934dbbd..60f6cbe 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -61,7 +61,6 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_ABI		0x0000f000
 #define EF_MIPS_FP64      0x00000200
 #define EF_MIPS_NAN2008   0x00000400
-#define EF_MIPS_ARCH      0xf0000000
 
 /* These constants define the different elf file types */
 #define ET_NONE   0
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 16/87] elf: Add ELF flags for MIPS machine variants
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (14 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 15/87] elf: Remove duplicate preprocessor constant definition Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 17/87] linux-user: Update MIPS syscall numbers up to kernel 4.18 headers Aleksandar Markovic
                   ` (72 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Add MIPS machine variants ELF flags so that the emulation behavior
can be adjusted if needed.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 include/elf.h | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index 60f6cbe..28a5a63 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -62,6 +62,29 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_FP64      0x00000200
 #define EF_MIPS_NAN2008   0x00000400
 
+/* MIPS machine variant */
+#define EF_MIPS_MACH_NONE     0x00000000  /* A standard MIPS implementation  */
+#define EF_MIPS_MACH_3900     0x00810000  /* Toshiba R3900                   */
+#define EF_MIPS_MACH_4010     0x00820000  /* LSI R4010                       */
+#define EF_MIPS_MACH_4100     0x00830000  /* NEC VR4100                      */
+#define EF_MIPS_MACH_4650     0x00850000  /* MIPS R4650                      */
+#define EF_MIPS_MACH_4120     0x00870000  /* NEC VR4120                      */
+#define EF_MIPS_MACH_4111     0x00880000  /* NEC VR4111/VR4181               */
+#define EF_MIPS_MACH_SB1      0x008a0000  /* Broadcom SB-1                   */
+#define EF_MIPS_MACH_OCTEON   0x008b0000  /* Cavium Networks Octeon          */
+#define EF_MIPS_MACH_XLR      0x008c0000  /* RMI Xlr                         */
+#define EF_MIPS_MACH_OCTEON2  0x008d0000  /* Cavium Networks Octeon2         */
+#define EF_MIPS_MACH_OCTEON3  0x008e0000  /* Cavium Networks Octeon3         */
+#define EF_MIPS_MACH_5400     0x00910000  /* NEC VR5400                      */
+#define EF_MIPS_MACH_5900     0x00920000  /* MIPS R5900                      */
+#define EF_MIPS_MACH_5500     0x00980000  /* NEC VR5500                      */
+#define EF_MIPS_MACH_9000     0x00990000  /* PMC-Sierra's RM9000             */
+#define EF_MIPS_MACH_LS2E     0x00a00000  /* ST Microelectronics Loongson 2E */
+#define EF_MIPS_MACH_LS2F     0x00a10000  /* ST Microelectronics Loongson 2F */
+#define EF_MIPS_MACH_LS3A     0x00a20000  /* ST Microelectronics Loongson 3A */
+#define EF_MIPS_MACH          0x00ff0000  /* EF_MIPS_MACH_xxx selection mask */
+
+
 /* These constants define the different elf file types */
 #define ET_NONE   0
 #define ET_REL    1
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 17/87] linux-user: Update MIPS syscall numbers up to kernel 4.18 headers
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (15 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 16/87] elf: Add ELF flags for MIPS machine variants Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 18/87] linux-user: Add preprocessor availability control to some syscalls Aleksandar Markovic
                   ` (71 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Synchronize content of linux-user/mips/syscall_nr.h and
linux-user/mips64/syscall_nr.h with Linux kernel 4.18 headers.
This adds 9 new syscall numbers, the last being NR_io_pgetevents.

Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/syscall_nr.h   |  9 +++++++++
 linux-user/mips64/syscall_nr.h | 18 ++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/linux-user/mips/syscall_nr.h b/linux-user/mips/syscall_nr.h
index ced3280..e70adfc 100644
--- a/linux-user/mips/syscall_nr.h
+++ b/linux-user/mips/syscall_nr.h
@@ -363,3 +363,12 @@
 #define TARGET_NR_userfaultfd           (TARGET_NR_Linux + 357)
 #define TARGET_NR_membarrier            (TARGET_NR_Linux + 358)
 #define TARGET_NR_mlock2                (TARGET_NR_Linux + 359)
+#define TARGET_NR_copy_file_range       (TARGET_NR_Linux + 360)
+#define TARGET_NR_preadv2               (TARGET_NR_Linux + 361)
+#define TARGET_NR_pwritev2              (TARGET_NR_Linux + 362)
+#define TARGET_NR_pkey_mprotect         (TARGET_NR_Linux + 363)
+#define TARGET_NR_pkey_alloc            (TARGET_NR_Linux + 364)
+#define TARGET_NR_pkey_free             (TARGET_NR_Linux + 365)
+#define TARGET_NR_statx                 (TARGET_NR_Linux + 366)
+#define TARGET_NR_rseq                  (TARGET_NR_Linux + 367)
+#define TARGET_NR_io_pgetevents         (TARGET_NR_Linux + 368)
diff --git a/linux-user/mips64/syscall_nr.h b/linux-user/mips64/syscall_nr.h
index 746cc26..ff218a9 100644
--- a/linux-user/mips64/syscall_nr.h
+++ b/linux-user/mips64/syscall_nr.h
@@ -327,6 +327,15 @@
 #define TARGET_NR_userfaultfd           (TARGET_NR_Linux + 321)
 #define TARGET_NR_membarrier            (TARGET_NR_Linux + 322)
 #define TARGET_NR_mlock2                (TARGET_NR_Linux + 323)
+#define TARGET_NR_copy_file_range       (TARGET_NR_Linux + 324)
+#define TARGET_NR_preadv2               (TARGET_NR_Linux + 325)
+#define TARGET_NR_pwritev2              (TARGET_NR_Linux + 326)
+#define TARGET_NR_pkey_mprotect         (TARGET_NR_Linux + 327)
+#define TARGET_NR_pkey_alloc            (TARGET_NR_Linux + 328)
+#define TARGET_NR_pkey_free             (TARGET_NR_Linux + 329)
+#define TARGET_NR_statx                 (TARGET_NR_Linux + 330)
+#define TARGET_NR_rseq                  (TARGET_NR_Linux + 331)
+#define TARGET_NR_io_pgetevents         (TARGET_NR_Linux + 332)
 
 #else
 /*
@@ -653,4 +662,13 @@
 #define TARGET_NR_userfaultfd           (TARGET_NR_Linux + 317)
 #define TARGET_NR_membarrier            (TARGET_NR_Linux + 318)
 #define TARGET_NR_mlock2                (TARGET_NR_Linux + 319)
+#define TARGET_NR_copy_file_range       (TARGET_NR_Linux + 320)
+#define TARGET_NR_preadv2               (TARGET_NR_Linux + 321)
+#define TARGET_NR_pwritev2              (TARGET_NR_Linux + 322)
+#define TARGET_NR_pkey_mprotect         (TARGET_NR_Linux + 323)
+#define TARGET_NR_pkey_alloc            (TARGET_NR_Linux + 324)
+#define TARGET_NR_pkey_free             (TARGET_NR_Linux + 325)
+#define TARGET_NR_statx                 (TARGET_NR_Linux + 326)
+#define TARGET_NR_rseq                  (TARGET_NR_Linux + 327)
+#define TARGET_NR_io_pgetevents         (TARGET_NR_Linux + 328)
 #endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 18/87] linux-user: Add preprocessor availability control to some syscalls
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (16 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 17/87] linux-user: Update MIPS syscall numbers up to kernel 4.18 headers Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 19/87] qemu-doc: Amend MIPS-related items Aleksandar Markovic
                   ` (70 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add ability to target platforms to individually include user-mode
support for system calls from "stat" group of system calls.

This change is related to new nanoMIPS platform in the sense that
it supports a different set of "stat" system calls than any other
target. nanoMIPS does not support structures stat and stat64 at
all. Also, support for certain number of other system calls is
dropped in nanoMIPS (those are most of the time obsoleted system
calls).

Without this patch, build for nanoMIPS would fail.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/strace.c  | 14 +++++++++++++-
 linux-user/syscall.c | 29 +++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/linux-user/strace.c b/linux-user/strace.c
index bd897a3..33f4a50 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -2304,7 +2304,19 @@ print_statfs(const struct syscallname *name,
     print_pointer(arg1, 1);
     print_syscall_epilogue(name);
 }
-#define print_statfs64  print_statfs
+#endif
+
+#ifdef TARGET_NR_statfs64
+static void
+print_statfs64(const struct syscallname *name,
+    abi_long arg0, abi_long arg1, abi_long arg2,
+    abi_long arg3, abi_long arg4, abi_long arg5)
+{
+    print_syscall_prologue(name);
+    print_string(arg0, 0);
+    print_pointer(arg1, 1);
+    print_syscall_epilogue(name);
+}
 #endif
 
 #ifdef TARGET_NR_symlink
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index dfc851c..3d57966 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7286,6 +7286,9 @@ static inline int target_to_host_mlockall_arg(int arg)
 }
 #endif
 
+#if (defined(TARGET_NR_stat64) || defined(TARGET_NR_lstat64) ||     \
+     defined(TARGET_NR_fstat64) || defined(TARGET_NR_fstatat64) ||  \
+     defined(TARGET_NR_newfstatat))
 static inline abi_long host_to_target_stat64(void *cpu_env,
                                              abi_ulong target_addr,
                                              struct stat *host_st)
@@ -7348,6 +7351,7 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
 
     return 0;
 }
+#endif
 
 /* ??? Using host futex calls even when target atomic operations
    are not really atomic probably breaks things.  However implementing
@@ -7996,8 +8000,15 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 {
     CPUState *cpu = ENV_GET_CPU(cpu_env);
     abi_long ret;
+#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
+    || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
+    || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
     struct stat st;
+#endif
+#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
+    || defined(TARGET_NR_fstatfs)
     struct statfs stfs;
+#endif
     void *p;
 
 #if defined(DEBUG_ERESTARTSYS)
@@ -8365,9 +8376,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_oldstat:
         goto unimplemented;
 #endif
+#ifdef TARGET_NR_lseek
     case TARGET_NR_lseek:
         ret = get_errno(lseek(arg1, arg2, arg3));
         break;
+#endif
 #if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
     /* Alpha specific */
     case TARGET_NR_getxpid:
@@ -9251,6 +9264,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(sethostname(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#ifdef TARGET_NR_setrlimit
     case TARGET_NR_setrlimit:
         {
             int resource = target_to_host_resource(arg1);
@@ -9264,6 +9278,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             ret = get_errno(setrlimit(resource, &rlim));
         }
         break;
+#endif
+#ifdef TARGET_NR_getrlimit
     case TARGET_NR_getrlimit:
         {
             int resource = target_to_host_resource(arg1);
@@ -9280,6 +9296,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
         }
         break;
+#endif
     case TARGET_NR_getrusage:
         {
             struct rusage rusage;
@@ -9644,15 +9661,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         ret = get_errno(munlockall());
         break;
 #endif
+#ifdef TARGET_NR_truncate
     case TARGET_NR_truncate:
         if (!(p = lock_user_string(arg1)))
             goto efault;
         ret = get_errno(truncate(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#endif
+#ifdef TARGET_NR_ftruncate
     case TARGET_NR_ftruncate:
         ret = get_errno(ftruncate(arg1, arg2));
         break;
+#endif
     case TARGET_NR_fchmod:
         ret = get_errno(fchmod(arg1, arg2));
         break;
@@ -9688,6 +9709,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_profil:
         goto unimplemented;
 #endif
+#ifdef TARGET_NR_statfs
     case TARGET_NR_statfs:
         if (!(p = lock_user_string(arg1)))
             goto efault;
@@ -9719,9 +9741,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             unlock_user_struct(target_stfs, arg2, 1);
         }
         break;
+#endif
+#ifdef TARGET_NR_fstatfs
     case TARGET_NR_fstatfs:
         ret = get_errno(fstatfs(arg1, &stfs));
         goto convert_statfs;
+#endif
 #ifdef TARGET_NR_statfs64
     case TARGET_NR_statfs64:
         if (!(p = lock_user_string(arg1)))
@@ -9969,6 +9994,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         unlock_user(p, arg1, 0);
         goto do_stat;
 #endif
+#ifdef TARGET_NR_fstat
     case TARGET_NR_fstat:
         {
             ret = get_errno(fstat(arg1, &st));
@@ -9998,6 +10024,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
         }
         break;
+#endif
 #ifdef TARGET_NR_olduname
     case TARGET_NR_olduname:
         goto unimplemented;
@@ -10997,6 +11024,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 
 #ifdef CONFIG_SENDFILE
+#ifdef TARGET_NR_sendfile
     case TARGET_NR_sendfile:
     {
         off_t *offp = NULL;
@@ -11017,6 +11045,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
     }
+#endif
 #ifdef TARGET_NR_sendfile64
     case TARGET_NR_sendfile64:
     {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 19/87] qemu-doc: Amend MIPS-related items
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (17 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 18/87] linux-user: Add preprocessor availability control to some syscalls Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 20/87] target/mips: Add preprocessor constants for nanoMIPS Aleksandar Markovic
                   ` (69 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Amend MIPS-related items in qemu-doc.texi

Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 qemu-doc.texi | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index abfd2db..8ea6bfa 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2693,8 +2693,17 @@ The binary format is detected automatically.
 @command{qemu-microblaze} TODO.
 
 @cindex user mode (MIPS)
-@command{qemu-mips} TODO.
-@command{qemu-mipsel} TODO.
+@command{qemu-mips} executes 32-bit big endian MIPS binaries (MIPS O32 ABI).
+
+@command{qemu-mipsel} executes 32-bit little endian MIPS binaries (MIPS O32 ABI).
+
+@command{qemu-mips64} executes 64-bit big endian MIPS binaries (MIPS O64 ABI).
+
+@command{qemu-mips64el} executes 64-bit little endian MIPS binaries (MIPS O64 ABI).
+
+@command{qemu-mipsn32} executes 32-bit big endian MIPS binaries (MIPS N32 ABI).
+
+@command{qemu-mipsn32el} executes 32-bit little endian MIPS binaries (MIPS N32 ABI).
 
 @cindex user mode (NiosII)
 @command{qemu-nios2} TODO.
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 20/87] target/mips: Add preprocessor constants for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (18 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 19/87] qemu-doc: Amend MIPS-related items Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 21/87] target/mips: Add nanoMIPS base instruction set opcodes Aleksandar Markovic
                   ` (68 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Add ISA_NANOMIPS32 and CPU_NANOMIPS32 preprocessor constants.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/mips-defs.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index d239069..c8e9979 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -39,6 +39,7 @@
 #define   ISA_MIPS64R5  0x00001000
 #define   ISA_MIPS32R6  0x00002000
 #define   ISA_MIPS64R6  0x00004000
+#define   ISA_NANOMIPS32  0x00008000
 
 /* MIPS ASEs. */
 #define   ASE_MIPS16    0x00010000
@@ -87,6 +88,9 @@
 #define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6)
 #define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6)
 
+/* Wave Computing: "nanoMIPS" */
+#define CPU_NANOMIPS32 (CPU_MIPS32R6 | ISA_NANOMIPS32)
+
 /* Strictly follow the architecture standard:
    - Disallow "special" instruction handling for PMON/SPIM.
    Note that we still maintain Count/Compare to match the host clock. */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 21/87] target/mips: Add nanoMIPS base instruction set opcodes
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (19 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 20/87] target/mips: Add preprocessor constants for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 22/87] target/mips: Add nanoMIPS DSP ASE opcodes Aleksandar Markovic
                   ` (67 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add nanoMIPS opcodes. nanoMIPS instruction are organized by so-called
instruction pools. Each pool contains a set of opcodes, that in turn
can be instruction opcodes or instruction pool opcodes.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 670 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 670 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index e2ffdb0..5984ebd 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -15754,6 +15754,676 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
     return 2;
 }
 
+/*
+ *
+ * nanoMIPS opcodes
+ *
+ */
+
+/* MAJOR, P16, and P32 pools opcodes */
+enum {
+    NM_P_ADDIU      = 0x00,
+    NM_ADDIUPC      = 0x01,
+    NM_MOVE_BALC    = 0x02,
+    NM_P16_MV       = 0x04,
+    NM_LW16         = 0x05,
+    NM_BC16         = 0x06,
+    NM_P16_SR       = 0x07,
+
+    NM_POOL32A      = 0x08,
+    NM_P_BAL        = 0x0a,
+    NM_P16_SHIFT    = 0x0c,
+    NM_LWSP16       = 0x0d,
+    NM_BALC16       = 0x0e,
+    NM_P16_4X4      = 0x0f,
+
+    NM_P_GP_W       = 0x10,
+    NM_P_GP_BH      = 0x11,
+    NM_P_J          = 0x12,
+    NM_P16C         = 0x14,
+    NM_LWGP16       = 0x15,
+    NM_P16_LB       = 0x17,
+
+    NM_P48I         = 0x18,
+    NM_P16_A1       = 0x1c,
+    NM_LW4X4        = 0x1d,
+    NM_P16_LH       = 0x1f,
+
+    NM_P_U12        = 0x20,
+    NM_P_LS_U12     = 0x21,
+    NM_P_BR1        = 0x22,
+    NM_P16_A2       = 0x24,
+    NM_SW16         = 0x25,
+    NM_BEQZC16      = 0x26,
+
+    NM_POOL32F      = 0x28,
+    NM_P_LS_S9      = 0x29,
+    NM_P_BR2        = 0x2a,
+
+    NM_P16_ADDU     = 0x2c,
+    NM_SWSP16       = 0x2d,
+    NM_BNEZC16      = 0x2e,
+    NM_MOVEP        = 0x2f,
+
+    NM_POOL32S      = 0x30,
+    NM_P_BRI        = 0x32,
+    NM_LI16         = 0x34,
+    NM_SWGP16       = 0x35,
+    NM_P16_BR       = 0x36,
+
+    NM_P_LUI        = 0x38,
+    NM_ANDI16       = 0x3c,
+    NM_SW4X4        = 0x3d,
+    NM_MOVEPREV     = 0x3f,
+};
+
+/* POOL32A instruction pool */
+enum {
+    NM_POOL32A0    = 0x00,
+    NM_SPECIAL2    = 0x01,
+    NM_COP2_1      = 0x02,
+    NM_UDI         = 0x03,
+    NM_POOL32A5    = 0x05,
+    NM_POOL32A7    = 0x07,
+};
+
+/* P.GP.W instruction pool */
+enum {
+    NM_ADDIUGP_W = 0x00,
+    NM_LWGP      = 0x02,
+    NM_SWGP      = 0x03,
+};
+
+/* P48I instruction pool */
+enum {
+    NM_LI48        = 0x00,
+    NM_ADDIU48     = 0x01,
+    NM_ADDIUGP48   = 0x02,
+    NM_ADDIUPC48   = 0x03,
+    NM_LWPC48      = 0x0b,
+    NM_SWPC48      = 0x0f,
+};
+
+/* P.U12 instruction pool */
+enum {
+    NM_ORI      = 0x00,
+    NM_XORI     = 0x01,
+    NM_ANDI     = 0x02,
+    NM_P_SR     = 0x03,
+    NM_SLTI     = 0x04,
+    NM_SLTIU    = 0x05,
+    NM_SEQI     = 0x06,
+    NM_ADDIUNEG = 0x08,
+    NM_P_SHIFT  = 0x0c,
+    NM_P_ROTX   = 0x0d,
+    NM_P_INS    = 0x0e,
+    NM_P_EXT    = 0x0f,
+};
+
+/* POOL32F instruction pool */
+enum {
+    NM_POOL32F_0   = 0x00,
+    NM_POOL32F_3   = 0x03,
+    NM_POOL32F_5   = 0x05,
+};
+
+/* POOL32S instruction pool */
+enum {
+    NM_POOL32S_0   = 0x00,
+    NM_POOL32S_4   = 0x04,
+};
+
+/* P.LUI instruction pool */
+enum {
+    NM_LUI      = 0x00,
+    NM_ALUIPC   = 0x01,
+};
+
+/* P.GP.BH instruction pool */
+enum {
+    NM_LBGP      = 0x00,
+    NM_SBGP      = 0x01,
+    NM_LBUGP     = 0x02,
+    NM_ADDIUGP_B = 0x03,
+    NM_P_GP_LH   = 0x04,
+    NM_P_GP_SH   = 0x05,
+    NM_P_GP_CP1  = 0x06,
+};
+
+/* P.LS.U12 instruction pool */
+enum {
+    NM_LB        = 0x00,
+    NM_SB        = 0x01,
+    NM_LBU       = 0x02,
+    NM_P_PREFU12 = 0x03,
+    NM_LH        = 0x04,
+    NM_SH        = 0x05,
+    NM_LHU       = 0x06,
+    NM_LWU       = 0x07,
+    NM_LW        = 0x08,
+    NM_SW        = 0x09,
+    NM_LWC1      = 0x0a,
+    NM_SWC1      = 0x0b,
+    NM_LDC1      = 0x0e,
+    NM_SDC1      = 0x0f,
+};
+
+/* P.LS.S9 instruction pool */
+enum {
+    NM_P_LS_S0         = 0x00,
+    NM_P_LS_S1         = 0x01,
+    NM_P_LS_E0         = 0x02,
+    NM_P_LS_WM         = 0x04,
+    NM_P_LS_UAWM       = 0x05,
+};
+
+/* P.BAL instruction pool */
+enum {
+    NM_BC       = 0x00,
+    NM_BALC     = 0x01,
+};
+
+/* P.J instruction pool */
+enum {
+    NM_JALRC    = 0x00,
+    NM_JALRC_HB = 0x01,
+    NM_P_BALRSC = 0x08,
+};
+
+/* P.BR1 instruction pool */
+enum {
+    NM_BEQC     = 0x00,
+    NM_P_BR3A   = 0x01,
+    NM_BGEC     = 0x02,
+    NM_BGEUC    = 0x03,
+};
+
+/* P.BR2 instruction pool */
+enum {
+    NM_BNEC     = 0x00,
+    NM_BLTC     = 0x02,
+    NM_BLTUC    = 0x03,
+};
+
+/* P.BRI instruction pool */
+enum {
+    NM_BEQIC    = 0x00,
+    NM_BBEQZC   = 0x01,
+    NM_BGEIC    = 0x02,
+    NM_BGEIUC   = 0x03,
+    NM_BNEIC    = 0x04,
+    NM_BBNEZC   = 0x05,
+    NM_BLTIC    = 0x06,
+    NM_BLTIUC   = 0x07,
+};
+
+/* P16.SHIFT instruction pool */
+enum {
+    NM_SLL16    = 0x00,
+    NM_SRL16    = 0x01,
+};
+
+/* POOL16C instruction pool */
+enum {
+    NM_POOL16C_0  = 0x00,
+    NM_LWXS16     = 0x01,
+};
+
+/* P16.A1 instruction pool */
+enum {
+    NM_ADDIUR1SP = 0x01,
+};
+
+/* P16.A2 instruction pool */
+enum {
+    NM_ADDIUR2  = 0x00,
+    NM_P_ADDIURS5  = 0x01,
+};
+
+/* P16.ADDU instruction pool */
+enum {
+    NM_ADDU16     = 0x00,
+    NM_SUBU16     = 0x01,
+};
+
+/* P16.SR instruction pool */
+enum {
+    NM_SAVE16        = 0x00,
+    NM_RESTORE_JRC16 = 0x01,
+};
+
+/* P16.4X4 instruction pool */
+enum {
+    NM_ADDU4X4      = 0x00,
+    NM_MUL4X4       = 0x01,
+};
+
+/* P16.LB instruction pool */
+enum {
+    NM_LB16       = 0x00,
+    NM_SB16       = 0x01,
+    NM_LBU16      = 0x02,
+};
+
+/* P16.LH  instruction pool */
+enum {
+    NM_LH16     = 0x00,
+    NM_SH16     = 0x01,
+    NM_LHU16    = 0x02,
+};
+
+/* P.RI instruction pool */
+enum {
+    NM_SIGRIE       = 0x00,
+    NM_P_SYSCALL    = 0x01,
+    NM_BREAK        = 0x02,
+    NM_SDBBP        = 0x03,
+};
+
+/* POOL32A0 instruction pool */
+enum {
+    NM_P_TRAP   = 0x00,
+    NM_SEB      = 0x01,
+    NM_SLLV     = 0x02,
+    NM_MUL      = 0x03,
+    NM_MFC0     = 0x06,
+    NM_MFHC0    = 0x07,
+    NM_SEH      = 0x09,
+    NM_SRLV     = 0x0a,
+    NM_MUH      = 0x0b,
+    NM_MTC0     = 0x0e,
+    NM_MTHC0    = 0x0f,
+    NM_SRAV     = 0x12,
+    NM_MULU     = 0x13,
+    NM_ROTRV    = 0x1a,
+    NM_MUHU     = 0x1b,
+    NM_ADD      = 0x22,
+    NM_DIV      = 0x23,
+    NM_ADDU     = 0x2a,
+    NM_MOD      = 0x2b,
+    NM_SUB      = 0x32,
+    NM_DIVU     = 0x33,
+    NM_RDHWR    = 0x38,
+    NM_SUBU     = 0x3a,
+    NM_MODU     = 0x3b,
+    NM_P_CMOVE  = 0x42,
+    NM_FORK     = 0x45,
+    NM_MFTR     = 0x46,
+    NM_MFHTR    = 0x47,
+    NM_AND      = 0x4a,
+    NM_YIELD    = 0x4d,
+    NM_MTTR     = 0x4e,
+    NM_MTHTR    = 0x4f,
+    NM_OR       = 0x52,
+    NM_D_E_MT_VPE = 0x56,
+    NM_NOR      = 0x5a,
+    NM_XOR      = 0x62,
+    NM_SLT      = 0x6a,
+    NM_P_SLTU   = 0x72,
+    NM_SOV      = 0x7a,
+};
+
+/* POOL32A7 instruction pool */
+enum {
+    NM_P_LSX        = 0x00,
+    NM_LSA          = 0x01,
+    NM_EXTW         = 0x03,
+    NM_POOL32AXF    = 0x07,
+};
+
+/* P.SR instruction pool */
+enum {
+    NM_PP_SR           = 0x00,
+    NM_P_SR_F          = 0x01,
+};
+
+/* P.SHIFT instruction pool */
+enum {
+    NM_P_SLL        = 0x00,
+    NM_SRL          = 0x02,
+    NM_SRA          = 0x04,
+    NM_ROTR         = 0x06,
+};
+
+/* P.ROTX instruction pool */
+enum {
+    NM_ROTX         = 0x00,
+};
+
+/* P.INS instruction pool */
+enum {
+    NM_INS          = 0x00,
+};
+
+/* P.EXT instruction pool */
+enum {
+    NM_EXT          = 0x00,
+};
+
+/* POOL32F_0 (fmt) instruction pool */
+enum {
+    NM_RINT_S              = 0x04,
+    NM_RINT_D              = 0x44,
+    NM_ADD_S               = 0x06,
+    NM_SELEQZ_S            = 0x07,
+    NM_SELEQZ_D            = 0x47,
+    NM_CLASS_S             = 0x0c,
+    NM_CLASS_D             = 0x4c,
+    NM_SUB_S               = 0x0e,
+    NM_SELNEZ_S            = 0x0f,
+    NM_SELNEZ_D            = 0x4f,
+    NM_MUL_S               = 0x16,
+    NM_SEL_S               = 0x17,
+    NM_SEL_D               = 0x57,
+    NM_DIV_S               = 0x1e,
+    NM_ADD_D               = 0x26,
+    NM_SUB_D               = 0x2e,
+    NM_MUL_D               = 0x36,
+    NM_MADDF_S             = 0x37,
+    NM_MADDF_D             = 0x77,
+    NM_DIV_D               = 0x3e,
+    NM_MSUBF_S             = 0x3f,
+    NM_MSUBF_D             = 0x7f,
+};
+
+/* POOL32F_3  instruction pool */
+enum {
+    NM_MIN_FMT         = 0x00,
+    NM_MAX_FMT         = 0x01,
+    NM_MINA_FMT        = 0x04,
+    NM_MAXA_FMT        = 0x05,
+    NM_POOL32FXF       = 0x07,
+};
+
+/* POOL32F_5  instruction pool */
+enum {
+    NM_CMP_CONDN_S     = 0x00,
+    NM_CMP_CONDN_D     = 0x02,
+};
+
+/* P.GP.LH instruction pool */
+enum {
+    NM_LHGP    = 0x00,
+    NM_LHUGP   = 0x01,
+};
+
+/* P.GP.SH instruction pool */
+enum {
+    NM_SHGP    = 0x00,
+};
+
+/* P.GP.CP1 instruction pool */
+enum {
+    NM_LWC1GP       = 0x00,
+    NM_SWC1GP       = 0x01,
+    NM_LDC1GP       = 0x02,
+    NM_SDC1GP       = 0x03,
+};
+
+/* P.LS.S0 instruction pool */
+enum {
+    NM_LBS9     = 0x00,
+    NM_LHS9     = 0x04,
+    NM_LWS9     = 0x08,
+    NM_LDS9     = 0x0c,
+
+    NM_SBS9     = 0x01,
+    NM_SHS9     = 0x05,
+    NM_SWS9     = 0x09,
+    NM_SDS9     = 0x0d,
+
+    NM_LBUS9    = 0x02,
+    NM_LHUS9    = 0x06,
+    NM_LWC1S9   = 0x0a,
+    NM_LDC1S9   = 0x0e,
+
+    NM_P_PREFS9 = 0x03,
+    NM_LWUS9    = 0x07,
+    NM_SWC1S9   = 0x0b,
+    NM_SDC1S9   = 0x0f,
+};
+
+/* P.LS.S1 instruction pool */
+enum {
+    NM_ASET_ACLR = 0x02,
+    NM_UALH      = 0x04,
+    NM_UASH      = 0x05,
+    NM_CACHE     = 0x07,
+    NM_P_LL      = 0x0a,
+    NM_P_SC      = 0x0b,
+};
+
+/* P.LS.WM instruction pool */
+enum {
+    NM_LWM       = 0x00,
+    NM_SWM       = 0x01,
+};
+
+/* P.LS.UAWM instruction pool */
+enum {
+    NM_UALWM       = 0x00,
+    NM_UASWM       = 0x01,
+};
+
+/* P.BR3A instruction pool */
+enum {
+    NM_BC1EQZC          = 0x00,
+    NM_BC1NEZC          = 0x01,
+    NM_BC2EQZC          = 0x02,
+    NM_BC2NEZC          = 0x03,
+    NM_BPOSGE32C        = 0x04,
+};
+
+/* P16.RI instruction pool */
+enum {
+    NM_P16_SYSCALL  = 0x01,
+    NM_BREAK16      = 0x02,
+    NM_SDBBP16      = 0x03,
+};
+
+/* POOL16C_0 instruction pool */
+enum {
+    NM_POOL16C_00      = 0x00,
+};
+
+/* P16.JRC instruction pool */
+enum {
+    NM_JRC          = 0x00,
+    NM_JALRC16      = 0x01,
+};
+
+/* P.SYSCALL instruction pool */
+enum {
+    NM_SYSCALL      = 0x00,
+    NM_HYPCALL      = 0x01,
+};
+
+/* P.TRAP instruction pool */
+enum {
+    NM_TEQ          = 0x00,
+    NM_TNE          = 0x01,
+};
+
+/* P.CMOVE instruction pool */
+enum {
+    NM_MOVZ            = 0x00,
+    NM_MOVN            = 0x01,
+};
+
+/* POOL32Axf instruction pool */
+enum {
+    NM_POOL32AXF_4 = 0x04,
+    NM_POOL32AXF_5 = 0x05,
+};
+
+/* POOL32Axf_{4, 5} instruction pool */
+enum {
+    NM_CLO      = 0x25,
+    NM_CLZ      = 0x2d,
+
+    NM_TLBP     = 0x01,
+    NM_TLBR     = 0x09,
+    NM_TLBWI    = 0x11,
+    NM_TLBWR    = 0x19,
+    NM_TLBINV   = 0x03,
+    NM_TLBINVF  = 0x0b,
+    NM_DI       = 0x23,
+    NM_EI       = 0x2b,
+    NM_RDPGPR   = 0x70,
+    NM_WRPGPR   = 0x78,
+    NM_WAIT     = 0x61,
+    NM_DERET    = 0x71,
+    NM_ERETX    = 0x79,
+};
+
+/* PP.SR instruction pool */
+enum {
+    NM_SAVE         = 0x00,
+    NM_RESTORE      = 0x02,
+    NM_RESTORE_JRC  = 0x03,
+};
+
+/* P.SR.F instruction pool */
+enum {
+    NM_SAVEF        = 0x00,
+    NM_RESTOREF     = 0x01,
+};
+
+/* P16.SYSCALL  instruction pool */
+enum {
+    NM_SYSCALL16     = 0x00,
+    NM_HYPCALL16     = 0x01,
+};
+
+/* POOL16C_00 instruction pool */
+enum {
+    NM_NOT16           = 0x00,
+    NM_XOR16           = 0x01,
+    NM_AND16           = 0x02,
+    NM_OR16            = 0x03,
+};
+
+/* PP.LSX and PP.LSXS instruction pool */
+enum {
+    NM_LBX      = 0x00,
+    NM_LHX      = 0x04,
+    NM_LWX      = 0x08,
+    NM_LDX      = 0x0c,
+
+    NM_SBX      = 0x01,
+    NM_SHX      = 0x05,
+    NM_SWX      = 0x09,
+    NM_SDX      = 0x0d,
+
+    NM_LBUX     = 0x02,
+    NM_LHUX     = 0x06,
+    NM_LWC1X    = 0x0a,
+    NM_LDC1X    = 0x0e,
+
+    NM_LWUX     = 0x07,
+    NM_SWC1X    = 0x0b,
+    NM_SDC1X    = 0x0f,
+
+    NM_LHXS     = 0x04,
+    NM_LWXS     = 0x08,
+    NM_LDXS     = 0x0c,
+
+    NM_SHXS     = 0x05,
+    NM_SWXS     = 0x09,
+    NM_SDXS     = 0x0d,
+
+    NM_LHUXS    = 0x06,
+    NM_LWC1XS   = 0x0a,
+    NM_LDC1XS   = 0x0e,
+
+    NM_LWUXS    = 0x07,
+    NM_SWC1XS   = 0x0b,
+    NM_SDC1XS   = 0x0f,
+};
+
+/* ERETx instruction pool */
+enum {
+    NM_ERET     = 0x00,
+    NM_ERETNC   = 0x01,
+};
+
+/* POOL32FxF_{0, 1} insturction pool */
+enum {
+    NM_CFC1     = 0x40,
+    NM_CTC1     = 0x60,
+    NM_MFC1     = 0x80,
+    NM_MTC1     = 0xa0,
+    NM_MFHC1    = 0xc0,
+    NM_MTHC1    = 0xe0,
+
+    NM_CVT_S_PL = 0x84,
+    NM_CVT_S_PU = 0xa4,
+
+    NM_CVT_L_S     = 0x004,
+    NM_CVT_L_D     = 0x104,
+    NM_CVT_W_S     = 0x024,
+    NM_CVT_W_D     = 0x124,
+
+    NM_RSQRT_S     = 0x008,
+    NM_RSQRT_D     = 0x108,
+
+    NM_SQRT_S      = 0x028,
+    NM_SQRT_D      = 0x128,
+
+    NM_RECIP_S     = 0x048,
+    NM_RECIP_D     = 0x148,
+
+    NM_FLOOR_L_S   = 0x00c,
+    NM_FLOOR_L_D   = 0x10c,
+
+    NM_FLOOR_W_S   = 0x02c,
+    NM_FLOOR_W_D   = 0x12c,
+
+    NM_CEIL_L_S    = 0x04c,
+    NM_CEIL_L_D    = 0x14c,
+    NM_CEIL_W_S    = 0x06c,
+    NM_CEIL_W_D    = 0x16c,
+    NM_TRUNC_L_S   = 0x08c,
+    NM_TRUNC_L_D   = 0x18c,
+    NM_TRUNC_W_S   = 0x0ac,
+    NM_TRUNC_W_D   = 0x1ac,
+    NM_ROUND_L_S   = 0x0cc,
+    NM_ROUND_L_D   = 0x1cc,
+    NM_ROUND_W_S   = 0x0ec,
+    NM_ROUND_W_D   = 0x1ec,
+
+    NM_MOV_S       = 0x01,
+    NM_MOV_D       = 0x81,
+    NM_ABS_S       = 0x0d,
+    NM_ABS_D       = 0x8d,
+    NM_NEG_S       = 0x2d,
+    NM_NEG_D       = 0xad,
+    NM_CVT_D_S     = 0x04d,
+    NM_CVT_D_W     = 0x0cd,
+    NM_CVT_D_L     = 0x14d,
+    NM_CVT_S_D     = 0x06d,
+    NM_CVT_S_W     = 0x0ed,
+    NM_CVT_S_L     = 0x16d,
+};
+
+/* P.LL instruction pool */
+enum {
+    NM_LL       = 0x00,
+    NM_LLWP     = 0x01,
+};
+
+/* P.SC instruction pool */
+enum {
+    NM_SC       = 0x00,
+    NM_SCWP     = 0x01,
+};
+
+/* P.DVP instruction pool */
+enum {
+    NM_DVP      = 0x00,
+    NM_EVP      = 0x01,
+};
+
 /* SmartMIPS extension to MIPS32 */
 
 #if defined(TARGET_MIPS64)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 22/87] target/mips: Add nanoMIPS DSP ASE opcodes
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (20 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 21/87] target/mips: Add nanoMIPS base instruction set opcodes Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 23/87] target/mips: Add placeholder and invocation of decode_nanomips_opc() Aleksandar Markovic
                   ` (66 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add nanoMIPS opcodes for DSP ASE instruction pools and instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 215 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 5984ebd..800941f 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16063,6 +16063,79 @@ enum {
     NM_SOV      = 0x7a,
 };
 
+/* POOL32A5 instruction pool */
+enum {
+    NM_CMP_EQ_PH        = 0x00,
+    NM_CMP_LT_PH        = 0x08,
+    NM_CMP_LE_PH        = 0x10,
+    NM_CMPGU_EQ_QB      = 0x18,
+    NM_CMPGU_LT_QB      = 0x20,
+    NM_CMPGU_LE_QB      = 0x28,
+    NM_CMPGDU_EQ_QB     = 0x30,
+    NM_CMPGDU_LT_QB     = 0x38,
+    NM_CMPGDU_LE_QB     = 0x40,
+    NM_CMPU_EQ_QB       = 0x48,
+    NM_CMPU_LT_QB       = 0x50,
+    NM_CMPU_LE_QB       = 0x58,
+    NM_ADDQ_S_W         = 0x60,
+    NM_SUBQ_S_W         = 0x68,
+    NM_ADDSC            = 0x70,
+    NM_ADDWC            = 0x78,
+
+    NM_ADDQ_S_PH   = 0x01,
+    NM_ADDQH_R_PH  = 0x09,
+    NM_ADDQH_R_W   = 0x11,
+    NM_ADDU_S_QB   = 0x19,
+    NM_ADDU_S_PH   = 0x21,
+    NM_ADDUH_R_QB  = 0x29,
+    NM_SHRAV_R_PH  = 0x31,
+    NM_SHRAV_R_QB  = 0x39,
+    NM_SUBQ_S_PH   = 0x41,
+    NM_SUBQH_R_PH  = 0x49,
+    NM_SUBQH_R_W   = 0x51,
+    NM_SUBU_S_QB   = 0x59,
+    NM_SUBU_S_PH   = 0x61,
+    NM_SUBUH_R_QB  = 0x69,
+    NM_SHLLV_S_PH  = 0x71,
+    NM_PRECR_SRA_R_PH_W = 0x79,
+
+    NM_MULEU_S_PH_QBL   = 0x12,
+    NM_MULEU_S_PH_QBR   = 0x1a,
+    NM_MULQ_RS_PH       = 0x22,
+    NM_MULQ_S_PH        = 0x2a,
+    NM_MULQ_RS_W        = 0x32,
+    NM_MULQ_S_W         = 0x3a,
+    NM_APPEND           = 0x42,
+    NM_MODSUB           = 0x52,
+    NM_SHRAV_R_W        = 0x5a,
+    NM_SHRLV_PH         = 0x62,
+    NM_SHRLV_QB         = 0x6a,
+    NM_SHLLV_QB         = 0x72,
+    NM_SHLLV_S_W        = 0x7a,
+
+    NM_SHILO            = 0x03,
+
+    NM_MULEQ_S_W_PHL    = 0x04,
+    NM_MULEQ_S_W_PHR    = 0x0c,
+
+    NM_MUL_S_PH         = 0x05,
+    NM_PRECR_QB_PH      = 0x0d,
+    NM_PRECRQ_QB_PH     = 0x15,
+    NM_PRECRQ_PH_W      = 0x1d,
+    NM_PRECRQ_RS_PH_W   = 0x25,
+    NM_PRECRQU_S_QB_PH  = 0x2d,
+    NM_PACKRL_PH        = 0x35,
+    NM_PICK_QB          = 0x3d,
+    NM_PICK_PH          = 0x45,
+
+    NM_SHRA_R_W         = 0x5e,
+    NM_SHRA_R_PH        = 0x66,
+    NM_SHLL_S_PH        = 0x76,
+    NM_SHLL_S_W         = 0x7e,
+
+    NM_REPL_PH          = 0x07
+};
+
 /* POOL32A7 instruction pool */
 enum {
     NM_P_LSX        = 0x00,
@@ -16252,8 +16325,127 @@ enum {
 
 /* POOL32Axf instruction pool */
 enum {
+    NM_POOL32AXF_1 = 0x01,
+    NM_POOL32AXF_2 = 0x02,
     NM_POOL32AXF_4 = 0x04,
     NM_POOL32AXF_5 = 0x05,
+    NM_POOL32AXF_7 = 0x07,
+};
+
+/* POOL32Axf_1 instruction pool */
+enum {
+    NM_POOL32AXF_1_0 = 0x00,
+    NM_POOL32AXF_1_1 = 0x01,
+    NM_POOL32AXF_1_3 = 0x03,
+    NM_POOL32AXF_1_4 = 0x04,
+    NM_POOL32AXF_1_5 = 0x05,
+    NM_POOL32AXF_1_7 = 0x07,
+};
+
+/* POOL32Axf_2 instruction pool */
+enum {
+    NM_POOL32AXF_2_0_7     = 0x00,
+    NM_POOL32AXF_2_8_15    = 0x01,
+    NM_POOL32AXF_2_16_23   = 0x02,
+    NM_POOL32AXF_2_24_31   = 0x03,
+};
+
+/* POOL32Axf_7 instruction pool */
+enum {
+    NM_SHRA_R_QB    = 0x0,
+    NM_SHRL_PH      = 0x1,
+    NM_REPL_QB      = 0x2,
+};
+
+/* POOL32Axf_1_0 instruction pool */
+enum {
+    NM_MFHI = 0x0,
+    NM_MFLO = 0x1,
+    NM_MTHI = 0x2,
+    NM_MTLO = 0x3,
+};
+
+/* POOL32Axf_1_1 instruction pool */
+enum {
+    NM_MTHLIP = 0x0,
+    NM_SHILOV = 0x1,
+};
+
+/* POOL32Axf_1_3 instruction pool */
+enum {
+    NM_RDDSP    = 0x0,
+    NM_WRDSP    = 0x1,
+    NM_EXTP     = 0x2,
+    NM_EXTPDP   = 0x3,
+};
+
+/* POOL32Axf_1_4 instruction pool */
+enum {
+    NM_SHLL_QB  = 0x0,
+    NM_SHRL_QB  = 0x1,
+};
+
+/* POOL32Axf_1_5 instruction pool */
+enum {
+    NM_MAQ_S_W_PHR   = 0x0,
+    NM_MAQ_S_W_PHL   = 0x1,
+    NM_MAQ_SA_W_PHR  = 0x2,
+    NM_MAQ_SA_W_PHL  = 0x3,
+};
+
+/* POOL32Axf_1_7 instruction pool */
+enum {
+    NM_EXTR_W       = 0x0,
+    NM_EXTR_R_W     = 0x1,
+    NM_EXTR_RS_W    = 0x2,
+    NM_EXTR_S_H     = 0x3,
+};
+
+/* POOL32Axf_2_0_7 instruction pool */
+enum {
+    NM_DPA_W_PH     = 0x0,
+    NM_DPAQ_S_W_PH  = 0x1,
+    NM_DPS_W_PH     = 0x2,
+    NM_DPSQ_S_W_PH  = 0x3,
+    NM_BALIGN       = 0x4,
+    NM_MADD         = 0x5,
+    NM_MULT         = 0x6,
+    NM_EXTRV_W      = 0x7,
+};
+
+/* POOL32Axf_2_8_15 instruction pool */
+enum {
+    NM_DPAX_W_PH    = 0x0,
+    NM_DPAQ_SA_L_W  = 0x1,
+    NM_DPSX_W_PH    = 0x2,
+    NM_DPSQ_SA_L_W  = 0x3,
+    NM_MADDU        = 0x5,
+    NM_MULTU        = 0x6,
+    NM_EXTRV_R_W    = 0x7,
+};
+
+/* POOL32Axf_2_16_23 instruction pool */
+enum {
+    NM_DPAU_H_QBL       = 0x0,
+    NM_DPAQX_S_W_PH     = 0x1,
+    NM_DPSU_H_QBL       = 0x2,
+    NM_DPSQX_S_W_PH     = 0x3,
+    NM_EXTPV            = 0x4,
+    NM_MSUB             = 0x5,
+    NM_MULSA_W_PH       = 0x6,
+    NM_EXTRV_RS_W       = 0x7,
+};
+
+/* POOL32Axf_2_24_31 instruction pool */
+enum {
+    NM_DPAU_H_QBR       = 0x0,
+    NM_DPAQX_SA_W_PH    = 0x1,
+    NM_DPSU_H_QBR       = 0x2,
+    NM_DPSQX_SA_W_PH    = 0x3,
+    NM_EXTPDPV          = 0x4,
+    NM_MSUBU            = 0x5,
+    NM_MULSAQ_S_W_PH    = 0x6,
+    NM_EXTRV_S_H        = 0x7,
 };
 
 /* POOL32Axf_{4, 5} instruction pool */
@@ -16274,6 +16466,29 @@ enum {
     NM_WAIT     = 0x61,
     NM_DERET    = 0x71,
     NM_ERETX    = 0x79,
+
+    /* nanoMIPS DSP instructions */
+    NM_ABSQ_S_QB        = 0x00,
+    NM_ABSQ_S_PH        = 0x08,
+    NM_ABSQ_S_W         = 0x10,
+    NM_PRECEQ_W_PHL     = 0x28,
+    NM_PRECEQ_W_PHR     = 0x30,
+    NM_PRECEQU_PH_QBL   = 0x38,
+    NM_PRECEQU_PH_QBR   = 0x48,
+    NM_PRECEU_PH_QBL    = 0x58,
+    NM_PRECEU_PH_QBR    = 0x68,
+    NM_PRECEQU_PH_QBLA  = 0x39,
+    NM_PRECEQU_PH_QBRA  = 0x49,
+    NM_PRECEU_PH_QBLA   = 0x59,
+    NM_PRECEU_PH_QBRA   = 0x69,
+    NM_REPLV_PH         = 0x01,
+    NM_REPLV_QB         = 0x09,
+    NM_BITREV           = 0x18,
+    NM_INSV             = 0x20,
+    NM_RADDU_W_QB       = 0x78,
+
+    NM_BITSWAP          = 0x05,
+    NM_WSBH             = 0x3d,
 };
 
 /* PP.SR instruction pool */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 23/87] target/mips: Add placeholder and invocation of decode_nanomips_opc()
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (21 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 22/87] target/mips: Add nanoMIPS DSP ASE opcodes Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 24/87] target/mips: Add nanoMIPS decoding and extraction utilities Aleksandar Markovic
                   ` (65 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Add empty body and invocation of decode_nanomips_opc() if the bit
ISA_NANOMIPS32 is set in ctx->insn_flags.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 800941f..0475e1d 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16639,6 +16639,19 @@ enum {
     NM_EVP      = 0x01,
 };
 
+
+/*
+ *
+ * nanoMIPS decoding engine
+ *
+ */
+
+static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
+{
+    return 2;
+}
+
+
 /* SmartMIPS extension to MIPS32 */
 
 #if defined(TARGET_MIPS64)
@@ -21459,6 +21472,9 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
         insn_bytes = 4;
         decode_opc(env, ctx);
+    } else if (ctx->insn_flags & ISA_NANOMIPS32) {
+        ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
+        insn_bytes = decode_nanomips_opc(env, ctx);
     } else if (ctx->insn_flags & ASE_MICROMIPS) {
         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
         insn_bytes = decode_micromips_opc(env, ctx);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 24/87] target/mips: Add nanoMIPS decoding and extraction utilities
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (22 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 23/87] target/mips: Add placeholder and invocation of decode_nanomips_opc() Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 25/87] target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions Aleksandar Markovic
                   ` (64 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Add some basic utility functions and macros for nanoMIPS decoding
engine.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 0475e1d..0467339 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16646,6 +16646,51 @@ enum {
  *
  */
 
+/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
+static inline int decode_gpr_gpr3(int r)
+{
+    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
+
+    return map[r & 0x7];
+}
+
+/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
+static inline int decode_gpr_gpr3_src_store(int r)
+{
+    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
+
+    return map[r & 0x7];
+}
+
+/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
+static inline int decode_gpr_gpr4(int r)
+{
+    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
+                               16, 17, 18, 19, 20, 21, 22, 23 };
+
+    return map[r & 0xf];
+}
+
+/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
+static inline int decode_gpr_gpr4_zero(int r)
+{
+    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
+                               16, 17, 18, 19, 20, 21, 22, 23 };
+
+    return map[r & 0xf];
+}
+
+
+/* extraction utilities */
+
+#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
+#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
+#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
+#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
+#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
+#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
+
+
 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     return 2;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 25/87] target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (23 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 24/87] target/mips: Add nanoMIPS decoding and extraction utilities Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 26/87] target/mips: Add emulation of nanoMIPS 16-bit branch instructions Aleksandar Markovic
                   ` (63 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS 16-bit arithmetic instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 0467339..85ecf23 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16693,6 +16693,131 @@ static inline int decode_gpr_gpr4_zero(int r)
 
 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
 {
+    uint32_t op;
+    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
+    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
+    int imm;
+
+    /* make sure instructions are on a halfword boundary */
+    if (ctx->base.pc_next & 0x1) {
+        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
+        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
+        tcg_temp_free(tmp);
+        generate_exception_end(ctx, EXCP_AdEL);
+        return 2;
+    }
+
+    op = extract32(ctx->opcode, 10, 6);
+    switch (op) {
+    case NM_P16_MV:
+        break;
+    case NM_P16_SHIFT:
+        break;
+    case NM_P16C:
+        break;
+    case NM_P16_A1:
+        switch (extract32(ctx->opcode, 6, 1)) {
+        case NM_ADDIUR1SP:
+            imm = extract32(ctx->opcode, 0, 6) << 2;
+            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_P16_A2:
+        switch (extract32(ctx->opcode, 3, 1)) {
+        case NM_ADDIUR2:
+            imm = extract32(ctx->opcode, 0, 3) << 2;
+            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
+            break;
+        case NM_P_ADDIURS5:
+            rt = extract32(ctx->opcode, 5, 5);
+            if (rt != 0) {
+                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
+                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
+                      (extract32(ctx->opcode, 0, 3));
+                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
+            }
+            break;
+        }
+        break;
+    case NM_P16_ADDU:
+        switch (ctx->opcode & 0x1) {
+        case NM_ADDU16:
+            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
+            break;
+        case NM_SUBU16:
+            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
+            break;
+        }
+        break;
+    case NM_P16_4X4:
+        rt = (extract32(ctx->opcode, 9, 1) << 3) |
+              extract32(ctx->opcode, 5, 3);
+        rs = (extract32(ctx->opcode, 4, 1) << 3) |
+              extract32(ctx->opcode, 0, 3);
+        rt = decode_gpr_gpr4(rt);
+        rs = decode_gpr_gpr4(rs);
+        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
+                (extract32(ctx->opcode, 3, 1))) {
+        case NM_ADDU4X4:
+            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
+            break;
+        case NM_MUL4X4:
+            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_LI16:
+        break;
+    case NM_ANDI16:
+        break;
+    case NM_P16_LB:
+        break;
+    case NM_P16_LH:
+        break;
+    case NM_LW16:
+        break;
+    case NM_LWSP16:
+        break;
+    case NM_LW4X4:
+        break;
+    case NM_SW4X4:
+        break;
+    case NM_LWGP16:
+        break;
+    case NM_SWSP16:
+        break;
+    case NM_SW16:
+        break;
+    case NM_SWGP16:
+        break;
+    case NM_BC16:
+        break;
+    case NM_BALC16:
+        break;
+    case NM_BEQZC16:
+        break;
+    case NM_BNEZC16:
+        break;
+    case NM_P16_BR:
+        break;
+    case NM_P16_SR:
+        break;
+    case NM_MOVEP:
+        break;
+    case NM_MOVEPREV:
+        break;
+    default:
+        break;
+    }
+
     return 2;
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 26/87] target/mips: Add emulation of nanoMIPS 16-bit branch instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (24 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 25/87] target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 27/87] target/mips: Add emulation of nanoMIPS 16-bit shift instructions Aleksandar Markovic
                   ` (62 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS 16-bit branch instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 85ecf23..0b9936f 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16799,14 +16799,50 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_SWGP16:
         break;
     case NM_BC16:
+        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
+                           (sextract32(ctx->opcode, 0, 1) << 10) |
+                           (extract32(ctx->opcode, 1, 9) << 1), 0);
         break;
     case NM_BALC16:
+        gen_compute_branch(ctx, OPC_BGEZAL, 2, 0, 0,
+                           (sextract32(ctx->opcode, 0, 1) << 10) |
+                           (extract32(ctx->opcode, 1, 9) << 1), 0);
         break;
     case NM_BEQZC16:
+        gen_compute_branch(ctx, OPC_BEQ, 2, rt, 0,
+                           (sextract32(ctx->opcode, 0, 1) << 7) |
+                           (extract32(ctx->opcode, 1, 6) << 1), 0);
         break;
     case NM_BNEZC16:
+        gen_compute_branch(ctx, OPC_BNE, 2, rt, 0,
+                           (sextract32(ctx->opcode, 0, 1) << 7) |
+                           (extract32(ctx->opcode, 1, 6) << 1), 0);
         break;
     case NM_P16_BR:
+        switch (ctx->opcode & 0xf) {
+        case 0:
+            /* P16.JRC */
+            switch (extract32(ctx->opcode, 4, 1)) {
+            case NM_JRC:
+                gen_compute_branch(ctx, OPC_JR, 2,
+                                   extract32(ctx->opcode, 5, 5), 0, 0, 0);
+                break;
+            case NM_JALRC16:
+                gen_compute_branch(ctx, OPC_JALR, 2,
+                                   extract32(ctx->opcode, 5, 5), 31, 0, 0);
+                break;
+            }
+            break;
+        default:
+            {
+                /* P16.BRI */
+                uint32_t opc = extract32(ctx->opcode, 4, 3) <
+                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
+                gen_compute_branch(ctx, opc, 2, rs, rt,
+                                   extract32(ctx->opcode, 0, 4) << 1, 0);
+            }
+            break;
+        }
         break;
     case NM_P16_SR:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 27/87] target/mips: Add emulation of nanoMIPS 16-bit shift instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (25 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 26/87] target/mips: Add emulation of nanoMIPS 16-bit branch instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 28/87] target/mips: Add emulation of nanoMIPS 16-bit misc instructions Aleksandar Markovic
                   ` (61 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS 16-bit shift instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 0b9936f..63aa986 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16713,6 +16713,21 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_P16_MV:
         break;
     case NM_P16_SHIFT:
+        {
+            int shift = extract32(ctx->opcode, 0, 3);
+            uint32_t opc = 0;
+            shift = (shift == 0) ? 8 : shift;
+
+            switch (extract32(ctx->opcode, 3, 1)) {
+            case NM_SLL16:
+                opc = OPC_SLL;
+                break;
+            case NM_SRL16:
+                opc = OPC_SRL;
+                break;
+            }
+            gen_shift_imm(ctx, opc, rt, rs, shift);
+        }
         break;
     case NM_P16C:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 28/87] target/mips: Add emulation of nanoMIPS 16-bit misc instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (26 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 27/87] target/mips: Add emulation of nanoMIPS 16-bit shift instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 29/87] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions Aleksandar Markovic
                   ` (60 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of misc nanoMIPS 16-bit instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 63aa986..c7fdc73 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16711,6 +16711,40 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     op = extract32(ctx->opcode, 10, 6);
     switch (op) {
     case NM_P16_MV:
+        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
+        if (rt != 0) {
+            /* MOVE */
+            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
+            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
+        } else {
+            /* P16.RI */
+            switch (extract32(ctx->opcode, 3, 2)) {
+            case NM_P16_SYSCALL:
+                if (extract32(ctx->opcode, 2, 1) == 0) {
+                    generate_exception_end(ctx, EXCP_SYSCALL);
+                } else {
+                    generate_exception_end(ctx, EXCP_RI);
+                }
+                break;
+            case NM_BREAK16:
+                generate_exception_end(ctx, EXCP_BREAK);
+                break;
+            case NM_SDBBP16:
+                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
+                    gen_helper_do_semihosting(cpu_env);
+                } else {
+                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
+                        generate_exception_end(ctx, EXCP_RI);
+                    } else {
+                        generate_exception_end(ctx, EXCP_DBp);
+                    }
+                }
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_P16_SHIFT:
         {
@@ -16790,6 +16824,13 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_LI16:
+        {
+            int imm = extract32(ctx->opcode, 0, 7);
+            imm = (imm == 0x7f ? -1 : imm);
+            if (rt != 0) {
+                tcg_gen_movi_tl(cpu_gpr[rt], imm);
+            }
+        }
         break;
     case NM_ANDI16:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 29/87] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (27 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 28/87] target/mips: Add emulation of nanoMIPS 16-bit misc instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 30/87] target/mips: Add emulation of nanoMIPS 16-bit logic instructions Aleksandar Markovic
                   ` (59 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of LWXS16, LB16, SB16, LBU16, LH16, SH16, LHU16, LW16, LWSP16,
LW4X4, SW4X4, LWGP16, SWSP16, SW16, and SWGP16 instructions.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/translate.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index c7fdc73..240e3fb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16697,6 +16697,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
+    int offset;
     int imm;
 
     /* make sure instructions are on a halfword boundary */
@@ -16764,6 +16765,13 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P16C:
+        switch (ctx->opcode & 1) {
+        case NM_POOL16C_0:
+            break;
+        case NM_LWXS16:
+            gen_ldxs(ctx, rt, rs, rd);
+            break;
+        }
         break;
     case NM_P16_A1:
         switch (extract32(ctx->opcode, 6, 1)) {
@@ -16835,24 +16843,95 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_ANDI16:
         break;
     case NM_P16_LB:
+        offset = extract32(ctx->opcode, 0, 2);
+        switch (extract32(ctx->opcode, 2, 2)) {
+        case NM_LB16:
+            gen_ld(ctx, OPC_LB, rt, rs, offset);
+            break;
+        case NM_SB16:
+            rt = decode_gpr_gpr3_src_store(
+                     NANOMIPS_EXTRACT_RD(ctx->opcode));
+            gen_st(ctx, OPC_SB, rt, rs, offset);
+            break;
+        case NM_LBU16:
+            gen_ld(ctx, OPC_LBU, rt, rs, offset);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
         break;
     case NM_P16_LH:
+        offset = extract32(ctx->opcode, 1, 2) << 1;
+        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
+        case NM_LH16:
+            gen_ld(ctx, OPC_LH, rt, rs, offset);
+            break;
+        case NM_SH16:
+            rt = decode_gpr_gpr3_src_store(
+                     NANOMIPS_EXTRACT_RD(ctx->opcode));
+            gen_st(ctx, OPC_SH, rt, rs, offset);
+            break;
+        case NM_LHU16:
+            gen_ld(ctx, OPC_LHU, rt, rs, offset);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
         break;
     case NM_LW16:
+        offset = extract32(ctx->opcode, 0, 4) << 2;
+        gen_ld(ctx, OPC_LW, rt, rs, offset);
         break;
     case NM_LWSP16:
+        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
+        offset = extract32(ctx->opcode, 0, 5) << 2;
+        gen_ld(ctx, OPC_LW, rt, 29, offset);
         break;
     case NM_LW4X4:
+        rt = (extract32(ctx->opcode, 9, 1) << 3) |
+             extract32(ctx->opcode, 5, 3);
+        rs = (extract32(ctx->opcode, 4, 1) << 3) |
+             extract32(ctx->opcode, 0, 3);
+        offset = (extract32(ctx->opcode, 3, 1) << 3) |
+                 (extract32(ctx->opcode, 8, 1) << 2);
+        rt = decode_gpr_gpr4(rt);
+        rs = decode_gpr_gpr4(rs);
+        gen_ld(ctx, OPC_LW, rt, rs, offset);
         break;
     case NM_SW4X4:
+        rt = (extract32(ctx->opcode, 9, 1) << 3) |
+             extract32(ctx->opcode, 5, 3);
+        rs = (extract32(ctx->opcode, 4, 1) << 3) |
+             extract32(ctx->opcode, 0, 3);
+        offset = (extract32(ctx->opcode, 3, 1) << 3) |
+                 (extract32(ctx->opcode, 8, 1) << 2);
+        rt = decode_gpr_gpr4_zero(rt);
+        rs = decode_gpr_gpr4(rs);
+        gen_st(ctx, OPC_SW, rt, rs, offset);
         break;
     case NM_LWGP16:
+        offset = extract32(ctx->opcode, 0, 7) << 2;
+        gen_ld(ctx, OPC_LW, rt, 28, offset);
         break;
     case NM_SWSP16:
+        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
+        offset = extract32(ctx->opcode, 0, 5) << 2;
+        gen_st(ctx, OPC_SW, rt, 29, offset);
         break;
     case NM_SW16:
+        rt = decode_gpr_gpr3_src_store(
+                 NANOMIPS_EXTRACT_RD(ctx->opcode));
+        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+        offset = extract32(ctx->opcode, 0, 4) << 2;
+        gen_st(ctx, OPC_SW, rt, rs, offset);
         break;
     case NM_SWGP16:
+        rt = decode_gpr_gpr3_src_store(
+                 NANOMIPS_EXTRACT_RD(ctx->opcode));
+        offset = extract32(ctx->opcode, 0, 7) << 2;
+        gen_st(ctx, OPC_SW, rt, 28, offset);
         break;
     case NM_BC16:
         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 30/87] target/mips: Add emulation of nanoMIPS 16-bit logic instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (28 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 29/87] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 31/87] target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions Aleksandar Markovic
                   ` (58 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of NOT16, AND16, XOR16, OR16 instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 240e3fb..6feb093 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16691,6 +16691,27 @@ static inline int decode_gpr_gpr4_zero(int r)
 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
 
 
+static void gen_pool16c_nanomips_insn(DisasContext *ctx)
+{
+    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
+    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
+
+    switch (extract32(ctx->opcode, 2, 2)) {
+    case NM_NOT16:
+        gen_logic(ctx, OPC_NOR, rt, rs, 0);
+        break;
+    case NM_AND16:
+        gen_logic(ctx, OPC_AND, rt, rt, rs);
+        break;
+    case NM_XOR16:
+        gen_logic(ctx, OPC_XOR, rt, rt, rs);
+        break;
+    case NM_OR16:
+        gen_logic(ctx, OPC_OR, rt, rt, rs);
+        break;
+    }
+}
+
 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t op;
@@ -16767,6 +16788,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_P16C:
         switch (ctx->opcode & 1) {
         case NM_POOL16C_0:
+            gen_pool16c_nanomips_insn(ctx);
             break;
         case NM_LWXS16:
             gen_ldxs(ctx, rt, rs, rd);
@@ -16841,6 +16863,12 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_ANDI16:
+        {
+            uint32_t u = extract32(ctx->opcode, 0, 4);
+            u = (u == 12) ? 0xff :
+                (u == 13) ? 0xffff : u;
+            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
+        }
         break;
     case NM_P16_LB:
         offset = extract32(ctx->opcode, 0, 2);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 31/87] target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (29 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 30/87] target/mips: Add emulation of nanoMIPS 16-bit logic instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions Aleksandar Markovic
                   ` (57 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Matthew Fortune <matthew.fortune@mips.com>

Add emulation of SAVE16 and RESTORE.JRC16 instructions. Routines
gen_save(), gen_restore(), and gen_adjust_sp() are provided to support
this feature.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6feb093..868535c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16691,6 +16691,62 @@ static inline int decode_gpr_gpr4_zero(int r)
 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
 
 
+static void gen_adjust_sp(DisasContext *ctx, int u)
+{
+    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
+}
+
+static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
+                     uint8_t gp, uint16_t u)
+{
+    int counter = 0;
+    TCGv va = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    while (counter != count) {
+        bool use_gp = gp && (counter == count - 1);
+        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
+        int this_offset = -((counter + 1) << 2);
+        gen_base_offset_addr(ctx, va, 29, this_offset);
+        gen_load_gpr(t0, this_rt);
+        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
+                           (MO_TEUL | ctx->default_tcg_memop_mask));
+        counter++;
+    }
+
+    /* adjust stack pointer */
+    gen_adjust_sp(ctx, -u);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(va);
+}
+
+static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
+                        uint8_t gp, uint16_t u)
+{
+    int counter = 0;
+    TCGv va = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    while (counter != count) {
+        bool use_gp = gp && (counter == count - 1);
+        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
+        int this_offset = u - ((counter + 1) << 2);
+        gen_base_offset_addr(ctx, va, 29, this_offset);
+        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
+                        ctx->default_tcg_memop_mask);
+        tcg_gen_ext32s_tl(t0, t0);
+        gen_store_gpr(t0, this_rt);
+        counter++;
+    }
+
+    /* adjust stack pointer */
+    gen_adjust_sp(ctx, u);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(va);
+}
+
 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
 {
     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
@@ -17008,6 +17064,21 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P16_SR:
+        {
+            int count = extract32(ctx->opcode, 0, 4);
+            int u = extract32(ctx->opcode, 4, 4) << 4;
+
+            rt = 30 + extract32(ctx->opcode, 9, 1);
+            switch (extract32(ctx->opcode, 8, 1)) {
+            case NM_SAVE16:
+                gen_save(ctx, rt, count, 0, u);
+                break;
+            case NM_RESTORE_JRC16:
+                gen_restore(ctx, rt, count, 0, u);
+                gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
+                break;
+            }
+        }
         break;
     case NM_MOVEP:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (30 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 31/87] target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 33/87] target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV Aleksandar Markovic
                   ` (56 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of SIGRIE, SYSCALL, BREAK, SDBBP, ADDIU, ADDIUPC,
ADDIUGP.W, LWGP, SWGP, ORI, XORI, ANDI, and other instructions.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 270 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 269 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 868535c..6cd8cec 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16768,6 +16768,274 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
+{
+    uint16_t insn;
+    uint32_t op;
+    int rt, rs;
+    int offset;
+    int imm;
+
+    insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
+    ctx->opcode = (ctx->opcode << 16) | insn;
+
+    rt = extract32(ctx->opcode, 21, 5);
+    rs = extract32(ctx->opcode, 16, 5);
+
+    op = extract32(ctx->opcode, 26, 6);
+    switch (op) {
+    case NM_P_ADDIU:
+        if (rt == 0) {
+            /* P.RI */
+            switch (extract32(ctx->opcode, 19, 2)) {
+            case NM_SIGRIE:
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            case NM_P_SYSCALL:
+                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
+                    generate_exception_end(ctx, EXCP_SYSCALL);
+                } else {
+                    generate_exception_end(ctx, EXCP_RI);
+                }
+                break;
+            case NM_BREAK:
+                generate_exception_end(ctx, EXCP_BREAK);
+                break;
+            case NM_SDBBP:
+                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
+                    gen_helper_do_semihosting(cpu_env);
+                } else {
+                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
+                        generate_exception_end(ctx, EXCP_RI);
+                    } else {
+                        generate_exception_end(ctx, EXCP_DBp);
+                    }
+                }
+                break;
+            }
+        } else {
+            imm = extract32(ctx->opcode, 0, 16);
+            if (rs != 0) {
+                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
+                tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+            } else {
+                tcg_gen_movi_tl(cpu_gpr[rt], imm);
+            }
+        }
+        break;
+    case NM_ADDIUPC:
+        if (rt != 0) {
+            offset = sextract32(ctx->opcode, 0, 1) << 21 |
+                     extract32(ctx->opcode, 1, 20) << 1;
+            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
+            tcg_gen_movi_tl(cpu_gpr[rt], addr);
+        }
+        break;
+    case NM_POOL32A:
+        break;
+    case NM_P_GP_W:
+        switch (ctx->opcode & 0x03) {
+        case NM_ADDIUGP_W:
+            if (rt != 0) {
+                offset = extract32(ctx->opcode, 0, 21);
+                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
+            }
+            break;
+        case NM_LWGP:
+            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
+            break;
+        case NM_SWGP:
+            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_P48I:
+        return 6;
+    case NM_P_U12:
+        switch (extract32(ctx->opcode, 12, 4)) {
+        case NM_ORI:
+            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
+            break;
+        case NM_XORI:
+            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
+            break;
+        case NM_ANDI:
+            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
+            break;
+        case NM_P_SR:
+            switch (extract32(ctx->opcode, 20, 1)) {
+            case NM_PP_SR:
+                switch (ctx->opcode & 3) {
+                case NM_SAVE:
+                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
+                             extract32(ctx->opcode, 2, 1),
+                             extract32(ctx->opcode, 3, 9) << 3);
+                    break;
+                case NM_RESTORE:
+                case NM_RESTORE_JRC:
+                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
+                                extract32(ctx->opcode, 2, 1),
+                                extract32(ctx->opcode, 3, 9) << 3);
+                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
+                        gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
+                    }
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            case NM_P_SR_F:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            break;
+        case NM_SLTI:
+            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
+            break;
+        case NM_SLTIU:
+            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
+            break;
+        case NM_SEQI:
+            {
+                TCGv t0 = tcg_temp_new();
+
+                imm = extract32(ctx->opcode, 0, 12);
+                gen_load_gpr(t0, rs);
+                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
+                gen_store_gpr(t0, rt);
+
+                tcg_temp_free(t0);
+            }
+            break;
+        case NM_ADDIUNEG:
+            imm = (int16_t) extract32(ctx->opcode, 0, 12);
+            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
+            break;
+        case NM_P_SHIFT:
+            {
+                int shift = extract32(ctx->opcode, 0, 5);
+                switch (extract32(ctx->opcode, 5, 4)) {
+                case NM_P_SLL:
+                    if (rt == 0 && shift == 0) {
+                        /* NOP */
+                    } else if (rt == 0 && shift == 3) {
+                        /* EHB treat as NOP */
+                    } else if (rt == 0 && shift == 5) {
+                        /* PAUSE */
+                        if (ctx->hflags & MIPS_HFLAG_BMASK) {
+                            generate_exception_end(ctx, EXCP_RI);
+                        }
+                    } else if (rt == 0 && shift == 6) {
+                        /* SYNC */
+                        gen_sync(extract32(ctx->opcode, 16, 5));
+                    } else {
+                        /* SLL */
+                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
+                                      extract32(ctx->opcode, 0, 5));
+                    }
+                    break;
+                case NM_SRL:
+                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
+                                  extract32(ctx->opcode, 0, 5));
+                    break;
+                case NM_SRA:
+                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
+                                  extract32(ctx->opcode, 0, 5));
+                    break;
+                case NM_ROTR:
+                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
+                                  extract32(ctx->opcode, 0, 5));
+                    break;
+                }
+            }
+            break;
+        case NM_P_ROTX:
+            break;
+        case NM_P_INS:
+            switch (((ctx->opcode >> 10) & 2) |
+                    (extract32(ctx->opcode, 5, 1))) {
+            case NM_INS:
+                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
+                           extract32(ctx->opcode, 6, 5));
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            break;
+        case NM_P_EXT:
+            switch (((ctx->opcode >> 10) & 2) |
+                    (extract32(ctx->opcode, 5, 1))) {
+            case NM_EXT:
+                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
+                           extract32(ctx->opcode, 6, 5));
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32F:
+        break;
+    case NM_POOL32S:
+        break;
+    case NM_P_LUI:
+        switch (extract32(ctx->opcode, 1, 1)) {
+        case NM_LUI:
+            if (rt != 0) {
+                tcg_gen_movi_tl(cpu_gpr[rt],
+                                sextract32(ctx->opcode, 0, 1) << 31 |
+                                extract32(ctx->opcode, 2, 10) << 21 |
+                                extract32(ctx->opcode, 12, 9) << 12);
+            }
+            break;
+        case NM_ALUIPC:
+            if (rt != 0) {
+                offset = sextract32(ctx->opcode, 0, 1) << 31 |
+                         extract32(ctx->opcode, 2, 10) << 21 |
+                         extract32(ctx->opcode, 12, 9) << 12;
+                target_long addr;
+                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
+                tcg_gen_movi_tl(cpu_gpr[rt], addr);
+            }
+            break;
+        }
+        break;
+    case NM_P_GP_BH:
+        break;
+    case NM_P_LS_U12:
+        break;
+    case NM_P_LS_S9:
+        break;
+    case NM_MOVE_BALC:
+        break;
+    case NM_P_BAL:
+        break;
+    case NM_P_J:
+        break;
+    case NM_P_BR1:
+        break;
+    case NM_P_BR2:
+        break;
+    case NM_P_BRI:
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+    return 4;
+}
+
 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint32_t op;
@@ -17085,7 +17353,7 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_MOVEPREV:
         break;
     default:
-        break;
+        return decode_nanomips_32_48_opc(env, ctx);
     }
 
     return 2;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 33/87] target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (31 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 34/87] target/mips: Add emulation of nanoMIPS 48-bit instructions Aleksandar Markovic
                   ` (55 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 6cd8cec..4e8994c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17349,8 +17349,39 @@ static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_MOVEP:
-        break;
     case NM_MOVEPREV:
+        {
+            static const int gpr2reg1[] = {4, 5, 6, 7};
+            static const int gpr2reg2[] = {5, 6, 7, 8};
+            int re;
+            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
+                      extract32(ctx->opcode, 8, 1);
+            int r1 = gpr2reg1[rd2];
+            int r2 = gpr2reg2[rd2];
+            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
+                     extract32(ctx->opcode, 0, 3);
+            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
+                     extract32(ctx->opcode, 5, 3);
+            TCGv t0 = tcg_temp_new();
+            TCGv t1 = tcg_temp_new();
+            if (op == NM_MOVEP) {
+                rd = r1;
+                re = r2;
+                rs = decode_gpr_gpr4_zero(r3);
+                rt = decode_gpr_gpr4_zero(r4);
+            } else {
+                rd = decode_gpr_gpr4(r3);
+                re = decode_gpr_gpr4(r4);
+                rs = r1;
+                rt = r2;
+            }
+            gen_load_gpr(t0, rs);
+            gen_load_gpr(t1, rt);
+            tcg_gen_mov_tl(cpu_gpr[rd], t0);
+            tcg_gen_mov_tl(cpu_gpr[re], t1);
+            tcg_temp_free(t0);
+            tcg_temp_free(t1);
+        }
         break;
     default:
         return decode_nanomips_32_48_opc(env, ctx);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 34/87] target/mips: Add emulation of nanoMIPS 48-bit instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (32 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 33/87] target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV Aleksandar Markovic
@ 2018-08-13 17:52 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 35/87] target/mips: Add emulation of nanoMIPS FP instructions Aleksandar Markovic
                   ` (54 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of LI48, ADDIU48, ADDIUGP48, ADDIUPC48, LWPC48, and
SWPC48 instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 4e8994c..40da813 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16854,7 +16854,71 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P48I:
-        return 6;
+        {
+            insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
+            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
+            switch (extract32(ctx->opcode, 16, 5)) {
+            case NM_LI48:
+                if (rt != 0) {
+                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
+                }
+                break;
+            case NM_ADDIU48:
+                if (rt != 0) {
+                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
+                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+                }
+                break;
+            case NM_ADDIUGP48:
+                if (rt != 0) {
+                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
+                }
+                break;
+            case NM_ADDIUPC48:
+                if (rt != 0) {
+                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
+                                                addr_off);
+
+                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
+                }
+                break;
+            case NM_LWPC48:
+                if (rt != 0) {
+                    TCGv t0;
+                    t0 = tcg_temp_new();
+
+                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
+                                                addr_off);
+
+                    tcg_gen_movi_tl(t0, addr);
+                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
+                    tcg_temp_free(t0);
+                }
+                break;
+            case NM_SWPC48:
+                {
+                    TCGv t0, t1;
+                    t0 = tcg_temp_new();
+                    t1 = tcg_temp_new();
+
+                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
+                                                addr_off);
+
+                    tcg_gen_movi_tl(t0, addr);
+                    gen_load_gpr(t1, rt);
+
+                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
+
+                    tcg_temp_free(t0);
+                    tcg_temp_free(t1);
+                }
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            return 6;
+        }
     case NM_P_U12:
         switch (extract32(ctx->opcode, 12, 4)) {
         case NM_ORI:
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 35/87] target/mips: Add emulation of nanoMIPS FP instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (33 preceding siblings ...)
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 34/87] target/mips: Add emulation of nanoMIPS 48-bit instructions Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 36/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32a0) Aleksandar Markovic
                   ` (53 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of basic floating point arithmetic for nanoMIPS.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 300 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 40da813..87bb2c2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16768,6 +16768,305 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool32f_nanomips_insn(DisasContext *ctx)
+{
+    int rt, rs, rd;
+
+    rt = extract32(ctx->opcode, 21, 5);
+    rs = extract32(ctx->opcode, 16, 5);
+    rd = extract32(ctx->opcode, 11, 5);
+
+    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
+        generate_exception_end(ctx, EXCP_RI);
+        return;
+    }
+    check_cp1_enabled(ctx);
+    switch (extract32(ctx->opcode, 0, 3)) {
+    case NM_POOL32F_0:
+        switch (extract32(ctx->opcode, 3, 7)) {
+        case NM_RINT_S:
+            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
+            break;
+        case NM_RINT_D:
+            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
+            break;
+        case NM_CLASS_S:
+            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
+            break;
+        case NM_CLASS_D:
+            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
+            break;
+        case NM_ADD_S:
+            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
+            break;
+        case NM_ADD_D:
+            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
+            break;
+        case NM_SUB_S:
+            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
+            break;
+        case NM_SUB_D:
+            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
+            break;
+        case NM_MUL_S:
+            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
+            break;
+        case NM_MUL_D:
+            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
+            break;
+        case NM_DIV_S:
+            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
+            break;
+        case NM_DIV_D:
+            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
+            break;
+        case NM_SELEQZ_S:
+            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
+            break;
+        case NM_SELEQZ_D:
+            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
+            break;
+        case NM_SELNEZ_S:
+            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
+            break;
+        case NM_SELNEZ_D:
+            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
+            break;
+        case NM_SEL_S:
+            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
+            break;
+        case NM_SEL_D:
+            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
+            break;
+        case NM_MADDF_S:
+            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
+            break;
+        case NM_MADDF_D:
+            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
+            break;
+        case NM_MSUBF_S:
+            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
+            break;
+        case NM_MSUBF_D:
+            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32F_3:
+        switch (extract32(ctx->opcode, 3, 3)) {
+        case NM_MIN_FMT:
+            switch (extract32(ctx->opcode, 9, 1)) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MAX_FMT:
+            switch (extract32(ctx->opcode, 9, 1)) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MINA_FMT:
+            switch (extract32(ctx->opcode, 9, 1)) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_MAXA_FMT:
+            switch (extract32(ctx->opcode, 9, 1)) {
+            case FMT_SDPS_S:
+                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
+                break;
+            case FMT_SDPS_D:
+                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
+                break;
+            }
+            break;
+        case NM_POOL32FXF:
+            switch (extract32(ctx->opcode, 6, 8)) {
+            case NM_CFC1:
+                gen_cp1(ctx, OPC_CFC1, rt, rs);
+                break;
+            case NM_CTC1:
+                gen_cp1(ctx, OPC_CTC1, rt, rs);
+                break;
+            case NM_MFC1:
+                gen_cp1(ctx, OPC_MFC1, rt, rs);
+                break;
+            case NM_MTC1:
+                gen_cp1(ctx, OPC_MTC1, rt, rs);
+                break;
+            case NM_MFHC1:
+                gen_cp1(ctx, OPC_MFHC1, rt, rs);
+                break;
+            case NM_MTHC1:
+                gen_cp1(ctx, OPC_MTHC1, rt, rs);
+                break;
+            case NM_CVT_S_PL:
+                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
+                break;
+            case NM_CVT_S_PU:
+                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
+                break;
+            default:
+                switch (extract32(ctx->opcode, 6, 9)) {
+                case NM_CVT_L_S:
+                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_L_D:
+                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_W_S:
+                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_W_D:
+                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_RSQRT_S:
+                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
+                    break;
+                case NM_RSQRT_D:
+                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
+                    break;
+                case NM_SQRT_S:
+                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
+                    break;
+                case NM_SQRT_D:
+                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
+                    break;
+                case NM_RECIP_S:
+                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
+                    break;
+                case NM_RECIP_D:
+                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_L_S:
+                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_L_D:
+                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_W_S:
+                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_FLOOR_W_D:
+                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_L_S:
+                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_L_D:
+                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_W_S:
+                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_CEIL_W_D:
+                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_L_S:
+                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_L_D:
+                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_W_S:
+                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_TRUNC_W_D:
+                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_L_S:
+                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_L_D:
+                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_W_S:
+                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
+                    break;
+                case NM_ROUND_W_D:
+                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
+                    break;
+                case NM_MOV_S:
+                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
+                    break;
+                case NM_MOV_D:
+                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
+                    break;
+                case NM_ABS_S:
+                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
+                    break;
+                case NM_ABS_D:
+                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
+                    break;
+                case NM_NEG_S:
+                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
+                    break;
+                case NM_NEG_D:
+                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_S:
+                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_W:
+                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_D_L:
+                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_D:
+                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_W:
+                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
+                    break;
+                case NM_CVT_S_L:
+                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            }
+            break;
+        }
+        break;
+    case NM_POOL32F_5:
+        switch (extract32(ctx->opcode, 3, 3)) {
+        case NM_CMP_CONDN_S:
+            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
+            break;
+        case NM_CMP_CONDN_D:
+            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint16_t insn;
@@ -17050,6 +17349,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32F:
+        gen_pool32f_nanomips_insn(ctx);
         break;
     case NM_POOL32S:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 36/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32a0)
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (34 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 35/87] target/mips: Add emulation of nanoMIPS FP instructions Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 37/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32axf) Aleksandar Markovic
                   ` (52 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS instructions that are situated in pool32a0.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 87bb2c2..7133538 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16768,6 +16768,181 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
+{
+    int rt = extract32(ctx->opcode, 21, 5);
+    int rs = extract32(ctx->opcode, 16, 5);
+    int rd = extract32(ctx->opcode, 11, 5);
+
+    switch (extract32(ctx->opcode, 3, 7)) {
+    case NM_P_TRAP:
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case NM_TEQ:
+            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
+            break;
+        case NM_TNE:
+            gen_trap(ctx, OPC_TNE, rs, rt, -1);
+            break;
+        }
+        break;
+    case NM_RDHWR:
+        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
+        break;
+    case NM_SEB:
+        gen_bshfl(ctx, OPC_SEB, rs, rt);
+        break;
+    case NM_SEH:
+        gen_bshfl(ctx, OPC_SEH, rs, rt);
+        break;
+    case NM_SLLV:
+        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
+        break;
+    case NM_SRLV:
+        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
+        break;
+    case NM_SRAV:
+        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
+        break;
+    case NM_ROTRV:
+        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
+        break;
+    case NM_ADD:
+        gen_arith(ctx, OPC_ADD, rd, rs, rt);
+        break;
+    case NM_ADDU:
+        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
+        break;
+    case NM_SUB:
+        gen_arith(ctx, OPC_SUB, rd, rs, rt);
+        break;
+    case NM_SUBU:
+        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
+        break;
+    case NM_P_CMOVE:
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case NM_MOVZ:
+            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
+            break;
+        case NM_MOVN:
+            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
+            break;
+        }
+        break;
+    case NM_AND:
+        gen_logic(ctx, OPC_AND, rd, rs, rt);
+        break;
+    case NM_OR:
+        gen_logic(ctx, OPC_OR, rd, rs, rt);
+        break;
+    case NM_NOR:
+        gen_logic(ctx, OPC_NOR, rd, rs, rt);
+        break;
+    case NM_XOR:
+        gen_logic(ctx, OPC_XOR, rd, rs, rt);
+        break;
+    case NM_SLT:
+        gen_slt(ctx, OPC_SLT, rd, rs, rt);
+        break;
+    case NM_P_SLTU:
+        if (rd == 0) {
+            /* P_DVP */
+#ifndef CONFIG_USER_ONLY
+            TCGv t0 = tcg_temp_new();
+            switch (extract32(ctx->opcode, 10, 1)) {
+            case NM_DVP:
+                if (ctx->vp) {
+                    check_cp0_enabled(ctx);
+                    gen_helper_dvp(t0, cpu_env);
+                    gen_store_gpr(t0, rt);
+                }
+                break;
+            case NM_EVP:
+                if (ctx->vp) {
+                    check_cp0_enabled(ctx);
+                    gen_helper_evp(t0, cpu_env);
+                    gen_store_gpr(t0, rt);
+                }
+                break;
+            }
+            tcg_temp_free(t0);
+#endif
+        } else {
+            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
+        }
+        break;
+    case NM_SOV:
+        {
+            TCGv t0 = tcg_temp_new();
+            TCGv t1 = tcg_temp_new();
+            TCGv t2 = tcg_temp_new();
+
+            gen_load_gpr(t1, rs);
+            gen_load_gpr(t2, rt);
+            tcg_gen_add_tl(t0, t1, t2);
+            tcg_gen_ext32s_tl(t0, t0);
+            tcg_gen_xor_tl(t1, t1, t2);
+            tcg_gen_xor_tl(t2, t0, t2);
+            tcg_gen_andc_tl(t1, t2, t1);
+
+            /* operands of same sign, result different sign */
+            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
+            gen_store_gpr(t0, rd);
+
+            tcg_temp_free(t0);
+            tcg_temp_free(t1);
+            tcg_temp_free(t2);
+        }
+        break;
+    case NM_MUL:
+        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
+        break;
+    case NM_MUH:
+        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
+        break;
+    case NM_MULU:
+        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
+        break;
+    case NM_MUHU:
+        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
+        break;
+    case NM_DIV:
+        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
+        break;
+    case NM_MOD:
+        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
+        break;
+    case NM_DIVU:
+        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
+        break;
+    case NM_MODU:
+        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
+        break;
+#ifndef CONFIG_USER_ONLY
+    case NM_MFC0:
+        check_cp0_enabled(ctx);
+        if (rt == 0) {
+            /* Treat as NOP. */
+            break;
+        }
+        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
+        break;
+    case NM_MTC0:
+        check_cp0_enabled(ctx);
+        {
+            TCGv t0 = tcg_temp_new();
+
+            gen_load_gpr(t0, rt);
+            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
+            tcg_temp_free(t0);
+        }
+        break;
+#endif
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
 {
     int rt, rs, rd;
@@ -17132,6 +17307,16 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32A:
+        switch (ctx->opcode & 0x07) {
+        case NM_POOL32A0:
+            gen_pool32a0_nanomips_insn(ctx);
+            break;
+        case NM_POOL32A7:
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
         break;
     case NM_P_GP_W:
         switch (ctx->opcode & 0x03) {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 37/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32axf)
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (35 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 36/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32a0) Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 38/87] target/mips: Add emulation of misc nanoMIPS instructions (p_lsx) Aleksandar Markovic
                   ` (51 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of misc nanoMIPS instructions situated in pool32axf.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 7133538..63928eb 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16943,6 +16943,87 @@ static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
+{
+    int rt = extract32(ctx->opcode, 21, 5);
+    int rs = extract32(ctx->opcode, 16, 5);
+
+    switch (extract32(ctx->opcode, 6, 3)) {
+    case NM_POOL32AXF_4:
+    case NM_POOL32AXF_5:
+        switch (extract32(ctx->opcode, 9, 7)) {
+#ifndef CONFIG_USER_ONLY
+        case NM_TLBP:
+            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
+            break;
+        case NM_TLBR:
+            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
+            break;
+        case NM_TLBWI:
+            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
+            break;
+        case NM_TLBWR:
+            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
+            break;
+        case NM_TLBINV:
+            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
+            break;
+        case NM_TLBINVF:
+            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
+            break;
+        case NM_DI:
+            check_cp0_enabled(ctx);
+            {
+                TCGv t0 = tcg_temp_new();
+
+                save_cpu_state(ctx, 1);
+                gen_helper_di(t0, cpu_env);
+                gen_store_gpr(t0, rt);
+            /* Stop translation as we may have switched the execution mode */
+                ctx->base.is_jmp = DISAS_STOP;
+                tcg_temp_free(t0);
+            }
+            break;
+        case NM_EI:
+            check_cp0_enabled(ctx);
+            {
+                TCGv t0 = tcg_temp_new();
+
+                save_cpu_state(ctx, 1);
+                gen_helper_ei(t0, cpu_env);
+                gen_store_gpr(t0, rt);
+            /* Stop translation as we may have switched the execution mode */
+                ctx->base.is_jmp = DISAS_STOP;
+                tcg_temp_free(t0);
+            }
+            break;
+        case NM_RDPGPR:
+            gen_load_srsgpr(rs, rt);
+            break;
+        case NM_WRPGPR:
+            gen_store_srsgpr(rs, rt);
+            break;
+        case NM_WAIT:
+            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
+            break;
+        case NM_DERET:
+            gen_cp0(env, ctx, OPC_DERET, 0, 0);
+            break;
+        case NM_ERETX:
+            gen_cp0(env, ctx, OPC_ERET, 0, 0);
+            break;
+#endif
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
 {
     int rt, rs, rd;
@@ -17312,6 +17393,14 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
             gen_pool32a0_nanomips_insn(ctx);
             break;
         case NM_POOL32A7:
+            switch (extract32(ctx->opcode, 3, 3)) {
+            case NM_POOL32AXF:
+                gen_pool32axf_nanomips_insn(env, ctx);
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
             break;
         default:
             generate_exception_end(ctx, EXCP_RI);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 38/87] target/mips: Add emulation of misc nanoMIPS instructions (p_lsx)
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (36 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 37/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32axf) Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 39/87] target/mips: Implement emulation of nanoMIPS ROTX instruction Aleksandar Markovic
                   ` (50 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of nanoMIPS instructions situated in pool p_lsx, and
emulation of LSA instruction as well.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 131 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 63928eb..a97a989 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17024,6 +17024,125 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
+
+static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
+{
+    TCGv t0, t1;
+    t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
+
+    gen_load_gpr(t0, rs);
+    gen_load_gpr(t1, rt);
+
+    if ((extract32(ctx->opcode, 6, 1)) == 1) {
+        /* PP.LSXS instructions require shifting */
+        switch (extract32(ctx->opcode, 7, 4)) {
+        case NM_LHXS:
+        case NM_SHXS:
+        case NM_LHUXS:
+            tcg_gen_shli_tl(t0, t0, 1);
+            break;
+        case NM_LWXS:
+        case NM_SWXS:
+        case NM_LWC1XS:
+        case NM_SWC1XS:
+            tcg_gen_shli_tl(t0, t0, 2);
+            break;
+        case NM_LDC1XS:
+        case NM_SDC1XS:
+            tcg_gen_shli_tl(t0, t0, 3);
+            break;
+        }
+    }
+    gen_op_addr_add(ctx, t0, t0, t1);
+
+    switch (extract32(ctx->opcode, 7, 4)) {
+    case NM_LBX:
+        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
+                           MO_SB);
+        gen_store_gpr(t0, rd);
+        break;
+    case NM_LHX:
+    /*case NM_LHXS:*/
+        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
+                           MO_TESW);
+        gen_store_gpr(t0, rd);
+        break;
+    case NM_LWX:
+    /*case NM_LWXS:*/
+        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
+                           MO_TESL);
+        gen_store_gpr(t0, rd);
+        break;
+    case NM_LBUX:
+        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
+                           MO_UB);
+        gen_store_gpr(t0, rd);
+        break;
+    case NM_LHUX:
+    /*case NM_LHUXS:*/
+        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
+                           MO_TEUW);
+        gen_store_gpr(t0, rd);
+        break;
+    case NM_SBX:
+        gen_load_gpr(t1, rd);
+        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
+                           MO_8);
+        break;
+    case NM_SHX:
+    /*case NM_SHXS:*/
+        gen_load_gpr(t1, rd);
+        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
+                           MO_TEUW);
+        break;
+    case NM_SWX:
+    /*case NM_SWXS:*/
+        gen_load_gpr(t1, rd);
+        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
+                           MO_TEUL);
+        break;
+    case NM_LWC1X:
+    /*case NM_LWC1XS:*/
+    case NM_LDC1X:
+    /*case NM_LDC1XS:*/
+    case NM_SWC1X:
+    /*case NM_SWC1XS:*/
+    case NM_SDC1X:
+    /*case NM_SDC1XS:*/
+        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
+            check_cp1_enabled(ctx);
+            switch (extract32(ctx->opcode, 7, 4)) {
+            case NM_LWC1X:
+            /*case NM_LWC1XS:*/
+                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
+                break;
+            case NM_LDC1X:
+            /*case NM_LDC1XS:*/
+                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
+                break;
+            case NM_SWC1X:
+            /*case NM_SWC1XS:*/
+                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
+                break;
+            case NM_SDC1X:
+            /*case NM_SDC1XS:*/
+                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
+                break;
+            }
+        } else {
+            generate_exception_err(ctx, EXCP_CpU, 1);
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
 {
     int rt, rs, rd;
@@ -17327,7 +17446,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint16_t insn;
     uint32_t op;
-    int rt, rs;
+    int rt, rs, rd;
     int offset;
     int imm;
 
@@ -17336,6 +17455,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
 
     rt = extract32(ctx->opcode, 21, 5);
     rs = extract32(ctx->opcode, 16, 5);
+    rd = extract32(ctx->opcode, 11, 5);
 
     op = extract32(ctx->opcode, 26, 6);
     switch (op) {
@@ -17394,6 +17514,16 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
             break;
         case NM_POOL32A7:
             switch (extract32(ctx->opcode, 3, 3)) {
+            case NM_P_LSX:
+                gen_p_lsx(ctx, rd, rs, rt);
+                break;
+            case NM_LSA:
+                /* In nanoMIPS, the shift field directly encodes the shift
+                 * amount, meaning that the supported shift values are in
+                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
+                gen_lsa(ctx, OPC_LSA, rd, rs, rt,
+                        extract32(ctx->opcode, 9, 2) - 1);
+                break;
             case NM_POOL32AXF:
                 gen_pool32axf_nanomips_insn(env, ctx);
                 break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 39/87] target/mips: Implement emulation of nanoMIPS ROTX instruction
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (37 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 38/87] target/mips: Add emulation of misc nanoMIPS instructions (p_lsx) Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 40/87] target/mips: Implement emulation of nanoMIPS EXTW instruction Aleksandar Markovic
                   ` (49 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Matthew Fortune <matthew.fortune@mips.com>

Added a helper for ROTX based on the pseudocode from the
architecture spec. This instraction was not present in previous
MIPS instruction sets.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/helper.h    |  2 ++
 target/mips/op_helper.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++
 target/mips/translate.c | 15 ++++++++
 3 files changed, 111 insertions(+)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 5f49234..b2a780a 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 #endif
 
+DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32)
+
 #ifndef CONFIG_USER_ONLY
 /* CP0 helpers */
 DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 0b2663b..b3eef9f 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -249,6 +249,100 @@ target_ulong helper_bitswap(target_ulong rt)
     return (int32_t)bitswap(rt);
 }
 
+target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx,
+                        uint32_t stripe)
+{
+    int i;
+    uint64_t tmp0 = ((uint64_t)rs) << 32 | ((uint64_t)rs & 0xffffffff);
+    uint64_t 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);
+            }
+        }
+    }
+
+    uint64_t 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);
+            }
+        }
+    }
+
+    uint64_t 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);
+            }
+        }
+    }
+
+    uint64_t 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);
+            }
+        }
+    }
+
+    uint64_t 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);
+            }
+        }
+    }
+
+    return (int64_t)(int32_t)(uint32_t)tmp5;
+}
+
 #ifndef CONFIG_USER_ONLY
 
 static inline hwaddr do_translate_address(CPUMIPSState *env,
diff --git a/target/mips/translate.c b/target/mips/translate.c
index a97a989..02c9813 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17722,6 +17722,21 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
             }
             break;
         case NM_P_ROTX:
+            if (rt != 0) {
+                TCGv t0 = tcg_temp_new();
+                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
+                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
+                                                << 1);
+                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
+
+                gen_load_gpr(t0, rs);
+                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
+                tcg_temp_free(t0);
+
+                tcg_temp_free_i32(shift);
+                tcg_temp_free_i32(shiftx);
+                tcg_temp_free_i32(stripe);
+            }
             break;
         case NM_P_INS:
             switch (((ctx->opcode >> 10) & 2) |
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 40/87] target/mips: Implement emulation of nanoMIPS EXTW instruction
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (38 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 39/87] target/mips: Implement emulation of nanoMIPS ROTX instruction Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 41/87] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions Aleksandar Markovic
                   ` (48 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: James Hogan <james.hogan@mips.com>

Implement emulation of nanoMIPS EXTW instruction. EXTW instruction
is similar to the MIPS r6 ALIGN instruction, except that it counts
the other way and in bits instead of bytes. We therefore generalise
gen_align() function into a new gen_align_bits() function (which
counts in bits instead of bytes and optimises when bits = size of
the word), and implement gen_align() and a new gen_ext() based on
that. Since we need to know the word size to check for when the
number of bits == the word size, the opc argument is replaced with
a wordsz argument (either 32 or 64).

Signed-off-by: James Hogan <james.hogan@mips.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/translate.c | 53 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 02c9813..27f56c4 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4789,8 +4789,8 @@ static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
     return;
 }
 
-static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
-                      int bp)
+static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
+                           int rt, int bits)
 {
     TCGv t0;
     if (rd == 0) {
@@ -4798,35 +4798,40 @@ static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
         return;
     }
     t0 = tcg_temp_new();
-    gen_load_gpr(t0, rt);
-    if (bp == 0) {
-        switch (opc) {
-        case OPC_ALIGN:
+    if (bits == 0 || bits == wordsz) {
+        if (bits == 0) {
+            gen_load_gpr(t0, rt);
+        } else {
+            gen_load_gpr(t0, rs);
+        }
+        switch (wordsz) {
+        case 32:
             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
             break;
 #if defined(TARGET_MIPS64)
-        case OPC_DALIGN:
+        case 64:
             tcg_gen_mov_tl(cpu_gpr[rd], t0);
             break;
 #endif
         }
     } else {
         TCGv t1 = tcg_temp_new();
+        gen_load_gpr(t0, rt);
         gen_load_gpr(t1, rs);
-        switch (opc) {
-        case OPC_ALIGN:
+        switch (wordsz) {
+        case 32:
             {
                 TCGv_i64 t2 = tcg_temp_new_i64();
                 tcg_gen_concat_tl_i64(t2, t1, t0);
-                tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
+                tcg_gen_shri_i64(t2, t2, 32 - bits);
                 gen_move_low32(cpu_gpr[rd], t2);
                 tcg_temp_free_i64(t2);
             }
             break;
 #if defined(TARGET_MIPS64)
-        case OPC_DALIGN:
-            tcg_gen_shli_tl(t0, t0, 8 * bp);
-            tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
+        case 64:
+            tcg_gen_shli_tl(t0, t0, bits);
+            tcg_gen_shri_tl(t1, t1, 64 - bits);
             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
             break;
 #endif
@@ -4837,6 +4842,18 @@ static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
     tcg_temp_free(t0);
 }
 
+static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
+                      int bp)
+{
+    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
+}
+
+static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
+                    int shift)
+{
+    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
+}
+
 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
 {
     TCGv t0;
@@ -14329,8 +14346,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             break;
         case ALIGN:
             check_insn(ctx, ISA_MIPS32R6);
-            gen_align(ctx, OPC_ALIGN, rd, rs, rt,
-                      extract32(ctx->opcode, 9, 2));
+            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
             break;
         case EXT:
             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
@@ -17524,6 +17540,9 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
                         extract32(ctx->opcode, 9, 2) - 1);
                 break;
+            case NM_EXTW:
+                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
+                break;
             case NM_POOL32AXF:
                 gen_pool32axf_nanomips_insn(env, ctx);
                 break;
@@ -20374,7 +20393,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
             switch (op2) {
             case OPC_ALIGN:
             case OPC_ALIGN_END:
-                gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
+                gen_align(ctx, 32, rd, rs, rt, sa & 3);
                 break;
             case OPC_BITSWAP:
                 gen_bitswap(ctx, op2, rd, rt);
@@ -20400,7 +20419,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
             switch (op2) {
             case OPC_DALIGN:
             case OPC_DALIGN_END:
-                gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
+                gen_align(ctx, 64, rd, rs, rt, sa & 7);
                 break;
             case OPC_DBITSWAP:
                 gen_bitswap(ctx, op2, rd, rt);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 41/87] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (39 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 40/87] target/mips: Implement emulation of nanoMIPS EXTW instruction Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair Aleksandar Markovic
                   ` (47 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of various nanoMIPS load and store instructions.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 277 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 27f56c4..9f27aab 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17814,10 +17814,287 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_P_GP_BH:
+        {
+            uint32_t u = extract32(ctx->opcode, 0, 18);
+
+            switch (extract32(ctx->opcode, 18, 3)) {
+            case NM_LBGP:
+                gen_ld(ctx, OPC_LB, rt, 28, u);
+                break;
+            case NM_SBGP:
+                gen_st(ctx, OPC_SB, rt, 28, u);
+                break;
+            case NM_LBUGP:
+                gen_ld(ctx, OPC_LBU, rt, 28, u);
+                break;
+            case NM_ADDIUGP_B:
+                if (rt != 0) {
+                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
+                }
+                break;
+            case NM_P_GP_LH:
+                u &= ~1;
+                switch (ctx->opcode & 1) {
+                case NM_LHGP:
+                    gen_ld(ctx, OPC_LH, rt, 28, u);
+                    break;
+                case NM_LHUGP:
+                    gen_ld(ctx, OPC_LHU, rt, 28, u);
+                    break;
+                }
+                break;
+            case NM_P_GP_SH:
+                u &= ~1;
+                switch (ctx->opcode & 1) {
+                case NM_SHGP:
+                    gen_st(ctx, OPC_SH, rt, 28, u);
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            case NM_P_GP_CP1:
+                u &= ~0x3;
+                switch (ctx->opcode & 0x3) {
+                case NM_LWC1GP:
+                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
+                    break;
+                case NM_LDC1GP:
+                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
+                    break;
+                case NM_SWC1GP:
+                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
+                    break;
+                case NM_SDC1GP:
+                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
+                    break;
+                }
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_P_LS_U12:
+        {
+            uint32_t u = extract32(ctx->opcode, 0, 12);
+
+            switch (extract32(ctx->opcode, 12, 4)) {
+            case NM_P_PREFU12:
+                if (rt == 31) {
+                    /* SYNCI */
+                    /* Break the TB to be able to sync copied instructions
+                       immediately */
+                    ctx->base.is_jmp = DISAS_STOP;
+                } else {
+                    /* PREF */
+                    /* Treat as NOP. */
+                }
+                break;
+            case NM_LB:
+                gen_ld(ctx, OPC_LB, rt, rs, u);
+                break;
+            case NM_LH:
+                gen_ld(ctx, OPC_LH, rt, rs, u);
+                break;
+            case NM_LW:
+                gen_ld(ctx, OPC_LW, rt, rs, u);
+                break;
+            case NM_LBU:
+                gen_ld(ctx, OPC_LBU, rt, rs, u);
+                break;
+            case NM_LHU:
+                gen_ld(ctx, OPC_LHU, rt, rs, u);
+                break;
+            case NM_SB:
+                gen_st(ctx, OPC_SB, rt, rs, u);
+                break;
+            case NM_SH:
+                gen_st(ctx, OPC_SH, rt, rs, u);
+                break;
+            case NM_SW:
+                gen_st(ctx, OPC_SW, rt, rs, u);
+                break;
+            case NM_LWC1:
+                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
+                break;
+            case NM_LDC1:
+                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
+                break;
+            case NM_SWC1:
+                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
+                break;
+            case NM_SDC1:
+                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_P_LS_S9:
+        {
+            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
+                        extract32(ctx->opcode, 0, 8);
+
+            switch (extract32(ctx->opcode, 8, 3)) {
+            case NM_P_LS_S0:
+                switch (extract32(ctx->opcode, 11, 4)) {
+                case NM_LBS9:
+                    gen_ld(ctx, OPC_LB, rt, rs, s);
+                    break;
+                case NM_LHS9:
+                    gen_ld(ctx, OPC_LH, rt, rs, s);
+                    break;
+                case NM_LWS9:
+                    gen_ld(ctx, OPC_LW, rt, rs, s);
+                    break;
+                case NM_LBUS9:
+                    gen_ld(ctx, OPC_LBU, rt, rs, s);
+                    break;
+                case NM_LHUS9:
+                    gen_ld(ctx, OPC_LHU, rt, rs, s);
+                    break;
+                case NM_SBS9:
+                    gen_st(ctx, OPC_SB, rt, rs, s);
+                    break;
+                case NM_SHS9:
+                    gen_st(ctx, OPC_SH, rt, rs, s);
+                    break;
+                case NM_SWS9:
+                    gen_st(ctx, OPC_SW, rt, rs, s);
+                    break;
+                case NM_LWC1S9:
+                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
+                    break;
+                case NM_LDC1S9:
+                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
+                    break;
+                case NM_SWC1S9:
+                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
+                    break;
+                case NM_SDC1S9:
+                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
+                    break;
+                case NM_P_PREFS9:
+                    if (rt == 31) {
+                        /* SYNCI */
+                        /* Break the TB to be able to sync copied instructions
+                           immediately */
+                        ctx->base.is_jmp = DISAS_STOP;
+                    } else {
+                        /* PREF */
+                        /* Treat as NOP. */
+                    }
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            case NM_P_LS_S1:
+                switch (extract32(ctx->opcode, 11, 4)) {
+                case NM_UALH:
+                case NM_UASH:
+                    {
+                        TCGv t0 = tcg_temp_new();
+                        TCGv t1 = tcg_temp_new();
+
+                        gen_base_offset_addr(ctx, t0, rs, s);
+
+                        switch (extract32(ctx->opcode, 11, 4)) {
+                        case NM_UALH:
+                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+                                               MO_UNALN);
+                            gen_store_gpr(t0, rt);
+                            break;
+                        case NM_UASH:
+                            gen_load_gpr(t1, rt);
+                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
+                                               MO_UNALN);
+                            break;
+                        }
+                        tcg_temp_free(t0);
+                        tcg_temp_free(t1);
+                    }
+                    break;
+                case NM_P_LL:
+                    switch (ctx->opcode & 0x03) {
+                    case NM_LL:
+                        gen_ld(ctx, OPC_LL, rt, rs, s);
+                        break;
+                    case NM_LLWP:
+                        break;
+                    }
+                    break;
+                case NM_P_SC:
+                    switch (ctx->opcode & 0x03) {
+                    case NM_SC:
+                        gen_st_cond(ctx, OPC_SC, rt, rs, s);
+                        break;
+                    case NM_SCWP:
+                        break;
+                    }
+                    break;
+                case NM_CACHE:
+                    check_cp0_enabled(ctx);
+                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+                        gen_cache_operation(ctx, rt, rs, s);
+                    }
+                    break;
+                }
+                break;
+            case NM_P_LS_WM:
+            case NM_P_LS_UAWM:
+            {
+                int count = extract32(ctx->opcode, 12, 3);
+                int counter = 0;
+
+                offset = sextract32(ctx->opcode, 15, 1) << 8 |
+                         extract32(ctx->opcode, 0, 8);
+                TCGv va = tcg_temp_new();
+                TCGv t1 = tcg_temp_new();
+                TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
+                                  NM_P_LS_UAWM ? MO_UNALN : 0;
+
+                count = (count == 0) ? 8 : count;
+                while (counter != count) {
+                    int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
+                    int this_offset = offset + (counter << 2);
+
+                    gen_base_offset_addr(ctx, va, rs, this_offset);
+
+                    switch (extract32(ctx->opcode, 11, 1)) {
+                    case NM_LWM:
+                        tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
+                                           memop | MO_TESL);
+                        gen_store_gpr(t1, this_rt);
+                        if ((this_rt == rs) &&
+                            (counter != (count - 1))) {
+                            /* UNPREDICTABLE */
+                        }
+                        break;
+                    case NM_SWM:
+                        this_rt = (rt == 0) ? 0 : this_rt;
+                        gen_load_gpr(t1, this_rt);
+                        tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
+                                           memop | MO_TEUL);
+                        break;
+                    }
+                    counter++;
+                }
+                tcg_temp_free(va);
+                tcg_temp_free(t1);
+            }
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_MOVE_BALC:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (40 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 41/87] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-14 12:20   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 43/87] target/mips: Add emulation of nanoMIPS 32-bit branch instructions Aleksandar Markovic
                   ` (46 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Implement support for nanoMIPS LLWP/SCWP instruction pair.

Signed-off-by: Dimitrije Nikolic <dnikolic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/cpu_loop.c | 25 ++++++++++++----
 target/mips/cpu.h          |  2 ++
 target/mips/translate.c    | 74 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 084ad6a..1d3dc9e 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -397,10 +397,13 @@ static int do_store_exclusive(CPUMIPSState *env)
     target_ulong addr;
     target_ulong page_addr;
     target_ulong val;
+    uint32_t val_wp = 0;
+    uint32_t llnewval_wp = 0;
     int flags;
     int segv = 0;
     int reg;
     int d;
+    int wp;
 
     addr = env->lladdr;
     page_addr = addr & TARGET_PAGE_MASK;
@@ -412,19 +415,31 @@ static int do_store_exclusive(CPUMIPSState *env)
     } else {
         reg = env->llreg & 0x1f;
         d = (env->llreg & 0x20) != 0;
-        if (d) {
-            segv = get_user_s64(val, addr);
+        wp = (env->llreg & 0x40) != 0;
+        if (!wp) {
+            if (d) {
+                segv = get_user_s64(val, addr);
+            } else {
+                segv = get_user_s32(val, addr);
+            }
         } else {
             segv = get_user_s32(val, addr);
+            segv |= get_user_s32(val_wp, addr);
+            llnewval_wp = env->llnewval_wp;
         }
         if (!segv) {
-            if (val != env->llval) {
+            if (val != env->llval && val_wp == llnewval_wp) {
                 env->active_tc.gpr[reg] = 0;
             } else {
-                if (d) {
-                    segv = put_user_u64(env->llnewval, addr);
+                if (!wp) {
+                    if (d) {
+                        segv = put_user_u64(env->llnewval, addr);
+                    } else {
+                        segv = put_user_u32(env->llnewval, addr);
+                    }
                 } else {
                     segv = put_user_u32(env->llnewval, addr);
+                    segv |= put_user_u32(env->llnewval_wp, addr + 4);
                 }
                 if (!segv) {
                     env->active_tc.gpr[reg] = 1;
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 8a8782b..bf9c634 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -506,6 +506,8 @@ struct CPUMIPSState {
     uint64_t lladdr;
     target_ulong llval;
     target_ulong llnewval;
+    uint64_t llval_wp;
+    uint32_t llnewval_wp;
     target_ulong llreg;
     uint64_t CP0_LLAddr_rw_bitmask;
     int CP0_LLAddr_shift;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9f27aab..70785f2 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2401,6 +2401,31 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t0);
 }
 
+static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
+                    uint32_t reg1, uint32_t reg2)
+{
+    TCGv taddr = tcg_temp_new();
+    TCGv_i64 tval = tcg_temp_new_i64();
+    TCGv tmp1 = tcg_temp_new();
+    TCGv tmp2 = tcg_temp_new();
+
+    gen_base_offset_addr(ctx, taddr, base, offset);
+    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
+#ifdef TARGET_WORDS_BIGENDIAN
+    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
+#else
+    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
+#endif
+    gen_store_gpr(tmp1, reg1);
+    tcg_temp_free(tmp1);
+    gen_store_gpr(tmp2, reg2);
+    tcg_temp_free(tmp2);
+    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
+    tcg_temp_free_i64(tval);
+    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
+    tcg_temp_free(taddr);
+}
+
 /* Store */
 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
                     int base, int offset)
@@ -2497,6 +2522,51 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
     tcg_temp_free(t0);
 }
 
+static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
+                    uint32_t reg1, uint32_t reg2)
+{
+    TCGv taddr = tcg_temp_local_new();
+    TCGv lladdr = tcg_temp_local_new();
+    TCGv_i64 tval = tcg_temp_new_i64();
+    TCGv_i64 llval = tcg_temp_new_i64();
+    TCGv_i64 val = tcg_temp_new_i64();
+    TCGv tmp1 = tcg_temp_new();
+    TCGv tmp2 = tcg_temp_new();
+    TCGLabel *lab_fail = gen_new_label();
+    TCGLabel *lab_done = gen_new_label();
+
+    gen_base_offset_addr(ctx, taddr, base, offset);
+
+    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
+    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
+
+    gen_load_gpr(tmp1, reg1);
+    gen_load_gpr(tmp2, reg2);
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
+#else
+    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
+#endif
+
+    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
+    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
+                               ctx->mem_idx, MO_64);
+    if (reg1 != 0) {
+        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
+    }
+    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
+
+    gen_set_label(lab_fail);
+
+    if (reg1 != 0) {
+        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
+    }
+    gen_set_label(lab_done);
+    tcg_gen_movi_tl(lladdr, -1);
+    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
+}
+
 /* Load and store */
 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
                           TCGv t0)
@@ -18027,6 +18097,8 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                         gen_ld(ctx, OPC_LL, rt, rs, s);
                         break;
                     case NM_LLWP:
+                        check_xnp(ctx);
+                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
                         break;
                     }
                     break;
@@ -18036,6 +18108,8 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
                         break;
                     case NM_SCWP:
+                        check_xnp(ctx);
+                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
                         break;
                     }
                     break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 43/87] target/mips: Add emulation of nanoMIPS 32-bit branch instructions
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (41 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 44/87] target/mips: Implement MT ASE support for nanoMIPS Aleksandar Markovic
                   ` (45 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Add emulation of various flavors of nanoMIPS 32-bit branch
instructions.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 262 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 70785f2..632fac5 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17110,6 +17110,155 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
+/* Immediate Value Compact Branches */
+static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
+                                   int rt, int32_t imm, int32_t offset)
+{
+    TCGCond cond;
+    int bcond_compute = 0;
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+
+    if (ctx->hflags & MIPS_HFLAG_BMASK) {
+#ifdef MIPS_DEBUG_DISAS
+        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
+                  "\n", ctx->base.pc_next);
+#endif
+        generate_exception_end(ctx, EXCP_RI);
+        goto out;
+    }
+
+    gen_load_gpr(t0, rt);
+    tcg_gen_movi_tl(t1, imm);
+    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
+
+    /* Load needed operands and calculate btarget */
+    switch (opc) {
+    case NM_BEQIC:
+        if (rt == 0 && imm == 0) {
+            /* Unconditional branch */
+        } else if (rt == 0 && imm != 0) {
+            /* Treat as NOP */
+            goto out;
+        } else {
+            bcond_compute = 1;
+            cond = TCG_COND_EQ;
+        }
+        break;
+    case NM_BBEQZC:
+    case NM_BBNEZC:
+        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
+            generate_exception_end(ctx, EXCP_RI);
+            goto out;
+        } else if (rt == 0 && opc == NM_BBEQZC) {
+            /* Unconditional branch */
+        } else if (rt == 0 && opc == NM_BBNEZC) {
+            /* Treat as NOP */
+            goto out;
+        } else {
+            tcg_gen_shri_tl(t0, t0, imm);
+            tcg_gen_andi_tl(t0, t0, 1);
+            tcg_gen_movi_tl(t1, 0);
+            bcond_compute = 1;
+            if (opc == NM_BBEQZC) {
+                cond = TCG_COND_EQ;
+            } else {
+                cond = TCG_COND_NE;
+            }
+        }
+        break;
+    case NM_BNEIC:
+        if (rt == 0 && imm == 0) {
+            /* Treat as NOP */
+            goto out;
+        } else if (rt == 0 && imm != 0) {
+            /* Unconditional branch */
+        } else {
+            bcond_compute = 1;
+            cond = TCG_COND_NE;
+        }
+        break;
+    case NM_BGEIC:
+        if (rt == 0 && imm == 0) {
+            /* Unconditional branch */
+        } else  {
+            bcond_compute = 1;
+            cond = TCG_COND_GE;
+        }
+        break;
+    case NM_BLTIC:
+        bcond_compute = 1;
+        cond = TCG_COND_LT;
+        break;
+    case NM_BGEIUC:
+        if (rt == 0 && imm == 0) {
+            /* Unconditional branch */
+        } else  {
+            bcond_compute = 1;
+            cond = TCG_COND_GEU;
+        }
+        break;
+    case NM_BLTIUC:
+        bcond_compute = 1;
+        cond = TCG_COND_LTU;
+        break;
+    default:
+        MIPS_INVAL("Immediate Value Compact branch");
+        generate_exception_end(ctx, EXCP_RI);
+        goto out;
+    }
+
+    if (bcond_compute == 0) {
+        /* Uncoditional compact branch */
+        ctx->hflags |= MIPS_HFLAG_B;
+        /* Generating branch here as compact branches don't have delay slot */
+        gen_branch(ctx, 4);
+    } else {
+        /* Conditional compact branch */
+        TCGLabel *fs = gen_new_label();
+        save_cpu_state(ctx, 0);
+
+        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
+
+        /* Generating branch here as compact branches don't have delay slot */
+        gen_goto_tb(ctx, 1, ctx->btarget);
+        gen_set_label(fs);
+
+        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+    }
+
+out:
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
+
+/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
+static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
+                                                int rt)
+{
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+
+    /* load rs */
+    gen_load_gpr(t0, rs);
+
+    /* link */
+    if (rt != 0) {
+        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
+    }
+
+    /* calculate btarget */
+    tcg_gen_shli_tl(t0, t0, 1);
+    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
+    gen_op_addr_add(ctx, btarget, t1, t0);
+
+    ctx->hflags |= MIPS_HFLAG_BR;
+    /* Generating branch here as compact branches don't have delay slot */
+    gen_branch(ctx, 4);
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+}
 
 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
 {
@@ -18171,16 +18320,129 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_MOVE_BALC:
+        {
+            TCGv t0 = tcg_temp_new();
+            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
+                        extract32(ctx->opcode, 1, 20) << 1;
+            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
+            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
+                            extract32(ctx->opcode, 21, 3));
+            gen_load_gpr(t0, rt);
+            tcg_gen_mov_tl(cpu_gpr[rd], t0);
+            gen_compute_branch(ctx, OPC_BGEZAL, 4, 0, 0, s, 0);
+            tcg_temp_free(t0);
+        }
         break;
     case NM_P_BAL:
+        {
+            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
+                        extract32(ctx->opcode, 1, 24) << 1;
+
+            if ((extract32(ctx->opcode, 25, 1)) == 0) {
+                /* BC */
+                gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, s, 0);
+            } else {
+                /* BALC */
+                gen_compute_branch(ctx, OPC_BGEZAL, 4, 0, 0, s, 0);
+            }
+        }
         break;
     case NM_P_J:
+        switch (extract32(ctx->opcode, 12, 4)) {
+        case NM_JALRC:
+        case NM_JALRC_HB:
+            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
+            break;
+        case NM_P_BALRSC:
+            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
         break;
     case NM_P_BR1:
+        {
+            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
+                        extract32(ctx->opcode, 1, 13) << 1;
+            switch (extract32(ctx->opcode, 14, 2)) {
+            case NM_BEQC:
+                gen_compute_branch(ctx, OPC_BEQ, 4, rs, rt, s, 0);
+                break;
+            case NM_P_BR3A:
+                s = sextract32(ctx->opcode, 0, 1) << 14 |
+                    extract32(ctx->opcode, 1, 13) << 1;
+                check_cp1_enabled(ctx);
+                switch (extract32(ctx->opcode, 16, 5)) {
+                case NM_BC1EQZC:
+                    gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rt, s, 0);
+                    break;
+                case NM_BC1NEZC:
+                    gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rt, s, 0);
+                    break;
+                default:
+                    generate_exception_end(ctx, EXCP_RI);
+                    break;
+                }
+                break;
+            case NM_BGEC:
+                if (rs == rt) {
+                    gen_compute_compact_branch(ctx, OPC_BC, rs, rt, s);
+                } else {
+                    gen_compute_compact_branch(ctx, OPC_BGEC, rs, rt, s);
+                }
+                break;
+            case NM_BGEUC:
+                if (rs == rt || rt == 0) {
+                    gen_compute_compact_branch(ctx, OPC_BC, 0, 0, s);
+                } else if (rs == 0) {
+                    gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0, s);
+                } else {
+                    gen_compute_compact_branch(ctx, OPC_BGEUC, rs, rt, s);
+                }
+                break;
+            }
+        }
         break;
     case NM_P_BR2:
+        {
+            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
+                        extract32(ctx->opcode, 1, 13) << 1;
+            switch (extract32(ctx->opcode, 14, 2)) {
+            case NM_BNEC:
+                gen_compute_branch(ctx, OPC_BNE, 4, rs, rt, s, 0);
+                break;
+            case NM_BLTC:
+                if (rs != 0 && rt != 0 && rs == rt) {
+                    /* NOP */
+                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+                } else {
+                    gen_compute_compact_branch(ctx, OPC_BLTC, rs, rt, s);
+                }
+                break;
+            case NM_BLTUC:
+                if (rs == 0 || rs == rt) {
+                    /* NOP */
+                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
+                } else {
+                    gen_compute_compact_branch(ctx, OPC_BLTUC, rs, rt, s);
+                }
+                break;
+            default:
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+        }
         break;
     case NM_P_BRI:
+        {
+            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
+                        extract32(ctx->opcode, 1, 10) << 1;
+            uint32_t u = extract32(ctx->opcode, 11, 7);
+
+            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
+                                   rt, u, s);
+        }
         break;
     default:
         generate_exception_end(ctx, EXCP_RI);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 44/87] target/mips: Implement MT ASE support for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (42 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 43/87] target/mips: Add emulation of nanoMIPS 32-bit branch instructions Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1 Aleksandar Markovic
                   ` (44 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of MT ASE instructions for nanoMIPS.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 632fac5..7be2128 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -16854,7 +16854,7 @@ static void gen_pool16c_nanomips_insn(DisasContext *ctx)
     }
 }
 
-static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
+static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
     int rt = extract32(ctx->opcode, 21, 5);
     int rs = extract32(ctx->opcode, 16, 5);
@@ -17022,6 +17022,87 @@ static void gen_pool32a0_nanomips_insn(DisasContext *ctx)
             tcg_temp_free(t0);
         }
         break;
+    case NM_D_E_MT_VPE:
+        {
+            uint8_t sc = extract32(ctx->opcode, 10, 1);
+            TCGv t0 = tcg_temp_new();
+
+            switch (sc) {
+            case 0:
+                if (rs == 1) {
+                    /* DMT */
+                    check_cp0_mt(ctx);
+                    gen_helper_dmt(t0);
+                    gen_store_gpr(t0, rt);
+                } else if (rs == 0) {
+                    /* DVPE */
+                    check_cp0_mt(ctx);
+                    gen_helper_dvpe(t0, cpu_env);
+                    gen_store_gpr(t0, rt);
+                } else {
+                    generate_exception_end(ctx, EXCP_RI);
+                }
+                break;
+            case 1:
+                if (rs == 1) {
+                    /* EMT */
+                    check_cp0_mt(ctx);
+                    gen_helper_emt(t0);
+                    gen_store_gpr(t0, rt);
+                } else if (rs == 0) {
+                    /* EVPE */
+                    check_cp0_mt(ctx);
+                    gen_helper_evpe(t0, cpu_env);
+                    gen_store_gpr(t0, rt);
+                } else {
+                    generate_exception_end(ctx, EXCP_RI);
+                }
+                break;
+            }
+
+            tcg_temp_free(t0);
+        }
+        break;
+    case NM_FORK:
+        check_mt(ctx);
+        {
+            TCGv t0 = tcg_temp_new();
+            TCGv t1 = tcg_temp_new();
+
+            gen_load_gpr(t0, rt);
+            gen_load_gpr(t1, rs);
+            gen_helper_fork(t0, t1);
+            tcg_temp_free(t0);
+            tcg_temp_free(t1);
+        }
+        break;
+    case NM_MFTR:
+    case NM_MFHTR:
+        check_cp0_enabled(ctx);
+        if (rd == 0) {
+            /* Treat as NOP. */
+            return;
+        }
+        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
+                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
+        break;
+    case NM_MTTR:
+    case NM_MTHTR:
+        check_cp0_enabled(ctx);
+        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
+                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
+        break;
+    case NM_YIELD:
+        check_mt(ctx);
+        {
+            TCGv t0 = tcg_temp_new();
+
+            gen_load_gpr(t0, rs);
+            gen_helper_yield(t0, cpu_env, t0);
+            gen_store_gpr(t0, rt);
+            tcg_temp_free(t0);
+        }
+        break;
 #endif
     default:
         generate_exception_end(ctx, EXCP_RI);
@@ -17745,7 +17826,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
     case NM_POOL32A:
         switch (ctx->opcode & 0x07) {
         case NM_POOL32A0:
-            gen_pool32a0_nanomips_insn(ctx);
+            gen_pool32a0_nanomips_insn(env, ctx);
             break;
         case NM_POOL32A7:
             switch (extract32(ctx->opcode, 3, 3)) {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (43 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 44/87] target/mips: Implement MT ASE support for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 46/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2 Aleksandar Markovic
                   ` (43 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 1.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 556 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 556 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 7be2128..de10a07 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17758,6 +17758,556 @@ static void gen_pool32f_nanomips_insn(DisasContext *ctx)
     }
 }
 
+static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
+                                       int rd, int rs, int rt)
+{
+    int ret = rd;
+    TCGv t0 = tcg_temp_new();
+    TCGv v1_t = tcg_temp_new();
+    TCGv v2_t = tcg_temp_new();
+
+    gen_load_gpr(v1_t, rs);
+    gen_load_gpr(v2_t, rt);
+
+    switch (opc) {
+    case NM_CMP_EQ_PH:
+        check_dsp(ctx);
+        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMP_LT_PH:
+        check_dsp(ctx);
+        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMP_LE_PH:
+        check_dsp(ctx);
+        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMPU_EQ_QB:
+        check_dsp(ctx);
+        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMPU_LT_QB:
+        check_dsp(ctx);
+        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMPU_LE_QB:
+        check_dsp(ctx);
+        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
+        break;
+    case NM_CMPGU_EQ_QB:
+        check_dsp(ctx);
+        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_CMPGU_LT_QB:
+        check_dsp(ctx);
+        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_CMPGU_LE_QB:
+        check_dsp(ctx);
+        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_CMPGDU_EQ_QB:
+        check_dspr2(ctx);
+        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
+        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_CMPGDU_LT_QB:
+        check_dspr2(ctx);
+        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
+        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_CMPGDU_LE_QB:
+        check_dspr2(ctx);
+        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
+        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PACKRL_PH:
+        check_dsp(ctx);
+        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PICK_QB:
+        check_dsp(ctx);
+        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PICK_PH:
+        check_dsp(ctx);
+        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_ADDQ_S_W:
+        check_dsp(ctx);
+        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SUBQ_S_W:
+        check_dsp(ctx);
+        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_ADDSC:
+        check_dsp(ctx);
+        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_ADDWC:
+        check_dsp(ctx);
+        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_ADDQ_S_PH:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDQ_PH */
+            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDQ_S_PH */
+            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_ADDQH_R_PH:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDQH_PH */
+            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDQH_R_PH */
+            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_ADDQH_R_W:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDQH_W */
+            gen_helper_addqh_w(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDQH_R_W */
+            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_ADDU_S_QB:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDU_QB */
+            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDU_S_QB */
+            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_ADDU_S_PH:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDU_PH */
+            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDU_S_PH */
+            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_ADDUH_R_QB:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* ADDUH_QB */
+            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* ADDUH_R_QB */
+            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SHRAV_R_PH:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SHRAV_PH */
+            gen_helper_shra_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SHRAV_R_PH */
+            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SHRAV_R_QB:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SHRAV_QB */
+            gen_helper_shra_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SHRAV_R_QB */
+            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBQ_S_PH:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBQ_PH */
+            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBQ_S_PH */
+            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBQH_R_PH:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBQH_PH */
+            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBQH_R_PH */
+            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBQH_R_W:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBQH_W */
+            gen_helper_subqh_w(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBQH_R_W */
+            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBU_S_QB:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBU_QB */
+            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBU_S_QB */
+            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBU_S_PH:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBU_PH */
+            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBU_S_PH */
+            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SUBUH_R_QB:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SUBUH_QB */
+            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SUBUH_R_QB */
+            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_SHLLV_S_PH:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SHLLV_PH */
+            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* SHLLV_S_PH */
+            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_PRECR_SRA_R_PH_W:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* PRECR_SRA_PH_W */
+            {
+                TCGv_i32 sa_t = tcg_const_i32(rd);
+                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
+                                          cpu_gpr[rt]);
+                gen_store_gpr(v1_t, rt);
+                tcg_temp_free_i32(sa_t);
+            }
+            break;
+        case 1:
+            /* PRECR_SRA_R_PH_W */
+            {
+                TCGv_i32 sa_t = tcg_const_i32(rd);
+                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
+                                            cpu_gpr[rt]);
+                gen_store_gpr(v1_t, rt);
+                tcg_temp_free_i32(sa_t);
+            }
+            break;
+       }
+        break;
+    case NM_MULEU_S_PH_QBL:
+        check_dsp(ctx);
+        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULEU_S_PH_QBR:
+        check_dsp(ctx);
+        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULQ_RS_PH:
+        check_dsp(ctx);
+        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULQ_S_PH:
+        check_dspr2(ctx);
+        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULQ_RS_W:
+        check_dspr2(ctx);
+        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULQ_S_W:
+        check_dspr2(ctx);
+        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_APPEND:
+        check_dspr2(ctx);
+        gen_load_gpr(t0, rs);
+        if (rd != 0) {
+            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
+        }
+        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
+        break;
+    case NM_MODSUB:
+        check_dsp(ctx);
+        gen_helper_modsub(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHRAV_R_W:
+        check_dsp(ctx);
+        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHRLV_PH:
+        check_dspr2(ctx);
+        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHRLV_QB:
+        check_dsp(ctx);
+        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHLLV_QB:
+        check_dsp(ctx);
+        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHLLV_S_W:
+        check_dsp(ctx);
+        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHILO:
+        check_dsp(ctx);
+        {
+            TCGv tv0 = tcg_temp_new();
+            TCGv tv1 = tcg_temp_new();
+            int16_t imm = extract32(ctx->opcode, 16, 7);
+
+            tcg_gen_movi_tl(tv0, rd >> 3);
+            tcg_gen_movi_tl(tv1, imm);
+            gen_helper_shilo(tv0, tv1, cpu_env);
+        }
+        break;
+    case NM_MULEQ_S_W_PHL:
+        check_dsp(ctx);
+        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MULEQ_S_W_PHR:
+        check_dsp(ctx);
+        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_MUL_S_PH:
+        check_dspr2(ctx);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* MUL_PH */
+            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        case 1:
+            /* MUL_S_PH */
+            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
+            gen_store_gpr(v1_t, ret);
+            break;
+        }
+        break;
+    case NM_PRECR_QB_PH:
+        check_dspr2(ctx);
+        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PRECRQ_QB_PH:
+        check_dsp(ctx);
+        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PRECRQ_PH_W:
+        check_dsp(ctx);
+        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PRECRQ_RS_PH_W:
+        check_dsp(ctx);
+        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_PRECRQU_S_QB_PH:
+        check_dsp(ctx);
+        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
+        gen_store_gpr(v1_t, ret);
+        break;
+    case NM_SHRA_R_W:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, rd);
+        gen_helper_shra_r_w(v1_t, t0, v1_t);
+        gen_store_gpr(v1_t, rt);
+        break;
+    case NM_SHRA_R_PH:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, rd >> 1);
+        switch (extract32(ctx->opcode, 10, 1)) {
+        case 0:
+            /* SHRA_PH */
+            gen_helper_shra_ph(v1_t, t0, v1_t);
+            break;
+            gen_store_gpr(v1_t, rt);
+        case 1:
+            /* SHRA_R_PH */
+            gen_helper_shra_r_ph(v1_t, t0, v1_t);
+            gen_store_gpr(v1_t, rt);
+            break;
+        }
+        break;
+    case NM_SHLL_S_PH:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, rd >> 1);
+        switch (extract32(ctx->opcode, 10, 2)) {
+        case 0:
+            /* SHLL_PH */
+            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
+            gen_store_gpr(v1_t, rt);
+            break;
+        case 2:
+            /* SHLL_S_PH */
+            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
+            gen_store_gpr(v1_t, rt);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_SHLL_S_W:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, rd);
+        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
+        gen_store_gpr(v1_t, rt);
+        break;
+    case NM_REPL_PH:
+        check_dsp(ctx);
+        {
+            int16_t imm;
+            imm = extract32(ctx->opcode, 11, 11);
+            imm = (int16_t)(imm << 6) >> 6;
+            if (rt != 0) {
+                tcg_gen_movi_tl(cpu_gpr[rt], \
+                                (target_long)((int32_t)imm << 16 | \
+                                (uint16_t)imm));
+            }
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+}
+
 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
 {
     uint16_t insn;
@@ -17828,6 +18378,12 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
         case NM_POOL32A0:
             gen_pool32a0_nanomips_insn(env, ctx);
             break;
+        case NM_POOL32A5:
+            {
+                int32_t op1 = extract32(ctx->opcode, 3, 7);
+                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
+            }
+            break;
         case NM_POOL32A7:
             switch (extract32(ctx->opcode, 3, 3)) {
             case NM_P_LSX:
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 46/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (44 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 47/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 3 Aleksandar Markovic
                   ` (42 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 2.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index de10a07..0e2af0d 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -19017,6 +19017,16 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
                 case NM_BC1NEZC:
                     gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rt, s, 0);
                     break;
+                case NM_BPOSGE32C:
+                    check_dspr2(ctx);
+                    {
+                        int32_t imm = extract32(ctx->opcode, 1, 13) |
+                                      extract32(ctx->opcode, 0, 1) << 13;
+
+                        gen_compute_branch(ctx, OPC_BPOSGE32, 4, -1, -2,
+                                           imm, 4);
+                    }
+                    break;
                 default:
                     generate_exception_end(ctx, EXCP_RI);
                     break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 47/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 3
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (45 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 46/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4 Aleksandar Markovic
                   ` (41 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 3.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 183 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 183 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 0e2af0d..c03908b 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17110,13 +17110,194 @@ static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
     }
 }
 
+/* dsp */
+static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                            int ret, int v1, int v2)
+{
+    TCGv_i32 t0;
+    TCGv v0_t;
+    TCGv v1_t;
+
+    t0 = tcg_temp_new_i32();
+
+    v0_t = tcg_temp_new();
+    v1_t = tcg_temp_new();
+
+    tcg_gen_movi_i32(t0, v2 >> 3);
+
+    gen_load_gpr(v0_t, ret);
+    gen_load_gpr(v1_t, v1);
+
+    switch (opc) {
+    case NM_MAQ_S_W_PHR:
+        check_dsp(ctx);
+        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
+        break;
+    case NM_MAQ_S_W_PHL:
+        check_dsp(ctx);
+        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
+        break;
+    case NM_MAQ_SA_W_PHR:
+        check_dsp(ctx);
+        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
+        break;
+    case NM_MAQ_SA_W_PHL:
+        check_dsp(ctx);
+        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free_i32(t0);
+
+    tcg_temp_free(v0_t);
+    tcg_temp_free(v1_t);
+}
+
+
+static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                    int ret, int v1, int v2)
+{
+    int16_t imm;
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    TCGv v0_t = tcg_temp_new();
+
+    gen_load_gpr(v0_t, v1);
+
+    switch (opc) {
+    case NM_POOL32AXF_1_0:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 12, 2)) {
+        case NM_MFHI:
+            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
+            break;
+        case NM_MFLO:
+            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
+            break;
+        case NM_MTHI:
+            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
+            break;
+        case NM_MTLO:
+            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_1_1:
+        check_dsp(ctx);
+        switch (extract32(ctx->opcode, 12, 2)) {
+        case NM_MTHLIP:
+            tcg_gen_movi_tl(t0, v2);
+            gen_helper_mthlip(t0, v0_t, cpu_env);
+            break;
+        case NM_SHILOV:
+            tcg_gen_movi_tl(t0, v2 >> 3);
+            gen_helper_shilo(t0, v0_t, cpu_env);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_1_3:
+        check_dsp(ctx);
+        imm = extract32(ctx->opcode, 14, 7);
+        switch (extract32(ctx->opcode, 12, 2)) {
+        case NM_RDDSP:
+            tcg_gen_movi_tl(t0, imm);
+            gen_helper_rddsp(t0, t0, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_WRDSP:
+            gen_load_gpr(t0, ret);
+            tcg_gen_movi_tl(t1, imm);
+            gen_helper_wrdsp(t0, t1, cpu_env);
+            break;
+        case NM_EXTP:
+            tcg_gen_movi_tl(t0, v2 >> 3);
+            tcg_gen_movi_tl(t1, v1);
+            gen_helper_extp(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_EXTPDP:
+            tcg_gen_movi_tl(t0, v2 >> 3);
+            tcg_gen_movi_tl(t1, v1);
+            gen_helper_extpdp(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_1_4:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, v2 >> 2);
+        switch (extract32(ctx->opcode, 12, 1)) {
+        case NM_SHLL_QB:
+            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_SHRL_QB:
+            gen_helper_shrl_qb(t0, t0, v0_t);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_1_5:
+        opc = extract32(ctx->opcode, 12, 2);
+        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
+        break;
+    case NM_POOL32AXF_1_7:
+        check_dsp(ctx);
+        tcg_gen_movi_tl(t0, v2 >> 3);
+        tcg_gen_movi_tl(t1, v1);
+        switch (extract32(ctx->opcode, 12, 2)) {
+        case NM_EXTR_W:
+            gen_helper_extr_w(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_EXTR_R_W:
+            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_EXTR_RS_W:
+            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_EXTR_S_H:
+            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+    tcg_temp_free(v0_t);
+}
+
+
 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
     int rt = extract32(ctx->opcode, 21, 5);
     int rs = extract32(ctx->opcode, 16, 5);
+    int rd = extract32(ctx->opcode, 11, 5);
 
     switch (extract32(ctx->opcode, 6, 3)) {
+    case NM_POOL32AXF_1:
+        {
+            int32_t op1 = extract32(ctx->opcode, 9, 3);
+            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
+        }
+        break;
+    case NM_POOL32AXF_2:
+        break;
     case NM_POOL32AXF_4:
+        break;
     case NM_POOL32AXF_5:
         switch (extract32(ctx->opcode, 9, 7)) {
 #ifndef CONFIG_USER_ONLY
@@ -17185,6 +17366,8 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
             break;
         }
         break;
+    case NM_POOL32AXF_7:
+        break;
     default:
         generate_exception_end(ctx, EXCP_RI);
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (46 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 47/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 3 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:31   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 49/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 5 Aleksandar Markovic
                   ` (40 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 4.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 363 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 363 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index c03908b..68b3599 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17280,6 +17280,365 @@ static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(v0_t);
 }
 
+static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
+                                    TCGv v0, TCGv v1, int rd)
+{
+    TCGv_i32 t0;
+
+    t0 = tcg_temp_new_i32();
+
+    tcg_gen_movi_i32(t0, rd >> 3);
+
+    switch (opc) {
+    case NM_POOL32AXF_2_0_7:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPA_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPAQ_S_W_PH:
+            check_dsp(ctx);
+            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPS_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPSQ_S_W_PH:
+            check_dsp(ctx);
+            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_8_15:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAX_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPAQ_SA_L_W:
+            check_dsp(ctx);
+            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPSX_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPSQ_SA_L_W:
+            check_dsp(ctx);
+            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_16_23:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAU_H_QBL:
+            check_dsp(ctx);
+            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPAQX_S_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPSU_H_QBL:
+            check_dsp(ctx);
+            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
+            break;
+        case NM_DPSQX_S_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
+            break;
+        case NM_MULSA_W_PH:
+            check_dspr2(ctx);
+            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_24_31:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAU_H_QBR:
+            check_dsp(ctx);
+            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPAQX_SA_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPSU_H_QBR:
+            check_dsp(ctx);
+            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
+            break;
+        case NM_DPSQX_SA_W_PH:
+            check_dspr2(ctx);
+            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
+            break;
+        case NM_MULSAQ_S_W_PH:
+            check_dsp(ctx);
+            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free_i32(t0);
+}
+
+static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                          int rt, int rs, int rd)
+{
+    int ret = rt;
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    TCGv v0_t = tcg_temp_new();
+    TCGv v1_t = tcg_temp_new();
+
+    gen_load_gpr(v0_t, rt);
+    gen_load_gpr(v1_t, rs);
+
+    switch (opc) {
+    case NM_POOL32AXF_2_0_7:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPA_W_PH:
+        case NM_DPAQ_S_W_PH:
+        case NM_DPS_W_PH:
+        case NM_DPSQ_S_W_PH:
+            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
+            break;
+        case NM_BALIGN:
+            check_dspr2(ctx);
+            if (rt != 0) {
+                gen_load_gpr(t0, rs);
+                rd &= 3;
+                if (rd != 0 && rd != 2) {
+                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
+                    tcg_gen_ext32u_tl(t0, t0);
+                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
+                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
+                }
+                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
+            }
+            break;
+        case NM_MADD:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i64 t2 = tcg_temp_new_i64();
+                TCGv_i64 t3 = tcg_temp_new_i64();
+
+                gen_load_gpr(t0, rt);
+                gen_load_gpr(t1, rs);
+                tcg_gen_ext_tl_i64(t2, t0);
+                tcg_gen_ext_tl_i64(t3, t1);
+                tcg_gen_mul_i64(t2, t2, t3);
+                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+                tcg_gen_add_i64(t2, t2, t3);
+                tcg_temp_free_i64(t3);
+                gen_move_low32(cpu_LO[acc], t2);
+                gen_move_high32(cpu_HI[acc], t2);
+                tcg_temp_free_i64(t2);
+            }
+            break;
+        case NM_MULT:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i32 t2 = tcg_temp_new_i32();
+                TCGv_i32 t3 = tcg_temp_new_i32();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_trunc_tl_i32(t2, t0);
+                tcg_gen_trunc_tl_i32(t3, t1);
+                tcg_gen_muls2_i32(t2, t3, t2, t3);
+                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
+                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
+                tcg_temp_free_i32(t2);
+                tcg_temp_free_i32(t3);
+            }
+            break;
+        case NM_EXTRV_W:
+            check_dsp(ctx);
+            gen_load_gpr(v1_t, rs);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_8_15:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAX_W_PH:
+        case NM_DPAQ_SA_L_W:
+        case NM_DPSX_W_PH:
+        case NM_DPSQ_SA_L_W:
+            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
+            break;
+        case NM_MADDU:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i64 t2 = tcg_temp_new_i64();
+                TCGv_i64 t3 = tcg_temp_new_i64();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_ext32u_tl(t0, t0);
+                tcg_gen_ext32u_tl(t1, t1);
+                tcg_gen_extu_tl_i64(t2, t0);
+                tcg_gen_extu_tl_i64(t3, t1);
+                tcg_gen_mul_i64(t2, t2, t3);
+                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+                tcg_gen_add_i64(t2, t2, t3);
+                tcg_temp_free_i64(t3);
+                gen_move_low32(cpu_LO[acc], t2);
+                gen_move_high32(cpu_HI[acc], t2);
+                tcg_temp_free_i64(t2);
+            }
+            break;
+        case NM_MULTU:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i32 t2 = tcg_temp_new_i32();
+                TCGv_i32 t3 = tcg_temp_new_i32();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_trunc_tl_i32(t2, t0);
+                tcg_gen_trunc_tl_i32(t3, t1);
+                tcg_gen_mulu2_i32(t2, t3, t2, t3);
+                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
+                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
+                tcg_temp_free_i32(t2);
+                tcg_temp_free_i32(t3);
+            }
+            break;
+        case NM_EXTRV_R_W:
+            check_dsp(ctx);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        default:
+            generate_exception_end(ctx, EXCP_RI);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_16_23:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAU_H_QBL:
+        case NM_DPAQX_S_W_PH:
+        case NM_DPSU_H_QBL:
+        case NM_DPSQX_S_W_PH:
+        case NM_MULSA_W_PH:
+            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
+            break;
+        case NM_EXTPV:
+            check_dsp(ctx);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extp(t0, t0, v1_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_MSUB:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i64 t2 = tcg_temp_new_i64();
+                TCGv_i64 t3 = tcg_temp_new_i64();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_ext_tl_i64(t2, t0);
+                tcg_gen_ext_tl_i64(t3, t1);
+                tcg_gen_mul_i64(t2, t2, t3);
+                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+                tcg_gen_sub_i64(t2, t3, t2);
+                tcg_temp_free_i64(t3);
+                gen_move_low32(cpu_LO[acc], t2);
+                gen_move_high32(cpu_HI[acc], t2);
+                tcg_temp_free_i64(t2);
+            }
+            break;
+        case NM_EXTRV_RS_W:
+            check_dsp(ctx);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    case NM_POOL32AXF_2_24_31:
+        switch (extract32(ctx->opcode, 9, 3)) {
+        case NM_DPAU_H_QBR:
+        case NM_DPAQX_SA_W_PH:
+        case NM_DPSU_H_QBR:
+        case NM_DPSQX_SA_W_PH:
+        case NM_MULSAQ_S_W_PH:
+            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
+            break;
+        case NM_EXTPDPV:
+            check_dsp(ctx);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        case NM_MSUBU:
+            check_dsp(ctx);
+            {
+                int acc = extract32(ctx->opcode, 14, 2);
+                TCGv_i64 t2 = tcg_temp_new_i64();
+                TCGv_i64 t3 = tcg_temp_new_i64();
+
+                gen_load_gpr(t0, rs);
+                gen_load_gpr(t1, rt);
+                tcg_gen_ext32u_tl(t0, t0);
+                tcg_gen_ext32u_tl(t1, t1);
+                tcg_gen_extu_tl_i64(t2, t0);
+                tcg_gen_extu_tl_i64(t3, t1);
+                tcg_gen_mul_i64(t2, t2, t3);
+                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
+                tcg_gen_sub_i64(t2, t3, t2);
+                tcg_temp_free_i64(t3);
+                gen_move_low32(cpu_LO[acc], t2);
+                gen_move_high32(cpu_HI[acc], t2);
+                tcg_temp_free_i64(t2);
+            }
+            break;
+        case NM_EXTRV_S_H:
+            check_dsp(ctx);
+            tcg_gen_movi_tl(t0, rd >> 3);
+            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
+            gen_store_gpr(t0, ret);
+            break;
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+
+    tcg_temp_free(v0_t);
+    tcg_temp_free(v1_t);
+}
+
 
 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
@@ -17295,6 +17654,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32AXF_2:
+        {
+            int32_t op1 = extract32(ctx->opcode, 12, 2);
+            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
+        }
         break;
     case NM_POOL32AXF_4:
         break;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 49/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 5
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (47 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 50/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6 Aleksandar Markovic
                   ` (39 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 5.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 68b3599..00d1164 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17639,6 +17639,144 @@ static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(v1_t);
 }
 
+static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                          int rt, int rs)
+{
+    int ret = rt;
+    TCGv t0 = tcg_temp_new();
+    TCGv v0_t = tcg_temp_new();
+
+    gen_load_gpr(v0_t, rs);
+
+    switch (opc) {
+    case NM_ABSQ_S_QB:
+        check_dspr2(ctx);
+        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_ABSQ_S_PH:
+        check_dsp(ctx);
+        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_ABSQ_S_W:
+        check_dsp(ctx);
+        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQ_W_PHL:
+        check_dsp(ctx);
+        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
+        tcg_gen_ext32s_tl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQ_W_PHR:
+        check_dsp(ctx);
+        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
+        tcg_gen_shli_tl(v0_t, v0_t, 16);
+        tcg_gen_ext32s_tl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQU_PH_QBL:
+        check_dsp(ctx);
+        gen_helper_precequ_ph_qbl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQU_PH_QBR:
+        check_dsp(ctx);
+        gen_helper_precequ_ph_qbr(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQU_PH_QBLA:
+        check_dsp(ctx);
+        gen_helper_precequ_ph_qbla(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEQU_PH_QBRA:
+        check_dsp(ctx);
+        gen_helper_precequ_ph_qbra(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEU_PH_QBL:
+        check_dsp(ctx);
+        gen_helper_preceu_ph_qbl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEU_PH_QBR:
+        check_dsp(ctx);
+        gen_helper_preceu_ph_qbr(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEU_PH_QBLA:
+        check_dsp(ctx);
+        gen_helper_preceu_ph_qbla(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_PRECEU_PH_QBRA:
+        check_dsp(ctx);
+        gen_helper_preceu_ph_qbra(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_REPLV_PH:
+        check_dsp(ctx);
+        tcg_gen_ext16u_tl(v0_t, v0_t);
+        tcg_gen_shli_tl(t0, v0_t, 16);
+        tcg_gen_or_tl(v0_t, v0_t, t0);
+        tcg_gen_ext32s_tl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_REPLV_QB:
+        check_dsp(ctx);
+        tcg_gen_ext8u_tl(v0_t, v0_t);
+        tcg_gen_shli_tl(t0, v0_t, 8);
+        tcg_gen_or_tl(v0_t, v0_t, t0);
+        tcg_gen_shli_tl(t0, v0_t, 16);
+        tcg_gen_or_tl(v0_t, v0_t, t0);
+        tcg_gen_ext32s_tl(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_BITREV:
+        check_dsp(ctx);
+        gen_helper_bitrev(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_INSV:
+        check_dsp(ctx);
+        {
+            TCGv tv0 = tcg_temp_new();
+
+            gen_load_gpr(tv0, rt);
+            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
+            gen_store_gpr(v0_t, ret);
+            tcg_temp_free(tv0);
+        }
+        break;
+    case NM_RADDU_W_QB:
+        check_dsp(ctx);
+        gen_helper_raddu_w_qb(v0_t, v0_t);
+        gen_store_gpr(v0_t, ret);
+        break;
+    case NM_BITSWAP:
+        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
+        break;
+    case NM_CLO:
+        gen_cl(ctx, OPC_CLO, ret, rs);
+        break;
+    case NM_CLZ:
+        gen_cl(ctx, OPC_CLZ, ret, rs);
+        break;
+    case NM_WSBH:
+        gen_bshfl(ctx, OPC_WSBH, ret, rs);
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+
+    tcg_temp_free(v0_t);
+    tcg_temp_free(t0);
+}
+
 
 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
@@ -17660,6 +17798,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32AXF_4:
+        {
+            int32_t op1 = extract32(ctx->opcode, 9, 7);
+            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
+        }
         break;
     case NM_POOL32AXF_5:
         switch (extract32(ctx->opcode, 9, 7)) {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 50/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (48 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 49/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 5 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 51/87] disas: Add support for microMIPS and nanoMIPS Aleksandar Markovic
                   ` (38 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add emulation of DSP ASE instructions for nanoMIPS - part 6.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 00d1164..3282fca 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -17777,6 +17777,64 @@ static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
     tcg_temp_free(t0);
 }
 
+static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
+                                          int rt, int rs, int rd)
+{
+    TCGv t0;
+    TCGv rs_t;
+
+    if (rt == 0) {
+        /* Treat as NOP. */
+        return;
+    }
+
+    t0 = tcg_temp_new();
+    rs_t = tcg_temp_new();
+
+    gen_load_gpr(rs_t, rs);
+
+    switch (opc) {
+    case NM_SHRA_R_QB:
+        check_dspr2(ctx);
+        tcg_gen_movi_tl(t0, rd >> 2);
+        switch (extract32(ctx->opcode, 12, 1)) {
+        case 0:
+            /* NM_SHRA_QB */
+            gen_helper_shra_qb(cpu_gpr[rt], t0, rs_t);
+            break;
+        case 1:
+            /* NM_SHRA_R_QB */
+            gen_helper_shra_r_qb(cpu_gpr[rt], t0, rs_t);
+            break;
+        }
+        break;
+    case NM_SHRL_PH:
+        check_dspr2(ctx);
+        tcg_gen_movi_tl(t0, rd >> 1);
+        gen_helper_shrl_ph(cpu_gpr[rt], t0, rs_t);
+        break;
+    case NM_REPL_QB:
+        check_dsp(ctx);
+        {
+            int16_t imm;
+            target_long result;
+            imm = extract32(ctx->opcode, 13, 8);
+            result = (uint32_t)imm << 24 |
+                     (uint32_t)imm << 16 |
+                     (uint32_t)imm << 8  |
+                     (uint32_t)imm;
+            result = (int32_t)result;
+            tcg_gen_movi_tl(cpu_gpr[rt], result);
+        }
+        break;
+    default:
+        generate_exception_end(ctx, EXCP_RI);
+        break;
+    }
+    tcg_temp_free(t0);
+    tcg_temp_free(rs_t);
+}
+
 
 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
 {
@@ -17872,6 +17930,10 @@ static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
         }
         break;
     case NM_POOL32AXF_7:
+        {
+            int32_t op1 = extract32(ctx->opcode, 9, 3);
+            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
+        }
         break;
     default:
         generate_exception_end(ctx, EXCP_RI);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 51/87] disas: Add support for microMIPS and nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (49 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 50/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6 Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS Aleksandar Markovic
                   ` (37 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Matthew Fortune <matthew.fortune@mips.com>

Modify disassembler engine to execute a separate disassembler
for microMIPS and nanoMIPS platforms.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 disas/Makefile.objs |     1 +
 disas/mips.c        |   358 +-
 disas/nanomips.cpp  | 15752 ++++++++++++++++++++++++++++++++++++++++++++++++++
 disas/nanomips.h    |  1208 ++++
 include/disas/bfd.h |     1 +
 target/mips/cpu.c   |    12 +-
 6 files changed, 17329 insertions(+), 3 deletions(-)
 create mode 100644 disas/nanomips.cpp
 create mode 100644 disas/nanomips.h

diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 213be2f..b31a7c2 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_I386_DIS) += i386.o
 common-obj-$(CONFIG_M68K_DIS) += m68k.o
 common-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
 common-obj-$(CONFIG_MIPS_DIS) += mips.o
+common-obj-$(CONFIG_MIPS_DIS) += nanomips.o
 common-obj-$(CONFIG_NIOS2_DIS) += nios2.o
 common-obj-$(CONFIG_MOXIE_DIS) += moxie.o
 common-obj-$(CONFIG_PPC_DIS) += ppc.o
diff --git a/disas/mips.c b/disas/mips.c
index 97f661a..5b02de1 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -558,6 +558,8 @@ struct mips_opcode
 #define INSN_ISA32R6              0x00000200
 #define INSN_ISA64R6              0x00000400
 
+#define INSN_ISANANOMIPS32        0x00000800
+
 /* Masks used for MIPS-defined ASEs.  */
 #define INSN_ASE_MASK		  0x0000f000
 
@@ -1167,6 +1169,8 @@ extern const int bfd_mips16_num_opcodes;
 #define I32R6   INSN_ISA32R6
 #define I64R6   INSN_ISA64R6
 
+#define M32R7   INSN_ISANANOMIPS32
+
 /* MIPS64 MIPS-3D ASE support.  */
 #define I16     INSN_MIPS16
 
@@ -5086,7 +5090,7 @@ print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
 {
   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
 }
-\f

+
 /* Disassemble mips16 instructions.  */
 #if 0
 static int
@@ -5798,3 +5802,355 @@ with the -M switch (multiple options should be separated by commas):\n");
   fprintf (stream, "\n");
 }
 #endif
+
+const struct mips_opcode micromips_opcodes[] = {
+/*
+ * These instructions appear first so that the disassembler will find
+ *  them first.  The assemblers uses a hash table based on the
+ *  instruction name anyhow.
+ */
+
+/* name,        args,       match,      mask,       pinfo,        membership */
+{"add",         "d,t,v",    0x20000110, 0xfc0003ff, WR_t,         0, M32R7},
+/* put sigrie before addiu */
+{"sigrie",      "mij",      0x00000000, 0xffe00000, WR_d,         0, M32R7},
+{"addiu",       "v,t,mid",  0x00000000, 0xfc006000, WR_d,         0, M32R7},
+/* addiugp */
+{"addiu",       "v,m8,mik", 0x40000000, 0xfc000003, WR_d,         0, M32R7},
+{"au20ipc",     "v,miv",    0xe0000002, 0xfc000002, WR_d,         0, M32R7},
+/* aluipcgp */
+{"alu20ipc",    "m8,miv",   0xe0000002, 0xffe00002, WR_d,         0, M32R7},
+{"addu",        "d,t,v",    0x20000150, 0xfc0003ff, WR_d,         0, M32R7},
+{"align",       "d,t,v",    0x2000001f, 0xfc00003f, WR_d,         0, M32R7},
+{"and",         "d,t,v",    0x20000250, 0xfc0003ff, WR_d,         0, M32R7},
+{"andi",        "v,t,miC",  0x80002000, 0xfc00f000, WR_d,         0, M32R7},
+{"balc",        "map",      0x2a000000, 0xfe000000, WR_d,         0, M32R7},
+{"bc",          "map",      0x28000000, 0xfc000000, WR_d,         0, M32R7},
+{"beqc",        "t,v,mae",  0x88000000, 0xfc00c000, WR_d,         0, M32R7},
+{"beqic",      "v,miB,mab", 0xc8000000, 0xfc1c0000, WR_d,         0, M32R7},
+{"beqzc",       "v,mak",    0xe8000000, 0xfc100000, WR_d,         0, M32R7},
+{"bgec",        "t,v,mae",  0x88008000, 0xfc00c000, WR_d,         0, M32R7},
+{"bgeic",      "v,miB,mab", 0xc8080000, 0xfc1c0000, WR_d,         0, M32R7},
+{"bgeuc",       "t,v,mae",  0x8800c000, 0xfc00c000, WR_d,         0, M32R7},
+{"bgeiuc",     "v,miB,mab", 0xc80c0000, 0xfc1c0000, WR_d,         0, M32R7},
+{"bitswap",     "v,t",      0x20000b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"bltc",        "t,v,mae",  0xa8008000, 0xfc00c000, WR_d,         0, M32R7},
+{"bltic",      "v,miB,mab", 0xc8180000, 0xfc1c0000, WR_d,         0, M32R7},
+{"bltuc",       "t,v,mae",  0xa800c000, 0xfc00c000, WR_d,         0, M32R7},
+{"bltiuc",     "v,miB,mab", 0xc81c0000, 0xfc1c0000, WR_d,         0, M32R7},
+{"bnec",        "t,v,mae",  0xa8000000, 0xfc00c000, WR_d,         0, M32R7},
+{"bneic",      "v,miB,mab", 0xc8100000, 0xfc1c0000, WR_d,         0, M32R7},
+{"bnezc",       "v,mak",    0xe8100000, 0xfc100000, WR_d,         0, M32R7},
+{"break",       "mij",      0x00100000, 0xfff80000, WR_d,         0, M32R7},
+{"cache",       "6,mi8(t)", 0xa4001900, 0xfc007f00, WR_d,         0, M32R7},
+{"clo",         "v,t",      0x20004b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"clz",         "v,t",      0x20005b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"di",          "",         0x2000477f, 0xffe0ffff, WR_d,         0, M32R7},
+{"di",          "v",        0x2000477f, 0xfc00ffff, WR_d,         0, M32R7},
+{"div",         "d,t,v",    0x20000118, 0xfc0003ff, WR_d,         0, M32R7},
+{"divu",        "d,t,v",    0x20000198, 0xfc0003ff, WR_d,         0, M32R7},
+{"ei",          "",         0x2000577f, 0xffe0ffff, WR_d,         0, M32R7},
+{"ei",          "v",        0x2000577f, 0xfc00ffff, WR_d,         0, M32R7},
+{"eret",        "",         0x2000f37f, 0xfc01ffff, WR_d,         0, M32R7},
+{"eretnc",      "",         0x2001f37f, 0xfc01ffff, WR_d,         0, M32R7},
+{"ext",      "v,t,mi5,miz", 0x8000f000, 0xfc00f820, WR_d,         0, M32R7},
+{"ins",      "v,t,mi5,miZ", 0x8000e000, 0xfc00f820, WR_d,         0, M32R7},
+{"jalrc",       "v,t",      0x48000000, 0xfc00f000, WR_d,         0, M32R7},
+{"jalrc.hb",    "v,t",      0x48001000, 0xfc00f000, WR_d,         0, M32R7},
+{"lb",          "v,mic(t)", 0x84000000, 0xfc00f000, WR_d,         0, M32R7},
+/* lbgp */
+{"lb",         "v,mii(m8)", 0x44000000, 0xfc1c0000, WR_d,         0, M32R7},
+/* lbs9 */
+{"lb",          "v,mi8(t)", 0xa4000000, 0xfc007f00, WR_d,         0, M32R7},
+{"lbu",         "v,mic(t)", 0x84002000, 0xfc00f000, WR_d,         0, M32R7},
+/* lbugp */
+{"lbu",        "v,mii(m8)", 0x44080000, 0xfc1c0000, WR_d,         0, M32R7},
+/* lbus9 */
+{"lbu",         "v,mi8(t)", 0xa4001000, 0xfc007f00, WR_d,         0, M32R7},
+{"lbux",        "d,t(v)",   0x40000107, 0xfc0007ff, WR_d,         0, M32R7},
+{"lbx",         "d,t(v)",   0x40000107, 0xfc000007, WR_d,         0, M32R7},
+{"lh",          "v,mic(t)", 0x84004000, 0xfc00f000, WR_d,         0, M32R7},
+/* lhgp */
+{"lh",         "v,mii(m8)", 0x44100000, 0xfc1c0000, WR_d,         0, M32R7},
+/* lhs9 */
+{"lh",          "v,mi8(t)", 0xa4002000, 0xfc007f00, WR_d,         0, M32R7},
+{"lhu",         "v,mic(t)", 0x84006000, 0xfc00f000, WR_d,         0, M32R7},
+/* lhugp */
+{"lhu",        "v,mii(m8)", 0x44180000, 0xfc1c0000, WR_d,         0, M32R7},
+/* lhus9 */
+{"lhu",         "v,mi8(t)", 0xa4003000, 0xfc007f00, WR_d,         0, M32R7},
+{"lhux",        "d,t(v)",   0x40000307, 0xfc0007ff, WR_d,         0, M32R7},
+{"lhuxs",       "d,t(v)",   0x40000347, 0xfc0007ff, WR_d,         0, M32R7},
+{"lhx",         "d,t(v)",   0x40000207, 0xfc0007ff, WR_d,         0, M32R7},
+{"lhxs",        "d,t(v)",   0x40000247, 0xfc0007ff, WR_d,         0, M32R7},
+{"ll",          "v,mi8(t)", 0xa4004100, 0xfc007f03, WR_d,         0, M32R7},
+{"llwp",        "v,mu,(t)", 0xa4004101, 0xfc007f03, WR_d,         0, M32R7},
+{"lsa",        "d,t,v,mi(", 0x4000000f, 0xfc00003f, WR_d,         0, M32R7},
+{"lu20i",       "v,miv",    0xe0000000, 0xfc000002, WR_t,         0, M32R7},
+{"lw",          "v,mic(t)", 0x84008000, 0xfc00f000, WR_d,         0, M32R7},
+/* lws9 */
+{"lw",          "v,mi8(t)", 0xa4004000, 0xfc007f00, WR_d,         0, M32R7},
+/* lwgp */
+{"lw",         "v,mik(m8)", 0x40000002, 0xfc000003, WR_d,         0, M32R7},
+{"lwx",         "d,t(v)",   0x20000407, 0xfc0007ff, WR_d,         0, M32R7},
+{"lwxs",        "d,t(v)",   0x20000447, 0xfc0007ff, WR_d,         0, M32R7},
+{"mfc0",        "v,mG",     0x20000030, 0xfc003bff, WR_d,         0, M32R7},
+{"mfc0",        "v,mD",     0x20000030, 0xfc0003ff, WR_d,         0, M32R7},
+{"mod",         "d,t,v",    0x20000158, 0xfc0003ff, WR_d,         0, M32R7},
+{"modu",        "d,t,v",    0x200001d8, 0xfc0003ff, WR_d,         0, M32R7},
+{"move.balc",  "mo,ml,mal", 0x08000000, 0xfc000000, WR_d,         0, M32R7},
+{"movn",        "d,t,v",    0x20000610, 0xfc0007ff, WR_d,         0, M32R7},
+{"movz",        "d,t,v",    0x20000210, 0xfc0007ff, WR_d,         0, M32R7},
+{"mtc0",        "v,mG",     0x20000070, 0xfc003bff, WR_d,         0, M32R7},
+{"mtc0",        "v,mD",     0x20000070, 0xfc0003ff, WR_d,         0, M32R7},
+{"muh",         "d,t,v",    0x20000058, 0xfc0003ff, WR_d,         0, M32R7},
+{"muhu",        "d,t,v",    0x200000d8, 0xfc0003ff, WR_d,         0, M32R7},
+{"mul",         "d,t,v",    0x20000018, 0xfc0003ff, WR_d,         0, M32R7},
+{"mulu",        "d,t,v",    0x20000098, 0xfc0003ff, WR_d,         0, M32R7},
+{"nop",         "",         0x8000c000, 0xffe0f1ff, WR_d,         0, M32R7},
+{"nor",         "d,t,v",    0x200002d0, 0xfc0003ff, WR_d,         0, M32R7},
+{"or",          "d,t,v",    0x20000290, 0xfc0003ff, WR_d,         0, M32R7},
+{"ori",         "v,t,miC",  0x80000000, 0xfc00f000, WR_d,         0, M32R7},
+{"pause",       "",         0x8000c005, 0xffe0f1ff, WR_d,         0, M32R7},
+/* put synci before pref */
+{"synci",       "mi8(t)",   0xa7e01800, 0xffe07f00, WR_d,         0, M32R7},
+{"pref",      "miL,mi8(t)", 0xa4001800, 0xfc007f00, WR_d,         0, M32R7},
+{"rdhwr",       "v,mg",     0x200001c0, 0xfc0003ff, WR_d,         0, M32R7},
+{"rdpgpr",      "v,t",      0x2000e17f, 0xfc00ffff, WR_d,         0, M32R7},
+{"restore",     "mib,v",    0x80013000, 0xfc01f004, WR_d,         0, M32R7},
+{"restore.jrc", "mib,v",    0x80013004, 0xfc01f004, WR_d,         0, M32R7},
+{"rotr",        "v,t,mi5",  0x8000c0c0, 0xfc00f1e0, WR_d,         0, M32R7},
+{"rotrv",       "d,t,v",    0x200000d0, 0xfc0003ff, WR_d,         0, M32R7},
+{"save",        "mib,v",    0x80003000, 0xfc01f000, WR_d,         0, M32R7},
+{"sb",          "v,mic(t)", 0x84001000, 0xfc00f000, WR_d,         0, M32R7},
+/* sbs9 */
+{"sb",          "v,mi8(t)", 0xa4000800, 0xfc007f00, WR_d,         0, M32R7},
+/* sbgp */
+{"sb",         "v,mii(m8)", 0x44040000, 0xfc1c0000, WR_d,         0, M32R7},
+{"sbx",         "d,t(v)",   0x20000087, 0xfc0007ff, WR_d,         0, M32R7},
+{"sc",          "v,mi8(t)", 0xa4004900, 0xfc007f03, WR_d,         0, M32R7},
+{"scwp",        "v,m3,(t)", 0xa4004901, 0xfc007f03, WR_d,         0, M32R7},
+{"seb",         "v,t",      0x20002b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"seh",         "v,t",      0x20003b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"seqi",        "v,t,mic",  0x20006000, 0xfc00f000, WR_d,         0, M32R7},
+{"sh",          "v,mic(t)", 0x84005000, 0xfc00f000, WR_d,         0, M32R7},
+/* shs9 */
+{"sh",          "v,mi8(t)", 0xa4002800, 0xfc007f00, WR_d,         0, M32R7},
+/* shgp */
+{"sh",         "v,mii(m8)", 0x44140000, 0xfc1c0000, WR_d,         0, M32R7},
+{"shx",         "d,t(v)",   0x20000287, 0xfc0007ff, WR_d,         0, M32R7},
+{"shxs",        "d,t(v)",   0x200002c7, 0xfc0007ff, WR_d,         0, M32R7},
+/* put sync/ehb before sll */
+{"sync",        "miG",      0x8000c006, 0xffe0f1ff, WR_d,         0, M32R7},
+{"ehb",         "",         0x8000c003, 0xffe0f1ff, WR_d,         0, M32R7},
+{"sll",         "v,t,mi5",  0x8000c000, 0xfc00f1e0, WR_d,         0, M32R7},
+{"sllv",        "d,t,v",    0x20000010, 0xfc0003ff, WR_d,         0, M32R7},
+{"slt",         "d,t,v",    0x20000350, 0xfc0003ff, WR_d,         0, M32R7},
+{"slti",        "v,t,mic",  0x80004000, 0xfc00f000, WR_d,         0, M32R7},
+{"sltiu",       "v,t,mic",  0x80005000, 0xfc00f000, WR_d,         0, M32R7},
+{"sltu",        "d,t,v",    0x20000390, 0xfc0003ff, WR_d,         0, M32R7},
+{"sov",         "d,t,v",    0x200003d0, 0xfc0003ff, WR_d,         0, M32R7},
+{"sra",         "v,t,mi5",  0x8000c080, 0xfc00f1e0, WR_d,         0, M32R7},
+{"srav",        "d,t,v",    0x20000090, 0xfc0003ff, WR_d,         0, M32R7},
+{"srl",         "v,t,mi5",  0x8000c040, 0xfc00f1e0, WR_d,         0, M32R7},
+{"srlv",        "d,t,v",    0x20000050, 0xfc0003ff, WR_d,         0, M32R7},
+{"sub",         "d,t,v",    0x20000190, 0xfc0003ff, WR_d,         0, M32R7},
+{"subu",        "d,t,v",    0x200001d0, 0xfc0003ff, WR_d,         0, M32R7},
+{"sw",          "v,mic(t)", 0x84009000, 0xfc00f000, WR_d,         0, M32R7},
+/* sws9 */
+{"sw",          "v,mi8(t)", 0xa4004800, 0xfc007f00, WR_d,         0, M32R7},
+/* swgp */
+{"sw",         "v,mik(m8)", 0x40000003, 0xfc000003, WR_d,         0, M32R7},
+{"swx",         "d,t(v)",   0x20000487, 0xfc0007ff, WR_d,         0, M32R7},
+{"swxs",        "d,t(v)",   0x200004c7, 0xfc0007ff, WR_d,         0, M32R7},
+{"syscall",     "mii",      0x00080000, 0xfffc0000, WR_d,         0, M32R7},
+{"ualw",        "v,mi8(t)", 0xa4000100, 0xfc007f00, WR_d,         0, M32R7},
+{"uasw",        "v,mi8(t)", 0xa4000900, 0xfc007f00, WR_d,         0, M32R7},
+{"wait",        "miG",      0x2000c37f, 0xfc00ffff, WR_d,         0, M32R7},
+{"wrpgpr",      "v,t",      0x2000f17f, 0xfc00ffff, WR_d,         0, M32R7},
+{"wsbh",        "v,t",      0x20007b3f, 0xfc00ffff, WR_d,         0, M32R7},
+{"xor",         "d,t,v",    0x20000310, 0xfc0003ff, WR_d,         0, M32R7},
+{"xori",        "v,t,miC",  0x80001000, 0xfc00f000, WR_d,         0, M32R7},
+{"deret",       "",         0x2000e37f, 0xfc00ffff, WR_d,         0, M32R7},
+{"sdbbp",       "mij",      0x00180000, 0xfff80000, WR_d,         0, M32R7},
+{"tlbinv",      "",         0x2000077f, 0xfc00ffff, WR_d,         0, M32R7},
+{"tlbinvf",     "",         0x2000177f, 0xfc00ffff, WR_d,         0, M32R7},
+{"tlbp",        "",         0x2000037f, 0xfc00ffff, WR_d,         0, M32R7},
+{"tlbr",        "",         0x2000137f, 0xfc00ffff, WR_d,         0, M32R7},
+{"tlbwi",       "",         0x2000237f, 0xfc00ffff, WR_d,         0, M32R7},
+{"tlbwr",       "",         0x2000337f, 0xfc00ffff, WR_d,         0, M32R7},
+{"dvp",         "v",        0x20000390, 0xfc00ffff, WR_d,         0, M32R7},
+{"evp",         "v",        0x20000790, 0xfc00ffff, WR_d,         0, M32R7},
+{"balrc",       "v,t",      0x48008000, 0xfc00f200, WR_d,         0, M32R7},
+{"balrsc",      "v,t",      0x48008200, 0xfc00f200, WR_d,         0, M32R7},
+{"brc",         "t",        0x48008000, 0xffe0f200, WR_d,         0, M32R7},
+{"brsc",        "t",        0x48008200, 0xffe0f200, WR_d,         0, M32R7},
+/* ADDIU48 */
+{"addiu",       "v,miw",    0x60010000, 0xfc1f0000, WR_d,         0, M32R7},
+/* ADDIUGP48 */
+{"addiu",       "v,m8,miw", 0x60020000, 0xfc1f0000, WR_d,         0, M32R7},
+/* li48 */
+{"li",          "v,miw",    0x60000000, 0xfc1f0000, WR_d,         0, M32R7},
+
+/*  put before addiurs5 */
+{"nop",         "",         0x9008,     0xffff,     WR_t,         0, M32R7},
+/* addiu r1 sp */
+{"addiu",      "mt,m9,mi7", 0x7040,     0xfc40,     WR_t,         0, M32R7},
+/* addiu r2 */
+{"addiu",      "mt,ms,mi4", 0x9000,     0xfc08,     WR_t,         0, M32R7},
+/* addiu rs5 */
+{"addiu",       "m5,mi3",   0x9008,     0xfc08,     WR_t,         0, M32R7},
+{"addu",        "md,ms,mt", 0xb000,     0xfc01,     WR_t,         0, M32R7},
+{"and",         "mt,ms",    0x5008,     0xfc0f,     WR_t,         0, M32R7},
+{"andi",       "mt,ms,mi0", 0xf000,     0xfc00,     WR_t,         0, M32R7},
+{"balc",        "maa",      0x3800,     0xfc00,     WR_t,         0, M32R7},
+{"bc",          "maa",      0x1800,     0xfc00,     WR_t,         0, M32R7},
+/*  put jrc, jalrc before b{eq|ne}c */
+{"jrc",         "m5",       0xd800,     0xfc1f,     WR_t,         0, M32R7},
+{"jalrc",       "m5",       0xd810,     0xfc1f,     WR_t,         0, M32R7},
+/* b{eq|ne}c */
+{"",         "mQmt,ms,ma4", 0xd800,     0xfc00,     WR_t,         0, M32R7},
+{"beqzc",       "mt,ma7",   0x9800,     0xfc00,     WR_t,         0, M32R7},
+{"bnezc",       "mt,ma7",   0xb800,     0xfc00,     WR_t,         0, M32R7},
+{"break",       "mi2",      0x1010,     0xfff8,     WR_t,         0, M32R7},
+
+{"lb",        "mt,mi1(ms)", 0x1400,     0xfc0c,     WR_t,         0, M32R7},
+{"lbu",        "mt,mi1(ms", 0x1408,     0xfc0c,     WR_t,         0, M32R7},
+{"lh",        "mt,mi@(ms)", 0x3400,     0xfc09,     WR_t,         0, M32R7},
+{"lhu",       "mt,mi@(ms)", 0x3408,     0xfc09,     WR_t,         0, M32R7},
+{"li",          "mt,mi)",   0xd000,     0xfc00,     WR_t,         0, M32R7},
+
+/* lw 4x4 */
+{"lw",        "m(,mi#(m$)", 0x9400,     0xfc00,     WR_t,         0, M32R7},
+{"lw",        "mt,mi%(ms)", 0x7400,     0xfc00,     WR_t,         0, M32R7},
+/* lwgp16 */
+{"lw",        "mt,mi*(m8)", 0xb400,     0xfc00,     WR_t,         0, M32R7},
+/* lwsp */
+{"lw",        "m5,mi6(m9)", 0x5400,     0xfc00,     WR_t,         0, M32R7},
+{"lwxs",       "md,ms(mt)", 0x5001,     0xfc01,     WR_t,         0, M32R7},
+/* put sdbbp befroe move */
+{"sdbbp",       "mi2",      0x1018,     0xfff8,     WR_t,         0, M32R7},
+{"move",        "m5,m0",    0x1000,     0xfc00,     WR_t,         0, M32R7},
+{"movep",       "mP",       0xbc00,     0xfc00,     WR_t,         0, M32R7},
+/* moveprev */
+{"movep",       "mV",       0xfc00,     0xfc00,     WR_t,         0, M32R7},
+{"not",         "mt,ms",    0x5000,     0xfc0f,     WR_t,         0, M32R7},
+{"or",          "mt,ms",    0x500c,     0xfc0f,     WR_t,         0, M32R7},
+{"restore",     "mi^",      0x1fe0,     0xffe1,     WR_t,         0, M32R7},
+{"restore.jrc", "mi^",      0x1c20,     0xfc21,     WR_t,         0, M32R7},
+{"save",        "mi^",      0x1c00,     0xfc21,     WR_t,         0, M32R7},
+{"sb",        "mT,mi1(ms)", 0x1404,     0xfc0c,     WR_t,         0, M32R7},
+{"sh",        "mT,mi@(ms)", 0x1401,     0xfc09,     WR_t,         0, M32R7},
+{"sll",        "mt,ms,mi2", 0x3000,     0xfc08,     WR_t,         0, M32R7},
+{"srl",        "mt,ms,mi2", 0x3008,     0xfc08,     WR_t,         0, M32R7},
+{"subu",        "md,ms,mt", 0xb001,     0xfc01,     WR_t,         0, M32R7},
+{"sw",        "mT,mi%(ms)", 0xf400,     0xfc00,     WR_t,         0, M32R7},
+/* swsp */
+{"sw",        "m5,mi6(m9)", 0xd400,     0xfc00,     WR_t,         0, M32R7},
+/* sw 4x4 */
+{"sw",        "m(,mi#(m$)", 0x9c00,     0xfc00,     WR_t,         0, M32R7},
+{"syscall",     "mi1",      0x1008,     0xfffc,     WR_t,         0, M32R7},
+{"xor",         "mt,ms",    0x5004,     0xfc0f,     WR_t,         0, M32R7},
+};
+
+#define MICROMIPS_NUM_OPCODES \
+    ((sizeof micromips_opcodes) / (sizeof(micromips_opcodes[0])))
+const int bfd_micromips_num_opcodes = MICROMIPS_NUM_OPCODES;
+
+/* The mips16 registers.  */
+
+/*
+ * static const unsigned int umips_decode_gpr3[] =
+ *      { 16, 17, 18, 19, 4, 5, 6, 7};
+ *
+ * static const unsigned int umips_decode_gpr3_src_store[] =
+ *      {  0, 17, 18, 19, 4, 5, 6, 7};
+ */
+
+#define umips_decode_gpr3_reg_names(rn) mips_gpr_names[umips_decode_gpr3[rn]]
+#define umips_decode_gpr3_src_store_reg_names(rn) \
+    mips_gpr_names[umips_decode_gpr3_src_store[rn]]
+
+int nanomips_dis(char *buf, unsigned address, unsigned short one,
+                 unsigned short two, unsigned short three);
+
+int print_insn_micromips(bfd_vma memaddr, struct disassemble_info *info)
+{
+    int status;
+    bfd_byte buffer[2];
+    uint16_t insn1 = 0, insn2 = 0, insn3 = 0;
+    char buf[200];
+
+    info->bytes_per_chunk = 2;
+    info->display_endian = info->endian;
+    info->insn_info_valid = 1;
+    info->branch_delay_insns = 0;
+    info->data_size = 0;
+    info->insn_type = dis_nonbranch;
+    info->target = 0;
+    info->target2 = 0;
+
+    set_default_mips_dis_options(info);
+    parse_mips_dis_options(info->disassembler_options);
+
+    status = (*info->read_memory_func)(memaddr, buffer, 2, info);
+    if (status != 0) {
+        (*info->memory_error_func)(status, memaddr, info);
+        return -1;
+    }
+
+    if (info->endian == BFD_ENDIAN_BIG) {
+        insn1 = bfd_getb16(buffer);
+    } else {
+        insn1 = bfd_getl16(buffer);
+    }
+    (*info->fprintf_func)(info->stream, "%04x ", insn1);
+
+    /* Handle 32-bit opcodes.  */
+    if ((insn1 & 0x1000) == 0) {
+        status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info);
+        if (status != 0) {
+            (*info->memory_error_func)(status, memaddr + 2, info);
+            return -1;
+        }
+
+        if (info->endian == BFD_ENDIAN_BIG) {
+            insn2 = bfd_getb16(buffer);
+        } else {
+            insn2 = bfd_getl16(buffer);
+        }
+        (*info->fprintf_func)(info->stream, "%04x ", insn2);
+    } else {
+        (*info->fprintf_func)(info->stream, "     ");
+    }
+    /* Handle 48-bit opcodes.  */
+    if ((insn1 >> 10) == 0x18) {
+        status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info);
+        if (status != 0) {
+            (*info->memory_error_func)(status, memaddr + 4, info);
+            return -1;
+        }
+
+        if (info->endian == BFD_ENDIAN_BIG) {
+            insn3 = bfd_getb16(buffer);
+        } else {
+            insn3 = bfd_getl16(buffer);
+        }
+        (*info->fprintf_func)(info->stream, "%04x ", insn3);
+    } else {
+        (*info->fprintf_func)(info->stream, "     ");
+    }
+
+    int length = nanomips_dis(buf, memaddr, insn1, insn2, insn3);
+
+    /* FIXME: Should probably use a hash table on the major opcode here.  */
+
+    (*info->fprintf_func) (info->stream, "%s", buf);
+    if (length > 0) {
+        return length / 8;
+    }
+
+    info->insn_type = dis_noninsn;
+
+    return insn3 ? 6 : insn2 ? 4 : 2;
+}
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
new file mode 100644
index 0000000..35c3973
--- /dev/null
+++ b/disas/nanomips.cpp
@@ -0,0 +1,15752 @@
+
+#include <cstring>
+#include <stdexcept>
+#include <sstream>
+
+#define INCLUDE_STANDALONE_UNIT_TEST
+
+#ifdef INCLUDE_STANDALONE_UNIT_TEST
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "nanomips.h"
+
+#define IMGASSERTONCE(test)
+
+namespace img
+{
+    address addr32(address a)
+    {
+        return a;
+    }
+
+    std::string format(const char *format, ...)
+    {
+        char buffer[256];
+        va_list args;
+        va_start(args, format);
+        int err = vsprintf(buffer, format, args);
+        if (err < 0) {
+            perror(buffer);
+        }
+        va_end(args);
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       std::string s2)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), s2.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       std::string s2,
+                       std::string s3)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       std::string s2,
+                       std::string s3,
+                       std::string s4)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(),
+                                s4.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       std::string s2,
+                       std::string s3,
+                       std::string s4,
+                       std::string s5)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), s2.c_str(), s3.c_str(),
+                                s4.c_str(), s5.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       uint64 d,
+                       std::string s2)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, d, s2.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       uint64 d,
+                       std::string s2)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), d, s2.c_str());
+
+        return buffer;
+    }
+
+    std::string format(const char *format,
+                       std::string s1,
+                       std::string s2,
+                       uint64 d)
+    {
+        char buffer[256];
+
+        sprintf(buffer, format, s1.c_str(), s2.c_str(), d);
+
+        return buffer;
+    }
+
+    char as_char(int c)
+    {
+        return static_cast<char>(c);
+    }
+};
+
+std::string to_string(img::address a)
+{
+    char buffer[256];
+    sprintf(buffer, "0x%08llx", a);
+    return buffer;
+}
+
+#else
+#include "imgleeds/imgleeds/format.h"
+#endif
+
+
+uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size)
+{
+    return (data << (64 - (bit_size + bit_offset))) >> (64 - bit_size);
+}
+
+int64 sign_extend(int64 data, int msb)
+{
+    uint64 shift = 63 - msb;
+    return (data << shift) >> shift;
+}
+
+uint64 NMD::renumber_registers(uint64 index, uint64 *register_list,
+                               size_t register_list_size)
+{
+    if (index < register_list_size) {
+        return register_list[index];
+    }
+
+    throw std::runtime_error(img::format(
+                   "Invalid register mapping index %d, size of list = %d",
+                   index, register_list_size));
+}
+
+/*
+ * these functions should be decode functions but the json does not have
+ * decode sections so they are based on the encode, the equivalent decode
+ * functions need writing eventually.
+ */
+uint64 NMD::encode_gpr3(uint64 d)
+{
+    static uint64 register_list[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_gpr3_store(uint64 d)
+{
+    static uint64 register_list[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_rd1_from_rd(uint64 d)
+{
+    static uint64 register_list[] = {  4,  5 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_gpr4_zero(uint64 d)
+{
+    static uint64 register_list[] = {  8,  9, 10,  0,  4,  5,  6,  7,
+                                      16, 17, 18, 19, 20, 21, 22, 23 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_gpr4(uint64 d)
+{
+    static uint64 register_list[] = {  8,  9, 10, 11,  4,  5,  6,  7,
+                                      16, 17, 18, 19, 20, 21, 22, 23 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_rd2_reg1(uint64 d)
+{
+    static uint64 register_list[] = {  4,  5,  6,  7 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+uint64 NMD::encode_rd2_reg2(uint64 d)
+{
+    static uint64 register_list[] = {  5,  6,  7,  8 };
+    return renumber_registers(d, register_list,
+               sizeof(register_list) / sizeof(register_list[0]));
+}
+
+uint64 NMD::copy(uint64 d)
+{
+    return d;
+}
+int64 NMD::copy(int64 d)
+{
+    return d;
+}
+int64 NMD::neg_copy(uint64 d)
+{
+    return 0ll - d;
+}
+int64 NMD::neg_copy(int64 d)
+{
+    return -d;
+}
+/* strange wrapper around  gpr3 */
+uint64 NMD::encode_rs3_and_check_rs3_ge_rt3(uint64 d)
+{
+return encode_gpr3(d);
+}
+/* strange wrapper around  gpr3 */
+uint64 NMD::encode_rs3_and_check_rs3_lt_rt3(uint64 d)
+{
+    return encode_gpr3(d);
+}
+/* nop - done by extraction function */
+uint64 NMD::encode_s_from_address(uint64 d)
+{
+    return d;
+}
+/* nop - done by extraction function */
+uint64 NMD::encode_u_from_address(uint64 d)
+{
+    return d;
+}
+/* nop - done by extraction function */
+uint64 NMD::encode_s_from_s_hi(uint64 d)
+{
+    return d;
+}
+uint64 NMD::encode_count3_from_count(uint64 d)
+{
+    IMGASSERTONCE(d < 8);
+    return d == 0ull ? 8ull : d;
+}
+uint64 NMD::encode_shift3_from_shift(uint64 d)
+{
+    IMGASSERTONCE(d < 8);
+    return d == 0ull ? 8ull : d;
+}
+/* special value for load literal */
+int64 NMD::encode_eu_from_s_li16(uint64 d)
+{
+    IMGASSERTONCE(d < 128);
+    return d == 127 ? -1 : (int64)d;
+}
+uint64 NMD::encode_msbd_from_size(uint64 d)
+{
+    IMGASSERTONCE(d < 32);
+    return d + 1;
+}
+uint64 NMD::encode_eu_from_u_andi16(uint64 d)
+{
+    IMGASSERTONCE(d < 16);
+    if (d == 12) {
+        return 0x00ffull;
+    }
+    if (d == 13) {
+        return 0xffffull;
+    }
+    return d;
+}
+uint64 NMD::encode_msbd_from_pos_and_size(uint64 d)
+{
+    IMGASSERTONCE(0);
+    return d;
+}
+/* save16 / restore16   ???? */
+uint64 NMD::encode_rt1_from_rt(uint64 d)
+{
+    return d ? 31 : 30;
+}
+/* ? */
+uint64 NMD::encode_lsb_from_pos_and_size(uint64 d)
+{
+    return d;
+}
+
+
+std::string NMD::save_restore_list(uint64 rt, uint64 count, uint64 gp)
+{
+    std::string str;
+
+    for (uint64 counter = 0; counter != count; counter++) {
+        bool use_gp = gp && (counter == count - 1);
+        uint64 this_rt = use_gp ? 28 : ((rt & 0x10) | (rt + counter)) & 0x1f;
+        str += img::format(",%s", GPR(this_rt));
+    }
+
+    return str;
+}
+
+std::string NMD::GPR(uint64 reg)
+{
+    static const char *gpr_reg[32] = {
+        "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
+        "a4",   "a5",   "a6",   "a7",   "r12",  "r13",  "r14",  "r15",
+        "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
+        "r24",  "r25",  "k0",   "k1",   "gp",   "sp",   "fp",   "ra"
+    };
+
+    if (reg < 32) {
+        return gpr_reg[reg];
+    }
+
+    throw std::runtime_error(img::format("Invalid GPR register index %d", reg));
+}
+
+std::string NMD::FPR(uint64 reg)
+{
+    static const char *fpr_reg[32] = {
+        "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
+        "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
+        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
+    };
+
+    if (reg < 32) {
+        return fpr_reg[reg];
+    }
+
+    throw std::runtime_error(img::format("Invalid FPR register index %d", reg));
+}
+
+std::string NMD::AC(uint64 reg)
+{
+    static const char *ac_reg[4] = {
+        "ac0",  "ac1",  "ac2",  "ac3"
+    };
+
+    if (reg < 4) {
+        return ac_reg[reg];
+    }
+
+    throw std::runtime_error(img::format("Invalid AC register index %d", reg));
+}
+
+std::string NMD::IMMEDIATE(uint64 value)
+{
+    return img::format("0x%x", value);
+}
+
+std::string NMD::IMMEDIATE(int64 value)
+{
+    return img::format("%d", value);
+}
+
+std::string NMD::CPR(uint64 reg)
+{
+    /* needs more work */
+    return img::format("CP%d", reg);
+}
+
+std::string NMD::ADDRESS(uint64 value, int instruction_size)
+{
+    /* token for string replace */
+    /* const char TOKEN_REPLACE = (char)0xa2; */
+    img::address address = m_pc + value + instruction_size;
+    /* symbol replacement */
+    /* return img::as_char(TOKEN_REPLACE) + to_string(address); */
+    return to_string(address);
+}
+
+uint64 NMD::extract_op_code_value(const uint16 * data, int size)
+{
+    switch (size) {
+    case 16:
+        return data[0];
+    case 32:
+        return ((uint64)data[0] << 16) | data[1];
+    case 48:
+        return ((uint64)data[0] << 32) | ((uint64)data[1] << 16) | data[2];
+    default:
+        return data[0];
+    }
+}
+
+/*
+ * Recurse through tables until the instruction is found then return
+ * the string and size
+ *
+ * inputs:
+ *      pointer to a word stream,
+ *      disassember table and size
+ * returns:
+ *      instruction size    - negative is error
+ *      disassembly string  - on error will constain error string
+ */
+int NMD::Disassemble(const uint16 * data, std::string & dis,
+                     NMD::TABLE_ENTRY_TYPE & type)
+{
+    return Disassemble(data, dis, type, MAJOR, 2);
+}
+
+
+int NMD::Disassemble(const uint16 * data, std::string & dis,
+                     NMD::TABLE_ENTRY_TYPE & type, const Pool *table,
+                     int table_size)
+{
+    try
+    {
+        for (int i = 0; i < table_size; i++) {
+            uint64 op_code = extract_op_code_value(data,
+                                 table[i].instructions_size);
+            if ((op_code & table[i].mask) == table[i].value) {
+                /* possible match */
+                conditional_function cond = table[i].condition;
+                if ((cond == 0) || (this->*cond)(op_code)) {
+                    try
+                    {
+                        if (table[i].type == pool) {
+                            return Disassemble(data, dis, type,
+                                               table[i].next_table,
+                                               table[i].next_table_size);
+                        } else if ((table[i].type == instruction) ||
+                                   (table[i].type == call_instruction) ||
+                                   (table[i].type == branch_instruction) ||
+                                   (table[i].type == return_instruction)) {
+                            if ((table[i].attributes != 0) &&
+                                (m_requested_instruction_catagories &
+                                 table[i].attributes) == 0) {
+                                /*
+                                 * failed due to instruction having
+                                 * an ASE attribute and the requested version
+                                 * not having that attribute
+                                 */
+                                dis = "ASE attribute missmatch";
+                                return -5;
+                            }
+                            disassembly_function dis_fn = table[i].disassembly;
+                            if (dis_fn == 0) {
+                                dis = "disassembler failure - bad table entry";
+                                return -6;
+                            }
+                            type = table[i].type;
+                            dis = (this->*dis_fn)(op_code);
+                            return table[i].instructions_size;
+                        } else {
+                            dis = "reserved instruction";
+                            return -2;
+                        }
+                    }
+                    catch (std::runtime_error & e)
+                    {
+                        dis = e.what();
+                        return -3;          /* runtime error */
+                    }
+                }
+            }
+        }
+    }
+    catch (std::exception & e)
+    {
+        dis = e.what();
+        return -4;          /* runtime error */
+    }
+
+    dis = "failed to disassemble";
+    return -1;      /* failed to disassemble        */
+}
+
+uint64 NMD::extr_codeil0il0bs19Fmsb18(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 19) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shift3il0il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil3il3bs9Fmsb11(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 9) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_countil0il0bs4Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 4) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rtz3il7il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 7, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil1il1bs17Fmsb17(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 1, 17) << 1;
+    return value;
+}
+
+
+int64 NMD::extr_sil11il0bs10Tmsb9(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 11, 10) << 0;
+    value = sign_extend(value, 9);
+    return value;
+}
+
+
+int64 NMD::extr_sil0il11bs1_il1il1bs10Tmsb11(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 11;
+    value |= extract_bits(instruction, 1, 10) << 1;
+    value = sign_extend(value, 11);
+    return value;
+}
+
+
+uint64 NMD::extr_uil10il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rtz4il21il0bs3_il25il3bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 3) << 0;
+    value |= extract_bits(instruction, 25, 1) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_sail11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftil0il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftxil7il1bs4Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 7, 4) << 1;
+    return value;
+}
+
+
+uint64 NMD::extr_hintil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_count3il12il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 12, 3) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 31;
+    value |= extract_bits(instruction, 2, 10) << 21;
+    value |= extract_bits(instruction, 12, 9) << 12;
+    value = sign_extend(value, 31);
+    return value;
+}
+
+
+int64 NMD::extr_sil0il7bs1_il1il1bs6Tmsb7(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 7;
+    value |= extract_bits(instruction, 1, 6) << 1;
+    value = sign_extend(value, 7);
+    return value;
+}
+
+
+uint64 NMD::extr_u2il9il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 9, 2) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_codeil16il0bs10Fmsb9(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       10) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rsil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil1il1bs2Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 1, 2) << 1;
+    return value;
+}
+
+
+uint64 NMD::extr_stripeil6il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil17il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 17, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil2il0bs1_il15il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 2, 1) << 0;
+    value |= extract_bits(instruction, 15, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_acil14il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 14, 2) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rd1il24il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 24, 1) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il10bs1_il1il1bs9Tmsb10(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 10;
+    value |= extract_bits(instruction, 1, 9) << 1;
+    value = sign_extend(value, 10);
+    return value;
+}
+
+
+uint64 NMD::extr_euil0il0bs7Fmsb6(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 7) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftil0il0bs6Fmsb5(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 6) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs6Fmsb5(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 6) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_countil16il0bs4Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       4) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_codeil0il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs4_il22il0bs4Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 4) << 0;
+    value |= extract_bits(instruction, 22, 4) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il0bs12Fmsb11(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 12) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rsil0il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil3il3bs18Fmsb20(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 18) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_xil12il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 12, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs4Fmsb5(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 4) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_cofunil3il0bs23Fmsb22(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 23) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs3Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rd3il1il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 1, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_sail12il0bs4Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 12, 4) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rtil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_ruil3il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil9il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 9, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il0bs18Fmsb17(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 18) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil14il0bs1_il15il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 14, 1) << 0;
+    value |= extract_bits(instruction, 15, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rsz4il0il0bs3_il4il3bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    value |= extract_bits(instruction, 4, 1) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_xil24il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 24, 1) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il21bs1_il1il1bs20Tmsb21(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 21;
+    value |= extract_bits(instruction, 1, 20) << 1;
+    value = sign_extend(value, 21);
+    return value;
+}
+
+
+uint64 NMD::extr_opil3il0bs23Fmsb22(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 23) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rs4il0il0bs3_il4il3bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    value |= extract_bits(instruction, 4, 1) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_bitil21il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rtil37il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 37, 5) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil16il0bs6Tmsb5(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 16,
+       6) << 0;
+    value = sign_extend(value, 5);
+    return value;
+}
+
+
+uint64 NMD::extr_xil6il0bs3_il10il0bs1Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 3) << 0;
+    value |= extract_bits(instruction, 10, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rd2il3il1bs1_il8il0bs1Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 1) << 1;
+    value |= extract_bits(instruction, 8, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_codeil0il0bs18Fmsb17(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 18) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil0il0bs12Fmsb11(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 12) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_sizeil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil2il2bs6_il15il8bs1Tmsb8(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 2, 6) << 2;
+    value |= extract_bits(instruction, 15, 1) << 8;
+    value = sign_extend(value, 8);
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il0bs16Fmsb15(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 16) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_fsil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il0bs8_il15il8bs1Tmsb8(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 8) << 0;
+    value |= extract_bits(instruction, 15, 1) << 8;
+    value = sign_extend(value, 8);
+    return value;
+}
+
+
+uint64 NMD::extr_stypeil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rt1il9il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 9, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_hsil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs1_il14il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 1) << 0;
+    value |= extract_bits(instruction, 14, 2) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_selil11il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_lsbil0il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil14il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 14, 2) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_gpil2il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 2, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rt3il7il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 7, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_ftil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil11il0bs7Fmsb6(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 7) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_csil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil16il0bs10Fmsb9(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       10) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rt4il5il0bs3_il9il3bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 5, 3) << 0;
+    value |= extract_bits(instruction, 9, 1) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_msbdil6il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs6Fmsb7(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 6) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_xil17il0bs9Fmsb8(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 17, 9) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_sail13il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 13, 3) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il14bs1_il1il1bs13Tmsb14(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 14;
+    value |= extract_bits(instruction, 1, 13) << 1;
+    value = sign_extend(value, 14);
+    return value;
+}
+
+
+uint64 NMD::extr_rs3il4il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 4, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il32bs32Fmsb63(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 32) << 32;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftil6il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_csil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_shiftxil6il0bs6Fmsb5(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 6) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_rtil5il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 5, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_opil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs7Fmsb8(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 7) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_bitil11il0bs6Fmsb5(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 6) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs1_il11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 10, 1) << 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_maskil14il0bs7Fmsb6(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 14, 7) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_euil0il0bs4Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 4) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil4il4bs4Fmsb7(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 4, 4) << 4;
+    return value;
+}
+
+
+int64 NMD::extr_sil3il3bs5_il15il8bs1Tmsb8(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 3, 5) << 3;
+    value |= extract_bits(instruction, 15, 1) << 8;
+    value = sign_extend(value, 8);
+    return value;
+}
+
+
+uint64 NMD::extr_ftil11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il16bs16_il16il0bs16Tmsb31(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 16) << 16;
+    value |= extract_bits(instruction, 16,
+       16) << 0;
+    value = sign_extend(value, 31);
+    return value;
+}
+
+
+uint64 NMD::extr_uil13il0bs8Fmsb7(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 13, 8) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil15il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 15, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil2il2bs16Fmsb17(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 2, 16) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_rdil11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_c0sil16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_codeil0il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 2) << 0;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il25bs1_il1il1bs24Tmsb25(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 1) << 25;
+    value |= extract_bits(instruction, 1, 24) << 1;
+    value = sign_extend(value, 25);
+    return value;
+}
+
+
+uint64 NMD::extr_xil0il0bs3_il4il0bs1Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    value |= extract_bits(instruction, 4, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 2) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil3il3bs1_il8il2bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 3, 1) << 3;
+    value |= extract_bits(instruction, 8, 1) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_xil9il0bs3_il16il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 9, 3) << 0;
+    value |= extract_bits(instruction, 16,
+       5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_fdil11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil6il0bs3Fmsb2(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 6, 3) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs5Fmsb6(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 5) << 2;
+    return value;
+}
+
+
+uint64 NMD::extr_rtz4il5il0bs3_il9il3bs1Fmsb3(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 5, 3) << 0;
+    value |= extract_bits(instruction, 9, 1) << 3;
+    return value;
+}
+
+
+uint64 NMD::extr_selil11il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_ctil21il0bs5Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 21, 5) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_xil11il0bs1Fmsb0(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 11, 1) << 0;
+    return value;
+}
+
+
+uint64 NMD::extr_uil2il2bs19Fmsb20(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 2, 19) << 2;
+    return value;
+}
+
+
+int64 NMD::extr_sil0il0bs3_il4il3bs1Tmsb3(uint64 instruction)
+{
+    int64 value = 0;
+    value |= extract_bits(instruction, 0, 3) << 0;
+    value |= extract_bits(instruction, 4, 1) << 3;
+    value = sign_extend(value, 3);
+    return value;
+}
+
+
+uint64 NMD::extr_uil0il1bs4Fmsb4(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 0, 4) << 1;
+    return value;
+}
+
+
+uint64 NMD::extr_xil9il0bs2Fmsb1(uint64 instruction)
+{
+    uint64 value = 0;
+    value |= extract_bits(instruction, 9, 2) << 0;
+    return value;
+}
+
+
+bool NMD::BNEC_16__cond(uint64 instruction)
+{
+    uint64 rs3 = extr_rs3il4il0bs3Fmsb2(instruction);
+    uint64 rt3 = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+    return rs3 >= rt3 && u != 0;
+}
+
+
+bool NMD::ADDIU_32__cond(uint64 instruction)
+{
+    uint64 rt = extr_rtil21il0bs5Fmsb4(instruction);
+    return rt != 0;
+}
+
+
+bool NMD::P16_BR1_cond(uint64 instruction)
+{
+    uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+    return u != 0;
+}
+
+
+bool NMD::ADDIU_RS5__cond(uint64 instruction)
+{
+    uint64 rt = extr_rtil5il0bs5Fmsb4(instruction);
+    return rt != 0;
+}
+
+
+bool NMD::BEQC_16__cond(uint64 instruction)
+{
+    uint64 rs3 = extr_rs3il4il0bs3Fmsb2(instruction);
+    uint64 rt3 = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+    return rs3 < rt3 && u != 0;
+}
+
+
+bool NMD::SLTU_cond(uint64 instruction)
+{
+    uint64 rd = extr_rdil11il0bs5Fmsb4(instruction);
+    return rd != 0;
+}
+
+
+bool NMD::PREF_S9__cond(uint64 instruction)
+{
+    uint64 hint = extr_hintil21il0bs5Fmsb4(instruction);
+    return hint != 31;
+}
+
+
+bool NMD::BALRSC_cond(uint64 instruction)
+{
+    uint64 rt = extr_rtil21il0bs5Fmsb4(instruction);
+    return rt != 0;
+}
+
+
+bool NMD::MOVE_cond(uint64 instruction)
+{
+    uint64 rt = extr_rtil5il0bs5Fmsb4(instruction);
+    return rt != 0;
+}
+
+
+bool NMD::PREFE_cond(uint64 instruction)
+{
+    uint64 hint = extr_hintil21il0bs5Fmsb4(instruction);
+    return hint != 31;
+}
+
+
+std::string NMD::SIGRIE(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs19Fmsb18(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("SIGRIE %s", code);
+}
+
+
+std::string NMD::SYSCALL_32_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs18Fmsb17(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("SYSCALL %s", code);
+}
+
+
+std::string NMD::HYPCALL(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs18Fmsb17(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("HYPCALL %s", code);
+}
+
+
+std::string NMD::BREAK_32_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs19Fmsb18(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("BREAK %s", code);
+}
+
+
+std::string NMD::SDBBP_32_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs19Fmsb18(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("SDBBP %s", code);
+}
+
+
+std::string NMD::ADDIU_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs16Fmsb15(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ADDIU %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::TEQ(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("TEQ %s, %s", rs, rt);
+}
+
+
+std::string NMD::TNE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("TNE %s, %s", rs, rt);
+}
+
+
+std::string NMD::SEB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SEB %s, %s", rt, rs);
+}
+
+
+std::string NMD::SLLV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SLLV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MUL_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MUL %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MFC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::MFHC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFHC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::SEH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SEH %s, %s", rt, rs);
+}
+
+
+std::string NMD::SRLV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SRLV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MUH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MUH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MTC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::MTHC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTHC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::SRAV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SRAV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MFGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::MFHGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFHGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::ROTRV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ROTRV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MUHU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MUHU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MTGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::MTHGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTHGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::ADD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADD %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DIV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DIV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMFC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("DMFC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::ADDU_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MOD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MOD %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMTC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("DMTC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::SUB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DIVU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DIVU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMFGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("DMFGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::RDHWR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 hs_value = extr_hsil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs3Fmsb2(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string hs = CPR(copy(hs_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("RDHWR %s, %s, %s", rt, hs, sel);
+}
+
+
+std::string NMD::SUBU_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MODU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MODU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMTGC0(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = CPR(copy(c0s_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("DMTGC0 %s, %s, %s", rt, c0s, sel);
+}
+
+
+std::string NMD::MOVZ(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MOVZ %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MOVN(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MOVN %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::FORK(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("FORK %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MFTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil10il0bs1Fmsb0(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = IMMEDIATE(copy(c0s_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFTR %s, %s, %s, %s", rt, c0s, u, sel);
+}
+
+
+std::string NMD::MFHTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil10il0bs1Fmsb0(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = IMMEDIATE(copy(c0s_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel);
+}
+
+
+std::string NMD::AND_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("AND %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::YIELD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("YIELD %s, %s", rt, rs);
+}
+
+
+std::string NMD::MTTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil10il0bs1Fmsb0(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = IMMEDIATE(copy(c0s_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTTR %s, %s, %s, %s", rt, c0s, u, sel);
+}
+
+
+std::string NMD::MTHTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 c0s_value = extr_c0sil16il0bs5Fmsb4(instruction);
+    uint64 sel_value = extr_selil11il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil10il0bs1Fmsb0(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string c0s = IMMEDIATE(copy(c0s_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string sel = IMMEDIATE(copy(sel_value));
+
+    return img::format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel);
+}
+
+
+std::string NMD::OR_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("OR %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMT(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMT %s", rt);
+}
+
+
+std::string NMD::DVPE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DVPE %s", rt);
+}
+
+
+std::string NMD::EMT(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("EMT %s", rt);
+}
+
+
+std::string NMD::EVPE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("EVPE %s", rt);
+}
+
+
+std::string NMD::NOR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("NOR %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::XOR_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("XOR %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SLT(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SLT %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DVP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DVP %s", rt);
+}
+
+
+std::string NMD::EVP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("EVP %s", rt);
+}
+
+
+std::string NMD::SLTU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SLTU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SOV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SOV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SPECIAL2(uint64 instruction)
+{
+    uint64 op_value = extr_opil3il0bs23Fmsb22(instruction);
+
+    std::string op = IMMEDIATE(copy(op_value));
+
+    return img::format("SPECIAL2 %s", op);
+}
+
+
+std::string NMD::COP2_1(uint64 instruction)
+{
+    uint64 cofun_value = extr_cofunil3il0bs23Fmsb22(instruction);
+
+    std::string cofun = IMMEDIATE(copy(cofun_value));
+
+    return img::format("COP2_1 %s", cofun);
+}
+
+
+std::string NMD::UDI(uint64 instruction)
+{
+    uint64 op_value = extr_opil3il0bs23Fmsb22(instruction);
+
+    std::string op = IMMEDIATE(copy(op_value));
+
+    return img::format("UDI %s", op);
+}
+
+
+std::string NMD::CMP_EQ_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMP.EQ.PH %s, %s", rs, rt);
+}
+
+
+std::string NMD::ADDQ_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQ.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDQ_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQ_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHILO(uint64 instruction)
+{
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    int64 s_value = extr_sil16il0bs6Tmsb5(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("SHILO %s, %s", ac, s);
+}
+
+
+std::string NMD::MULEQ_S_W_PHL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MUL_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MUL.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MUL_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MUL_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::REPL_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil11il0bs10Tmsb9(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("REPL.PH %s, %s", rt, s);
+}
+
+
+std::string NMD::CMP_LT_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMP.LT.PH %s, %s", rs, rt);
+}
+
+
+std::string NMD::ADDQH_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQH.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDQH_R_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQH_R.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULEQ_S_W_PHR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECR_QB_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PRECR.QB.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMP_LE_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMP.LE.PH %s, %s", rs, rt);
+}
+
+
+std::string NMD::ADDQH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQH.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDQH_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQH_R.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULEU_S_PH_QBL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECRQ_QB_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGU_EQ_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDU_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDU.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDU_S_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDU_S.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULEU_S_PH_QBR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECRQ_PH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGU_LT_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDU_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDU.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDU_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDU_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULQ_RS_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULQ_RS.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECRQ_RS_PH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGU_LE_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDUH_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDUH.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::ADDUH_R_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDUH_R.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MULQ_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULQ_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECRQU_S_QB_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGDU_EQ_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHRAV_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRAV.PH %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHRAV_R_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRAV_R.PH %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::MULQ_RS_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULQ_RS.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PACKRL_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PACKRL.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGDU_LT_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHRAV_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRAV.QB %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHRAV_R_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRAV_R.QB %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::MULQ_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULQ_S.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PICK_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PICK.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPGDU_LE_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBQ_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQ.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBQ_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQ_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::APPEND(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("APPEND %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::PICK_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("PICK.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPU_EQ_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPU.EQ.QB %s, %s", rs, rt);
+}
+
+
+std::string NMD::SUBQH_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQH.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBQH_R_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQH_R.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PREPEND(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("PREPEND %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::CMPU_LT_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPU.LT.QB %s, %s", rs, rt);
+}
+
+
+std::string NMD::SUBQH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQH.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBQH_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQH_R.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::MODSUB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MODSUB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::CMPU_LE_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("CMPU.LE.QB %s, %s", rs, rt);
+}
+
+
+std::string NMD::SUBU_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBU.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBU_S_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBU_S.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHRAV_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRAV_R.W %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHRA_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRA_R.W %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::ADDQ_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDQ_S.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBU_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBU.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBU_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBU_S.PH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHRLV_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRLV.PH %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHRA_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail12il0bs4Fmsb3(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRA.PH %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHRA_R_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail12il0bs4Fmsb3(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRA_R.PH %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SUBQ_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBQ_S.W %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBUH_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBUH.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SUBUH_R_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SUBUH_R.QB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHRLV_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHRLV.QB %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::ADDSC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDSC %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::SHLLV_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHLLV.PH %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHLLV_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHLLV_S.PH %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHLLV_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHLLV.QB %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHLL_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail12il0bs4Fmsb3(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHLL.PH %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHLL_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail12il0bs4Fmsb3(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHLL_S.PH %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::ADDWC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("ADDWC %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::PRECR_SRA_PH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHLLV_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHLLV_S.W %s, %s, %s", rd, rt, rs);
+}
+
+
+std::string NMD::SHLL_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHLL_S.W %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::LBX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LBX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SBX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SBX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LBUX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LBUX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LHX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LHX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SHX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SHX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LHUX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LHUX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWUX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWUX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SWX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SWX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWC1X(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWC1X %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::SWC1X(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SWC1X %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::LDX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LDX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SDX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SDX %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LDC1X(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LDC1X %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::SDC1X(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SDC1X %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::LHXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LHXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SHXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SHXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LHUXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LHUXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWUXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWUXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWXS_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SWXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SWXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LWC1XS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LWC1XS %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::SWC1XS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SWC1XS %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::LDXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LDXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::SDXS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SDXS %s, %s(%s)", rd, rs, rt);
+}
+
+
+std::string NMD::LDC1XS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("LDC1XS %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::SDC1XS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("SDC1XS %s, %s(%s)", ft, rs, rt);
+}
+
+
+std::string NMD::LSA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 u2_value = extr_u2il9il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string u2 = IMMEDIATE(copy(u2_value));
+
+    return img::format("LSA %s, %s, %s, %s", rd, rs, rt, u2);
+}
+
+
+std::string NMD::EXTW(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil6il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTW %s, %s, %s, %s", rd, rs, rt, shift);
+}
+
+
+std::string NMD::MFHI_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+
+    return img::format("MFHI %s, %s", rt, ac);
+}
+
+
+std::string NMD::MFLO_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+
+    return img::format("MFLO %s, %s", rt, ac);
+}
+
+
+std::string NMD::MTHI_DSP_(uint64 instruction)
+{
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string ac = AC(copy(ac_value));
+
+    return img::format("MTHI %s, %s", rs, ac);
+}
+
+
+std::string NMD::MTLO_DSP_(uint64 instruction)
+{
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string ac = AC(copy(ac_value));
+
+    return img::format("MTLO %s, %s", rs, ac);
+}
+
+
+std::string NMD::MTHLIP(uint64 instruction)
+{
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string ac = AC(copy(ac_value));
+
+    return img::format("MTHLIP %s, %s", rs, ac);
+}
+
+
+std::string NMD::SHILOV(uint64 instruction)
+{
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHILOV %s, %s", ac, rs);
+}
+
+
+std::string NMD::RDDSP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 mask_value = extr_maskil14il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string mask = IMMEDIATE(copy(mask_value));
+
+    return img::format("RDDSP %s, %s", rt, mask);
+}
+
+
+std::string NMD::WRDSP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 mask_value = extr_maskil14il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string mask = IMMEDIATE(copy(mask_value));
+
+    return img::format("WRDSP %s, %s", rt, mask);
+}
+
+
+std::string NMD::EXTP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 size_value = extr_sizeil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string size = IMMEDIATE(copy(size_value));
+
+    return img::format("EXTP %s, %s, %s", rt, ac, size);
+}
+
+
+std::string NMD::EXTPDP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 size_value = extr_sizeil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string size = IMMEDIATE(copy(size_value));
+
+    return img::format("EXTPDP %s, %s, %s", rt, ac, size);
+}
+
+
+std::string NMD::SHLL_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail13il0bs3Fmsb2(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHLL.QB %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHRL_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail13il0bs3Fmsb2(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRL.QB %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::MAQ_S_W_PHR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MAQ_SA_W_PHR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MAQ_S_W_PHL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MAQ_SA_W_PHL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTR_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil16il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTR.W %s, %s, %s", rt, ac, shift);
+}
+
+
+std::string NMD::EXTR_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil16il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTR_R.W %s, %s, %s", rt, ac, shift);
+}
+
+
+std::string NMD::EXTR_RS_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil16il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTR_RS.W %s, %s, %s", rt, ac, shift);
+}
+
+
+std::string NMD::EXTR_S_H(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil16il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTR_S.H %s, %s, %s", rt, ac, shift);
+}
+
+
+std::string NMD::DPA_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPA.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPAQ_S_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPS_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPS.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSQ_S_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MADD_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MADD %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MULT_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULT %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTRV_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTRV.W %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::DPAX_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAX.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPAQ_SA_L_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSX_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSX.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSQ_SA_L_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MADDU_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MADDU %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MULTU_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULTU %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTRV_R_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTRV_R.W %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::DPAU_H_QBL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAU.H.QBL %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPAQX_S_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSU_H_QBL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSU.H.QBL %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSQX_S_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTPV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTPV %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::MSUB_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MSUB %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MULSA_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULSA.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTRV_RS_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTRV_RS.W %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::DPAU_H_QBR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAU.H.QBR %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPAQX_SA_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSU_H_QBR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSU.H.QBR %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::DPSQX_SA_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTPDPV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTPDPV %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::MSUBU_DSP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MSUBU %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::MULSAQ_S_W_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt);
+}
+
+
+std::string NMD::EXTRV_S_H(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ac_value = extr_acil14il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ac = AC(copy(ac_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("EXTRV_S.H %s, %s, %s", rt, ac, rs);
+}
+
+
+std::string NMD::ABSQ_S_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("ABSQ_S.QB %s, %s", rt, rs);
+}
+
+
+std::string NMD::REPLV_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("REPLV.PH %s, %s", rt, rs);
+}
+
+
+std::string NMD::ABSQ_S_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("ABSQ_S.PH %s, %s", rt, rs);
+}
+
+
+std::string NMD::REPLV_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("REPLV.QB %s, %s", rt, rs);
+}
+
+
+std::string NMD::ABSQ_S_W(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("ABSQ_S.W %s, %s", rt, rs);
+}
+
+
+std::string NMD::INSV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("INSV %s, %s", rt, rs);
+}
+
+
+std::string NMD::CLO(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("CLO %s, %s", rt, rs);
+}
+
+
+std::string NMD::MFC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("MFC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEQ_W_PHL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQ.W.PHL %s, %s", rt, rs);
+}
+
+
+std::string NMD::CLZ(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("CLZ %s, %s", rt, rs);
+}
+
+
+std::string NMD::MTC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("MTC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEQ_W_PHR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQ.W.PHR %s, %s", rt, rs);
+}
+
+
+std::string NMD::DMFC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("DMFC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEQU_PH_QBL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQU.PH.QBL %s, %s", rt, rs);
+}
+
+
+std::string NMD::PRECEQU_PH_QBLA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQU.PH.QBLA %s, %s", rt, rs);
+}
+
+
+std::string NMD::DMTC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("DMTC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::MFHC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("MFHC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEQU_PH_QBR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQU.PH.QBR %s, %s", rt, rs);
+}
+
+
+std::string NMD::PRECEQU_PH_QBRA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEQU.PH.QBRA %s, %s", rt, rs);
+}
+
+
+std::string NMD::MTHC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("MTHC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEU_PH_QBL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEU.PH.QBL %s, %s", rt, rs);
+}
+
+
+std::string NMD::PRECEU_PH_QBLA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEU.PH.QBLA %s, %s", rt, rs);
+}
+
+
+std::string NMD::CFC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("CFC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::PRECEU_PH_QBR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEU.PH.QBR %s, %s", rt, rs);
+}
+
+
+std::string NMD::PRECEU_PH_QBRA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PRECEU.PH.QBRA %s, %s", rt, rs);
+}
+
+
+std::string NMD::CTC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("CTC2 %s, %s", rt, cs);
+}
+
+
+std::string NMD::RADDU_W_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("RADDU.W.QB %s, %s", rt, rs);
+}
+
+
+std::string NMD::TLBGP(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGP ";
+}
+
+
+std::string NMD::TLBP(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBP ";
+}
+
+
+std::string NMD::TLBGINV(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGINV ";
+}
+
+
+std::string NMD::TLBINV(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBINV ";
+}
+
+
+std::string NMD::TLBGR(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGR ";
+}
+
+
+std::string NMD::TLBR(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBR ";
+}
+
+
+std::string NMD::TLBGINVF(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGINVF ";
+}
+
+
+std::string NMD::TLBINVF(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBINVF ";
+}
+
+
+std::string NMD::TLBGWI(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGWI ";
+}
+
+
+std::string NMD::TLBWI(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBWI ";
+}
+
+
+std::string NMD::TLBGWR(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBGWR ";
+}
+
+
+std::string NMD::TLBWR(uint64 instruction)
+{
+    (void)instruction;
+
+    return "TLBWR ";
+}
+
+
+std::string NMD::DI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DI %s", rt);
+}
+
+
+std::string NMD::EI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("EI %s", rt);
+}
+
+
+std::string NMD::WAIT(uint64 instruction)
+{
+    uint64 code_value = extr_codeil16il0bs10Fmsb9(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("WAIT %s", code);
+}
+
+
+std::string NMD::IRET(uint64 instruction)
+{
+    (void)instruction;
+
+    return "IRET ";
+}
+
+
+std::string NMD::RDPGPR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("RDPGPR %s, %s", rt, rs);
+}
+
+
+std::string NMD::DERET(uint64 instruction)
+{
+    (void)instruction;
+
+    return "DERET ";
+}
+
+
+std::string NMD::WRPGPR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("WRPGPR %s, %s", rt, rs);
+}
+
+
+std::string NMD::ERET(uint64 instruction)
+{
+    (void)instruction;
+
+    return "ERET ";
+}
+
+
+std::string NMD::ERETNC(uint64 instruction)
+{
+    (void)instruction;
+
+    return "ERETNC ";
+}
+
+
+std::string NMD::SHRA_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail13il0bs3Fmsb2(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRA.QB %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHRA_R_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail13il0bs3Fmsb2(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRA_R.QB %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::SHRL_PH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 sa_value = extr_sail12il0bs4Fmsb3(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string sa = IMMEDIATE(copy(sa_value));
+
+    return img::format("SHRL.PH %s, %s, %s", rt, rs, sa);
+}
+
+
+std::string NMD::REPL_QB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil13il0bs8Fmsb7(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("REPL.QB %s, %s", rt, u);
+}
+
+
+std::string NMD::ADDIU_GP_W_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs19Fmsb20(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ADDIU %s, $%d, %s", rt, 28, u);
+}
+
+
+std::string NMD::LD_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil3il3bs18Fmsb20(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LD %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::SD_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil3il3bs18Fmsb20(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SD %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LW_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs19Fmsb20(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LW %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::SW_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs19Fmsb20(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SW %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LI_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("LI %s, %s", rt, s);
+}
+
+
+std::string NMD::ADDIU_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("ADDIU %s, %s", rt, s);
+}
+
+
+std::string NMD::ADDIU_GP48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("ADDIU %s, $%d, %s", rt, 28, s);
+}
+
+
+std::string NMD::ADDIUPC_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 6);
+
+    return img::format("ADDIUPC %s, %s", rt, s);
+}
+
+
+std::string NMD::LWPC_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 6);
+
+    return img::format("LWPC %s, %s", rt, s);
+}
+
+
+std::string NMD::SWPC_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 6);
+
+    return img::format("SWPC %s, %s", rt, s);
+}
+
+
+std::string NMD::DADDIU_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("DADDIU %s, %s", rt, s);
+}
+
+
+std::string NMD::DLUI_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il32bs32Fmsb63(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("DLUI %s, %s", rt, u);
+}
+
+
+std::string NMD::LDPC_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 6);
+
+    return img::format("LDPC %s, %s", rt, s);
+}
+
+
+std::string NMD::SDPC_48_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil37il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il16bs16_il16il0bs16Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 6);
+
+    return img::format("SDPC %s, %s", rt, s);
+}
+
+
+std::string NMD::ORI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ORI %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::XORI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("XORI %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::ANDI_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ANDI %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::SAVE_32_(uint64 instruction)
+{
+    uint64 count_value = extr_countil16il0bs4Fmsb3(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+    uint64 gp_value = extr_gpil2il0bs1Fmsb0(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    return img::format("SAVE %s%s", u,
+               save_restore_list(rt_value, count_value, gp_value));
+}
+
+
+std::string NMD::RESTORE_32_(uint64 instruction)
+{
+    uint64 count_value = extr_countil16il0bs4Fmsb3(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+    uint64 gp_value = extr_gpil2il0bs1Fmsb0(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    return img::format("RESTORE %s%s", u,
+               save_restore_list(rt_value, count_value, gp_value));
+}
+
+
+std::string NMD::RESTORE_JRC_32_(uint64 instruction)
+{
+    uint64 count_value = extr_countil16il0bs4Fmsb3(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+    uint64 gp_value = extr_gpil2il0bs1Fmsb0(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    return img::format("RESTORE.JRC %s%s", u,
+               save_restore_list(rt_value, count_value, gp_value));
+}
+
+
+std::string NMD::SAVEF(uint64 instruction)
+{
+    uint64 count_value = extr_countil16il0bs4Fmsb3(instruction);
+    uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string count = IMMEDIATE(copy(count_value));
+
+    return img::format("SAVEF %s, %s", u, count);
+}
+
+
+std::string NMD::RESTOREF(uint64 instruction)
+{
+    uint64 count_value = extr_countil16il0bs4Fmsb3(instruction);
+    uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string count = IMMEDIATE(copy(count_value));
+
+    return img::format("RESTOREF %s, %s", u, count);
+}
+
+
+std::string NMD::SLTI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SLTI %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::SLTIU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SLTIU %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::SEQI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SEQI %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::ADDIU_NEG_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(neg_copy(u_value));
+
+    return img::format("ADDIU %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::DADDIU_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("DADDIU %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::DADDIU_NEG_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string u = IMMEDIATE(neg_copy(u_value));
+
+    return img::format("DADDIU %s, %s, %s", rt, rs, u);
+}
+
+
+std::string NMD::DROTX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs6Fmsb5(instruction);
+    uint64 shiftx_value = extr_shiftxil6il0bs6Fmsb5(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+    std::string shiftx = IMMEDIATE(copy(shiftx_value));
+
+    return img::format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx);
+}
+
+
+std::string NMD::NOP_32_(uint64 instruction)
+{
+    (void)instruction;
+
+    return "NOP ";
+}
+
+
+std::string NMD::EHB(uint64 instruction)
+{
+    (void)instruction;
+
+    return "EHB ";
+}
+
+
+std::string NMD::PAUSE(uint64 instruction)
+{
+    (void)instruction;
+
+    return "PAUSE ";
+}
+
+
+std::string NMD::SYNC(uint64 instruction)
+{
+    uint64 stype_value = extr_stypeil16il0bs5Fmsb4(instruction);
+
+    std::string stype = IMMEDIATE(copy(stype_value));
+
+    return img::format("SYNC %s", stype);
+}
+
+
+std::string NMD::SLL_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("SLL %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::SRL_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("SRL %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::SRA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("SRA %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::ROTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("ROTR %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSLL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSLL %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSLL32(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSLL32 %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSRL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSRL %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSRL32(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSRL32 %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSRA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSRA %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DSRA32(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DSRA32 %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DROTR(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DROTR %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::DROTR32(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("DROTR32 %s, %s, %s", rt, rs, shift);
+}
+
+
+std::string NMD::ROTX(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil0il0bs5Fmsb4(instruction);
+    uint64 shiftx_value = extr_shiftxil7il1bs4Fmsb4(instruction);
+    uint64 stripe_value = extr_stripeil6il0bs1Fmsb0(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+    std::string shiftx = IMMEDIATE(copy(shiftx_value));
+    std::string stripe = IMMEDIATE(copy(stripe_value));
+
+    return img::format("ROTX %s, %s, %s, %s, %s",
+                       rt, rs, shift, shiftx, stripe);
+}
+
+
+std::string NMD::INS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value));
+    std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value));
+    /* !!!!!!!!!! - no conversion function */
+
+    return img::format("INS %s, %s, %s, %s", rt, rs, pos, size);
+    /* hand edited */
+}
+
+
+std::string NMD::DINSU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value));
+    std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value));
+    /* !!!!!!!!!! - no conversion function */
+
+    return img::format("DINSU %s, %s, %s, %s", rt, rs, pos, size);
+    /* hand edited */
+}
+
+
+std::string NMD::DINSM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value));
+    std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value));
+    /* !!!!!!!!!! - no conversion function */
+
+    return img::format("DINSM %s, %s, %s, %s", rt, rs, pos, size);
+    /* hand edited */
+}
+
+
+std::string NMD::DINS(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string pos = IMMEDIATE(encode_lsb_from_pos_and_size(lsb_value));
+    std::string size = IMMEDIATE(encode_lsb_from_pos_and_size(msbd_value));
+    /* !!!!!!!!!! - no conversion function */
+
+    return img::format("DINS %s, %s, %s, %s", rt, rs, pos, size);
+    /* hand edited */
+}
+
+
+std::string NMD::EXT(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string lsb = IMMEDIATE(copy(lsb_value));
+    std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value));
+
+    return img::format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd);
+}
+
+
+std::string NMD::DEXTU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string lsb = IMMEDIATE(copy(lsb_value));
+    std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value));
+
+    return img::format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd);
+}
+
+
+std::string NMD::DEXTM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string lsb = IMMEDIATE(copy(lsb_value));
+    std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value));
+
+    return img::format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd);
+}
+
+
+std::string NMD::DEXT(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 msbd_value = extr_msbdil6il0bs5Fmsb4(instruction);
+    uint64 lsb_value = extr_lsbil0il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string lsb = IMMEDIATE(copy(lsb_value));
+    std::string msbd = IMMEDIATE(encode_msbd_from_size(msbd_value));
+
+    return img::format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd);
+}
+
+
+std::string NMD::RINT_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RINT.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::RINT_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RINT.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::ADD_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("ADD.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SELEQZ_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SELEQZ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SELEQZ_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SELEQZ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CLASS_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CLASS.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CLASS_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CLASS.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::SUB_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SUB.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SELNEZ_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SELNEZ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SELNEZ_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SELNEZ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MUL_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MUL.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SEL_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SEL.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SEL_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SEL.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::DIV_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("DIV.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::ADD_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("ADD.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::SUB_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("SUB.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MUL_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MUL.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MADDF_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MADDF.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MADDF_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MADDF.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::DIV_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("DIV.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MSUBF_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MSUBF.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MSUBF_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MSUBF.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MIN_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MIN.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MIN_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MIN.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MAX_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MAX.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MAX_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MAX.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MINA_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MINA.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MINA_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MINA.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MAXA_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MAXA.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::MAXA_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("MAXA.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CVT_L_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.L.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_L_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.L.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::RSQRT_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RSQRT.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::RSQRT_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RSQRT.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::FLOOR_L_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("FLOOR.L.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::FLOOR_L_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("FLOOR.L.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_W_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.W.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_W_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.W.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::SQRT_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("SQRT.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::SQRT_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("SQRT.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::FLOOR_W_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("FLOOR.W.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::FLOOR_W_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("FLOOR.W.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CFC1(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("CFC1 %s, %s", rt, cs);
+}
+
+
+std::string NMD::RECIP_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RECIP.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::RECIP_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("RECIP.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CEIL_L_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CEIL.L.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CEIL_L_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CEIL.L.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CTC1(uint64 instruction)
+{
+    uint64 cs_value = extr_csil16il0bs5Fmsb4(instruction);
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string cs = CPR(copy(cs_value));
+
+    return img::format("CTC1 %s, %s", rt, cs);
+}
+
+
+std::string NMD::CEIL_W_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CEIL.W.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CEIL_W_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CEIL.W.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::MFC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MFC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::CVT_S_PL(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.S.PL %s, %s", ft, fs);
+}
+
+
+std::string NMD::TRUNC_L_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("TRUNC.L.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::TRUNC_L_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("TRUNC.L.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::DMFC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("DMFC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::MTC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MTC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::CVT_S_PU(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.S.PU %s, %s", ft, fs);
+}
+
+
+std::string NMD::TRUNC_W_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("TRUNC.W.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::TRUNC_W_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("TRUNC.W.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::DMTC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("DMTC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::MFHC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MFHC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::ROUND_L_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ROUND.L.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::ROUND_L_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ROUND.L.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::MTHC1(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MTHC1 %s, %s", rt, fs);
+}
+
+
+std::string NMD::ROUND_W_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ROUND.W.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::ROUND_W_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ROUND.W.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::MOV_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MOV.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::MOV_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("MOV.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::ABS_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ABS.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::ABS_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("ABS.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::NEG_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("NEG.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::NEG_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("NEG.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_D_S(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.D.S %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_D_W(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.D.W %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_D_L(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.D.L %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_S_D(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.S.D %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_S_W(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.S.W %s, %s", ft, fs);
+}
+
+
+std::string NMD::CVT_S_L(uint64 instruction)
+{
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string fs = FPR(copy(fs_value));
+
+    return img::format("CVT.S.L %s, %s", ft, fs);
+}
+
+
+std::string NMD::CMP_AF_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.AF.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UN_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UN.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_EQ_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.EQ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UEQ_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UEQ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_LT_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.LT.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_ULT_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.ULT.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_LE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.LE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_ULE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.ULE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SAF_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SAF.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUN_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUN.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SEQ_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SEQ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUEQ_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SLT_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SLT.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SULT_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SULT.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SLE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SLE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SULE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SULE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_OR_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.OR.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UNE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UNE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_NE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.NE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SOR_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SOR.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUNE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUNE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SNE_S(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SNE.S %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_AF_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.AF.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UN_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UN.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_EQ_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.EQ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UEQ_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UEQ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_LT_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.LT.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_ULT_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.ULT.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_LE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.LE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_ULE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.ULE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SAF_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SAF.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUN_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUN.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SEQ_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SEQ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUEQ_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SLT_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SLT.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SULT_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SULT.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SLE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SLE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SULE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SULE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_OR_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.OR.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_UNE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.UNE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_NE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.NE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SOR_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SOR.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SUNE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SUNE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::CMP_SNE_D(uint64 instruction)
+{
+    uint64 fd_value = extr_fdil11il0bs5Fmsb4(instruction);
+    uint64 fs_value = extr_fsil16il0bs5Fmsb4(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string fd = FPR(copy(fd_value));
+    std::string fs = FPR(copy(fs_value));
+    std::string ft = FPR(copy(ft_value));
+
+    return img::format("CMP.SNE.D %s, %s, %s", fd, fs, ft);
+}
+
+
+std::string NMD::DLSA(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 u2_value = extr_u2il9il0bs2Fmsb1(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string u2 = IMMEDIATE(copy(u2_value));
+
+    return img::format("DLSA %s, %s, %s, %s", rd, rs, rt, u2);
+}
+
+
+std::string NMD::DSLLV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DSLLV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMUL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMUL %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DSRLV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DSRLV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMUH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMUH %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DSRAV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DSRAV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMULU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMULU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DROTRV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DROTRV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMUHU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMUHU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DADD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DADD %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DDIV(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DDIV %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DADDU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DADDU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMOD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMOD %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DSUB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DSUB %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DDIVU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DDIVU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DSUBU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DSUBU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::DMODU(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("DMODU %s, %s, %s", rd, rs, rt);
+}
+
+
+std::string NMD::EXTD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil6il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTD %s, %s, %s, %s", rd, rs, rt, shift);
+}
+
+
+std::string NMD::EXTD32(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 shift_value = extr_shiftil6il0bs5Fmsb4(instruction);
+    uint64 rd_value = extr_rdil11il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rd = GPR(copy(rd_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string shift = IMMEDIATE(copy(shift_value));
+
+    return img::format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift);
+}
+
+
+std::string NMD::DCLO(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("DCLO %s, %s", rt, rs);
+}
+
+
+std::string NMD::DCLZ(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("DCLZ %s, %s", rt, rs);
+}
+
+
+std::string NMD::LUI(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("LUI %s, %%hi(%s)", rt, s);
+}
+
+
+std::string NMD::ALUIPC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("ALUIPC %s, %%pcrel_hi(%s)", rt, s);
+}
+
+
+std::string NMD::ADDIUPC_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il21bs1_il1il1bs20Tmsb21(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("ADDIUPC %s, %s", rt, s);
+}
+
+
+std::string NMD::LB_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs18Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LB %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::SB_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs18Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SB %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LBU_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs18Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LBU %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::ADDIU_GP_B_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs18Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ADDIU %s, $%d, %s", rt, 28, u);
+}
+
+
+std::string NMD::LH_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil1il1bs17Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LH %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LHU_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil1il1bs17Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LHU %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::SH_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil1il1bs17Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SH %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LWC1_GP_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs16Fmsb17(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LWC1 %s, %s($%d)", ft, u, 28);
+}
+
+
+std::string NMD::SWC1_GP_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs16Fmsb17(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SWC1 %s, %s($%d)", ft, u, 28);
+}
+
+
+std::string NMD::LDC1_GP_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs16Fmsb17(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LDC1 %s, %s($%d)", ft, u, 28);
+}
+
+
+std::string NMD::SDC1_GP_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs16Fmsb17(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SDC1 %s, %s($%d)", ft, u, 28);
+}
+
+
+std::string NMD::LWU_GP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil2il2bs16Fmsb17(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LWU %s, %s($%d)", rt, u, 28);
+}
+
+
+std::string NMD::LB_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LB %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::SB_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SB %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LBU_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LBU %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::PREF_U12_(uint64 instruction)
+{
+    uint64 hint_value = extr_hintil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string hint = IMMEDIATE(copy(hint_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PREF %s, %s(%s)", hint, u, rs);
+}
+
+
+std::string NMD::LH_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LH %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::SH_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SH %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LHU_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LHU %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LWU_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWU %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LW_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LW %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::SW_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SW %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LWC1_U12_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWC1 %s, %s(%s)", ft, u, rs);
+}
+
+
+std::string NMD::SWC1_U12_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SWC1 %s, %s(%s)", ft, u, rs);
+}
+
+
+std::string NMD::LD_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LD %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::SD_U12_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SD %s, %s(%s)", rt, u, rs);
+}
+
+
+std::string NMD::LDC1_U12_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LDC1 %s, %s(%s)", ft, u, rs);
+}
+
+
+std::string NMD::SDC1_U12_(uint64 instruction)
+{
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il0bs12Fmsb11(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SDC1 %s, %s(%s)", ft, u, rs);
+}
+
+
+std::string NMD::LB_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LB %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SB_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SB %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LBU_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LBU %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SYNCI(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SYNCI %s(%s)", s, rs);
+}
+
+
+std::string NMD::PREF_S9_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 hint_value = extr_hintil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string hint = IMMEDIATE(copy(hint_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PREF %s, %s(%s)", hint, s, rs);
+}
+
+
+std::string NMD::LH_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LH %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SH_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SH %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LHU_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LHU %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LWU_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWU %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LW_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LW %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SW_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SW %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LWC1_S9_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWC1 %s, %s(%s)", ft, s, rs);
+}
+
+
+std::string NMD::SWC1_S9_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SWC1 %s, %s(%s)", ft, s, rs);
+}
+
+
+std::string NMD::LD_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LD %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SD_S9_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SD %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LDC1_S9_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LDC1 %s, %s(%s)", ft, s, rs);
+}
+
+
+std::string NMD::SDC1_S9_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SDC1 %s, %s(%s)", ft, s, rs);
+}
+
+
+std::string NMD::ASET(uint64 instruction)
+{
+    uint64 bit_value = extr_bitil21il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string bit = IMMEDIATE(copy(bit_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("ASET %s, %s(%s)", bit, s, rs);
+}
+
+
+std::string NMD::ACLR(uint64 instruction)
+{
+    uint64 bit_value = extr_bitil21il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string bit = IMMEDIATE(copy(bit_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("ACLR %s, %s(%s)", bit, s, rs);
+}
+
+
+std::string NMD::UALH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("UALH %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::UASH(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("UASH %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::CACHE(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 op_value = extr_opil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string op = IMMEDIATE(copy(op_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("CACHE %s, %s(%s)", op, s, rs);
+}
+
+
+std::string NMD::LWC2(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ct_value = extr_ctil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ct = CPR(copy(ct_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWC2 %s, %s(%s)", ct, s, rs);
+}
+
+
+std::string NMD::SWC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string cs = CPR(copy(cs_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SWC2 %s, %s(%s)", cs, s, rs);
+}
+
+
+std::string NMD::LL(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LL %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LLWP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LLWP %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::SC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SC %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SCWP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SCWP %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::LDC2(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 ct_value = extr_ctil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string ct = CPR(copy(ct_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LDC2 %s, %s(%s)", ct, s, rs);
+}
+
+
+std::string NMD::SDC2(uint64 instruction)
+{
+    uint64 cs_value = extr_csil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string cs = CPR(copy(cs_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SDC2 %s, %s(%s)", cs, s, rs);
+}
+
+
+std::string NMD::LLD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil3il3bs5_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LLD %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LLDP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LLDP %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::SCD(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil3il3bs5_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SCD %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SCDP(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SCDP %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::LBE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LBE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SBE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SBE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LBUE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LBUE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SYNCIE(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SYNCIE %s(%s)", s, rs);
+}
+
+
+std::string NMD::PREFE(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 hint_value = extr_hintil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string hint = IMMEDIATE(copy(hint_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("PREFE %s, %s(%s)", hint, s, rs);
+}
+
+
+std::string NMD::LHE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LHE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SHE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SHE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LHUE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LHUE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::CACHEE(uint64 instruction)
+{
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 op_value = extr_opil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string op = IMMEDIATE(copy(op_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("CACHEE %s, %s(%s)", op, s, rs);
+}
+
+
+std::string NMD::LWE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LWE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SWE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SWE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LLE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LLE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::LLWPE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("LLWPE %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::SCE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SCE %s, %s(%s)", rt, s, rs);
+}
+
+
+std::string NMD::SCWPE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 ru_value = extr_ruil3il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string ru = GPR(copy(ru_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("SCWPE %s, %s, (%s)", rt, ru, rs);
+}
+
+
+std::string NMD::LWM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("LWM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::SWM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("SWM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::UALWM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("UALWM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::UASWM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("UASWM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::LDM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("LDM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::SDM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("SDM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::UALDM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("UALDM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::UASDM(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 count3_value = extr_count3il12il0bs3Fmsb2(instruction);
+    int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+    std::string rs = GPR(copy(rs_value));
+    std::string count3 = IMMEDIATE(encode_count3_from_count(count3_value));
+
+    return img::format("UASDM %s, %s(%s), %s", rt, s, rs, count3);
+}
+
+
+std::string NMD::MOVE_BALC(uint64 instruction)
+{
+    uint64 rd1_value = extr_rd1il24il0bs1Fmsb0(instruction);
+    int64 s_value = extr_sil0il21bs1_il1il1bs20Tmsb21(instruction);
+    uint64 rtz4_value = extr_rtz4il21il0bs3_il25il3bs1Fmsb3(instruction);
+
+    std::string rd1 = GPR(encode_rd1_from_rd(rd1_value));
+    std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("MOVE.BALC %s, %s, %s", rd1, rtz4, s);
+}
+
+
+std::string NMD::BC_32_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il25bs1_il1il1bs24Tmsb25(instruction);
+
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BC %s", s);
+}
+
+
+std::string NMD::BALC_32_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il25bs1_il1il1bs24Tmsb25(instruction);
+
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BALC %s", s);
+}
+
+
+std::string NMD::JALRC_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("JALRC %s, %s", rt, rs);
+}
+
+
+std::string NMD::JALRC_HB(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("JALRC.HB %s, %s", rt, rs);
+}
+
+
+std::string NMD::BRSC(uint64 instruction)
+{
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("BRSC %s", rs);
+}
+
+
+std::string NMD::BALRSC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("BALRSC %s, %s", rt, rs);
+}
+
+
+std::string NMD::BEQC_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BEQC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BC1EQZC(uint64 instruction)
+{
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BC1EQZC %s, %s", ft, s);
+}
+
+
+std::string NMD::BC1NEZC(uint64 instruction)
+{
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 ft_value = extr_ftil21il0bs5Fmsb4(instruction);
+
+    std::string ft = FPR(copy(ft_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BC1NEZC %s, %s", ft, s);
+}
+
+
+std::string NMD::BC2EQZC(uint64 instruction)
+{
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 ct_value = extr_ctil21il0bs5Fmsb4(instruction);
+
+    std::string ct = CPR(copy(ct_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BC2EQZC %s, %s", ct, s);
+}
+
+
+std::string NMD::BC2NEZC(uint64 instruction)
+{
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 ct_value = extr_ctil21il0bs5Fmsb4(instruction);
+
+    std::string ct = CPR(copy(ct_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BC2NEZC %s, %s", ct, s);
+}
+
+
+std::string NMD::BPOSGE32C(uint64 instruction)
+{
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BPOSGE32C %s", s);
+}
+
+
+std::string NMD::BGEC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BGEC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BGEUC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BGEUC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BNEC_32_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BNEC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BLTC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BLTC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BLTUC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+    uint64 rs_value = extr_rsil16il0bs5Fmsb4(instruction);
+
+    std::string rs = GPR(copy(rs_value));
+    std::string rt = GPR(copy(rt_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BLTUC %s, %s, %s", rs, rt, s);
+}
+
+
+std::string NMD::BEQIC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BEQIC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::BBEQZC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 bit_value = extr_bitil11il0bs6Fmsb5(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string bit = IMMEDIATE(copy(bit_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BBEQZC %s, %s, %s", rt, bit, s);
+}
+
+
+std::string NMD::BGEIC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BGEIC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::BGEIUC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BGEIUC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::BNEIC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BNEIC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::BBNEZC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    uint64 bit_value = extr_bitil11il0bs6Fmsb5(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string bit = IMMEDIATE(copy(bit_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BBNEZC %s, %s, %s", rt, bit, s);
+}
+
+
+std::string NMD::BLTIC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BLTIC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::BLTIUC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil21il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+    uint64 u_value = extr_uil11il0bs7Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 4);
+
+    return img::format("BLTIUC %s, %s, %s", rt, u, s);
+}
+
+
+std::string NMD::SYSCALL_16_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs2Fmsb1(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("SYSCALL %s", code);
+}
+
+
+std::string NMD::HYPCALL_16_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs2Fmsb1(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("HYPCALL %s", code);
+}
+
+
+std::string NMD::BREAK_16_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs3Fmsb2(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("BREAK %s", code);
+}
+
+
+std::string NMD::SDBBP_16_(uint64 instruction)
+{
+    uint64 code_value = extr_codeil0il0bs3Fmsb2(instruction);
+
+    std::string code = IMMEDIATE(copy(code_value));
+
+    return img::format("SDBBP %s", code);
+}
+
+
+std::string NMD::MOVE(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+    uint64 rs_value = extr_rsil0il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string rs = GPR(copy(rs_value));
+
+    return img::format("MOVE %s, %s", rt, rs);
+}
+
+
+std::string NMD::SLL_16_(uint64 instruction)
+{
+    uint64 shift3_value = extr_shift3il0il0bs3Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value));
+
+    return img::format("SLL %s, %s, %s", rt3, rs3, shift3);
+}
+
+
+std::string NMD::SRL_16_(uint64 instruction)
+{
+    uint64 shift3_value = extr_shift3il0il0bs3Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value));
+
+    return img::format("SRL %s, %s, %s", rt3, rs3, shift3);
+}
+
+
+std::string NMD::NOT_16_(uint64 instruction)
+{
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("NOT %s, %s", rt3, rs3);
+}
+
+
+std::string NMD::XOR_16_(uint64 instruction)
+{
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+
+    return img::format("XOR %s, %s", rs3, rt3);
+}
+
+
+std::string NMD::AND_16_(uint64 instruction)
+{
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+
+    return img::format("AND %s, %s", rs3, rt3);
+}
+
+
+std::string NMD::OR_16_(uint64 instruction)
+{
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+
+    return img::format("OR %s, %s", rs3, rt3);
+}
+
+
+std::string NMD::LWXS_16_(uint64 instruction)
+{
+    uint64 rd3_value = extr_rd3il1il0bs3Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rd3 = GPR(encode_gpr3(rd3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = IMMEDIATE(encode_gpr3(rt3_value));
+
+    return img::format("LWXS %s, %s(%s)", rd3, rs3, rt3);
+}
+
+
+std::string NMD::ADDIU_R1_SP_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il2bs6Fmsb7(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ADDIU %s, $%d, %s", rt3, 29, u);
+}
+
+
+std::string NMD::ADDIU_R2_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il2bs3Fmsb4(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("ADDIU %s, %s, %s", rt3, rs3, u);
+}
+
+
+std::string NMD::NOP_16_(uint64 instruction)
+{
+    (void)instruction;
+
+    return "NOP ";
+}
+
+
+std::string NMD::ADDIU_RS5_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+    int64 s_value = extr_sil0il0bs3_il4il3bs1Tmsb3(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string s = IMMEDIATE(copy(s_value));
+
+    return img::format("ADDIU %s, %s", rt, s);
+}
+
+
+std::string NMD::ADDU_16_(uint64 instruction)
+{
+    uint64 rd3_value = extr_rd3il1il0bs3Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rd3 = GPR(encode_gpr3(rd3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+
+    return img::format("ADDU %s, %s, %s", rd3, rs3, rt3);
+}
+
+
+std::string NMD::SUBU_16_(uint64 instruction)
+{
+    uint64 rd3_value = extr_rd3il1il0bs3Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rd3 = GPR(encode_gpr3(rd3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+
+    return img::format("SUBU %s, %s, %s", rd3, rs3, rt3);
+}
+
+
+std::string NMD::LI_16_(uint64 instruction)
+{
+    uint64 eu_value = extr_euil0il0bs7Fmsb6(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string eu = IMMEDIATE(encode_eu_from_s_li16(eu_value));
+
+    return img::format("LI %s, %s", rt3, eu);
+}
+
+
+std::string NMD::ANDI_16_(uint64 instruction)
+{
+    uint64 eu_value = extr_euil0il0bs4Fmsb3(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+    std::string eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value));
+
+    return img::format("ANDI %s, %s, %s", rt3, rs3, eu);
+}
+
+
+std::string NMD::LW_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il2bs4Fmsb5(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("LW %s, %s(%s)", rt3, u, rs3);
+}
+
+
+std::string NMD::LW_SP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il2bs5Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LW %s, %s($%d)", rt, u, 29);
+}
+
+
+std::string NMD::LW_GP16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il2bs7Fmsb8(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("LW %s, %s($%d)", rt3, u, 28);
+}
+
+
+std::string NMD::LW_4X4_(uint64 instruction)
+{
+    uint64 rs4_value = extr_rs4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rt4_value = extr_rt4il5il0bs3_il9il3bs1Fmsb3(instruction);
+    uint64 u_value = extr_uil3il3bs1_il8il2bs1Fmsb3(instruction);
+
+    std::string rt4 = GPR(encode_gpr4(rt4_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs4 = GPR(encode_gpr4(rs4_value));
+
+    return img::format("LW %s, %s(%s)", rt4, u, rs4);
+}
+
+
+std::string NMD::SW_16_(uint64 instruction)
+{
+    uint64 rtz3_value = extr_rtz3il7il0bs3Fmsb2(instruction);
+    uint64 u_value = extr_uil0il2bs4Fmsb5(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("SW %s, %s(%s)", rtz3, u, rs3);
+}
+
+
+std::string NMD::SW_SP_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+    uint64 u_value = extr_uil0il2bs5Fmsb6(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SW %s, %s($%d)", rt, u, 29);
+}
+
+
+std::string NMD::SW_GP16_(uint64 instruction)
+{
+    uint64 rtz3_value = extr_rtz3il7il0bs3Fmsb2(instruction);
+    uint64 u_value = extr_uil0il2bs7Fmsb8(instruction);
+
+    std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+
+    return img::format("SW %s, %s($%d)", rtz3, u, 28);
+}
+
+
+std::string NMD::SW_4X4_(uint64 instruction)
+{
+    uint64 rs4_value = extr_rs4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rtz4_value = extr_rtz4il5il0bs3_il9il3bs1Fmsb3(instruction);
+    uint64 u_value = extr_uil3il3bs1_il8il2bs1Fmsb3(instruction);
+
+    std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs4 = GPR(encode_gpr4(rs4_value));
+
+    return img::format("SW %s, %s(%s)", rtz4, u, rs4);
+}
+
+
+std::string NMD::BC_16_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il10bs1_il1il1bs9Tmsb10(instruction);
+
+    std::string s = ADDRESS(encode_s_from_address(s_value), 2);
+
+    return img::format("BC %s", s);
+}
+
+
+std::string NMD::BALC_16_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il10bs1_il1il1bs9Tmsb10(instruction);
+
+    std::string s = ADDRESS(encode_s_from_address(s_value), 2);
+
+    return img::format("BALC %s", s);
+}
+
+
+std::string NMD::BEQZC_16_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il7bs1_il1il1bs6Tmsb7(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 2);
+
+    return img::format("BEQZC %s, %s", rt3, s);
+}
+
+
+std::string NMD::BNEZC_16_(uint64 instruction)
+{
+    int64 s_value = extr_sil0il7bs1_il1il1bs6Tmsb7(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string s = ADDRESS(encode_s_from_address(s_value), 2);
+
+    return img::format("BNEZC %s, %s", rt3, s);
+}
+
+
+std::string NMD::JRC(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("JRC %s", rt);
+}
+
+
+std::string NMD::JALRC_16_(uint64 instruction)
+{
+    uint64 rt_value = extr_rtil5il0bs5Fmsb4(instruction);
+
+    std::string rt = GPR(copy(rt_value));
+
+    return img::format("JALRC $%d, %s", 31, rt);
+}
+
+
+std::string NMD::BEQC_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il1bs4Fmsb4(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = ADDRESS(encode_u_from_address(u_value), 2);
+
+    return img::format("BEQC %s, %s, %s", rs3, rt3, u);
+}
+
+
+std::string NMD::BNEC_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il1bs4Fmsb4(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value));
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = ADDRESS(encode_u_from_address(u_value), 2);
+
+    return img::format("BNEC %s, %s, %s", rs3, rt3, u);
+}
+
+
+std::string NMD::SAVE_16_(uint64 instruction)
+{
+    uint64 count_value = extr_countil0il0bs4Fmsb3(instruction);
+    uint64 rt1_value = extr_rt1il9il0bs1Fmsb0(instruction);
+    uint64 u_value = extr_uil4il4bs4Fmsb7(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    return img::format("SAVE %s%s", u,
+        save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0));
+}
+
+
+std::string NMD::RESTORE_JRC_16_(uint64 instruction)
+{
+    uint64 count_value = extr_countil0il0bs4Fmsb3(instruction);
+    uint64 rt1_value = extr_rt1il9il0bs1Fmsb0(instruction);
+    uint64 u_value = extr_uil4il4bs4Fmsb7(instruction);
+
+    std::string u = IMMEDIATE(copy(u_value));
+    return img::format("RESTORE.JRC %s%s", u,
+        save_restore_list(encode_rt1_from_rt(rt1_value), count_value, 0));
+}
+
+
+std::string NMD::ADDU_4X4_(uint64 instruction)
+{
+    uint64 rs4_value = extr_rs4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rt4_value = extr_rt4il5il0bs3_il9il3bs1Fmsb3(instruction);
+
+    std::string rs4 = GPR(encode_gpr4(rs4_value));
+    std::string rt4 = GPR(encode_gpr4(rt4_value));
+
+    return img::format("ADDU %s, %s", rs4, rt4);
+}
+
+
+std::string NMD::MUL_4X4_(uint64 instruction)
+{
+    uint64 rs4_value = extr_rs4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rt4_value = extr_rt4il5il0bs3_il9il3bs1Fmsb3(instruction);
+
+    std::string rs4 = GPR(encode_gpr4(rs4_value));
+    std::string rt4 = GPR(encode_gpr4(rt4_value));
+
+    return img::format("MUL %s, %s", rs4, rt4);
+}
+
+
+std::string NMD::LB_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il0bs2Fmsb1(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("LB %s, %s(%s)", rt3, u, rs3);
+}
+
+
+std::string NMD::SB_16_(uint64 instruction)
+{
+    uint64 rtz3_value = extr_rtz3il7il0bs3Fmsb2(instruction);
+    uint64 u_value = extr_uil0il0bs2Fmsb1(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("SB %s, %s(%s)", rtz3, u, rs3);
+}
+
+
+std::string NMD::LBU_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil0il0bs2Fmsb1(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("LBU %s, %s(%s)", rt3, u, rs3);
+}
+
+
+std::string NMD::LH_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("LH %s, %s(%s)", rt3, u, rs3);
+}
+
+
+std::string NMD::SH_16_(uint64 instruction)
+{
+    uint64 rtz3_value = extr_rtz3il7il0bs3Fmsb2(instruction);
+    uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rtz3 = GPR(encode_gpr3_store(rtz3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("SH %s, %s(%s)", rtz3, u, rs3);
+}
+
+
+std::string NMD::LHU_16_(uint64 instruction)
+{
+    uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+    uint64 rt3_value = extr_rt3il7il0bs3Fmsb2(instruction);
+    uint64 rs3_value = extr_rs3il4il0bs3Fmsb2(instruction);
+
+    std::string rt3 = GPR(encode_gpr3(rt3_value));
+    std::string u = IMMEDIATE(copy(u_value));
+    std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+    return img::format("LHU %s, %s(%s)", rt3, u, rs3);
+}
+
+
+std::string NMD::MOVEP(uint64 instruction)
+{
+    uint64 rsz4_value = extr_rsz4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rtz4_value = extr_rtz4il5il0bs3_il9il3bs1Fmsb3(instruction);
+    uint64 rd2_value = extr_rd2il3il1bs1_il8il0bs1Fmsb1(instruction);
+
+    std::string rd2 = GPR(encode_rd2_reg1(rd2_value));
+    std::string re2 = GPR(encode_rd2_reg2(rd2_value));
+    /* !!!!!!!!!! - no conversion function */
+    std::string rsz4 = GPR(encode_gpr4_zero(rsz4_value));
+    std::string rtz4 = GPR(encode_gpr4_zero(rtz4_value));
+
+    return img::format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4);
+    /* hand edited */
+}
+
+
+std::string NMD::MOVEP_REV_(uint64 instruction)
+{
+    uint64 rs4_value = extr_rs4il0il0bs3_il4il3bs1Fmsb3(instruction);
+    uint64 rt4_value = extr_rt4il5il0bs3_il9il3bs1Fmsb3(instruction);
+    uint64 rd2_value = extr_rd2il3il1bs1_il8il0bs1Fmsb1(instruction);
+
+    std::string rs4 = GPR(encode_gpr4(rs4_value));
+    std::string rt4 = GPR(encode_gpr4(rt4_value));
+    std::string rd2 = GPR(encode_rd2_reg1(rd2_value));
+    std::string rs2 = GPR(encode_rd2_reg2(rd2_value));
+    /* !!!!!!!!!! - no conversion function */
+
+    return img::format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2);
+    /* hand edited */
+}
+
+
+NMD::Pool NMD::P_SYSCALL[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfffc0000, 0x00080000, &NMD::SYSCALL_32_      , 0,
+       0x0                 },        /* SYSCALL[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xfffc0000, 0x000c0000, &NMD::HYPCALL          , 0,
+       CP0_ | VZ_          },        /* HYPCALL */
+};
+
+
+NMD::Pool NMD::P_RI[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfff80000, 0x00000000, &NMD::SIGRIE           , 0,
+       0x0                 },        /* SIGRIE */
+    { pool                , P_SYSCALL           , 2   , 32,
+       0xfff80000, 0x00080000, 0                      , 0,
+       0x0                 },        /* P.SYSCALL */
+    { instruction         , 0                   , 0   , 32,
+       0xfff80000, 0x00100000, &NMD::BREAK_32_        , 0,
+       0x0                 },        /* BREAK[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xfff80000, 0x00180000, &NMD::SDBBP_32_        , 0,
+       EJTAG_              },        /* SDBBP[32] */
+};
+
+
+NMD::Pool NMD::P_ADDIU[2] = {
+    { pool                , P_RI                , 4   , 32,
+       0xffe00000, 0x00000000, 0                      , 0,
+       0x0                 },        /* P.RI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000000, 0x00000000, &NMD::ADDIU_32_        , &NMD::ADDIU_32__cond   ,
+       0x0                 },        /* ADDIU[32] */
+};
+
+
+NMD::Pool NMD::P_TRAP[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000000, &NMD::TEQ              , 0,
+       XMMS_               },        /* TEQ */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000400, &NMD::TNE              , 0,
+       XMMS_               },        /* TNE */
+};
+
+
+NMD::Pool NMD::P_CMOVE[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000210, &NMD::MOVZ             , 0,
+       0x0                 },        /* MOVZ */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000610, &NMD::MOVN             , 0,
+       0x0                 },        /* MOVN */
+};
+
+
+NMD::Pool NMD::P_D_MT_VPE[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1f3fff, 0x20010ab0, &NMD::DMT              , 0,
+       MT_                 },        /* DMT */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1f3fff, 0x20000ab0, &NMD::DVPE             , 0,
+       MT_                 },        /* DVPE */
+};
+
+
+NMD::Pool NMD::P_E_MT_VPE[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1f3fff, 0x20010eb0, &NMD::EMT              , 0,
+       MT_                 },        /* EMT */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1f3fff, 0x20000eb0, &NMD::EVPE             , 0,
+       MT_                 },        /* EVPE */
+};
+
+
+NMD::Pool NMD::_P_MT_VPE[2] = {
+    { pool                , P_D_MT_VPE          , 2   , 32,
+       0xfc003fff, 0x20000ab0, 0                      , 0,
+       0x0                 },        /* P.D_MT_VPE */
+    { pool                , P_E_MT_VPE          , 2   , 32,
+       0xfc003fff, 0x20000eb0, 0                      , 0,
+       0x0                 },        /* P.E_MT_VPE */
+};
+
+
+NMD::Pool NMD::P_MT_VPE[8] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x200002b0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(0) */
+    { pool                , _P_MT_VPE           , 2   , 32,
+       0xfc003bff, 0x20000ab0, 0                      , 0,
+       0x0                 },        /* _P.MT_VPE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x200012b0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x20001ab0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x200022b0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x20002ab0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x200032b0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003bff, 0x20003ab0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE~*(7) */
+};
+
+
+NMD::Pool NMD::P_DVP[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000390, &NMD::DVP              , 0,
+       0x0                 },        /* DVP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000790, &NMD::EVP              , 0,
+       0x0                 },        /* EVP */
+};
+
+
+NMD::Pool NMD::P_SLTU[2] = {
+    { pool                , P_DVP               , 2   , 32,
+       0xfc00fbff, 0x20000390, 0                      , 0,
+       0x0                 },        /* P.DVP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000390, &NMD::SLTU             , &NMD::SLTU_cond        ,
+       0x0                 },        /* SLTU */
+};
+
+
+NMD::Pool NMD::_POOL32A0[128] = {
+    { pool                , P_TRAP              , 2   , 32,
+       0xfc0003ff, 0x20000000, 0                      , 0,
+       0x0                 },        /* P.TRAP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000008, &NMD::SEB              , 0,
+       XMMS_               },        /* SEB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000010, &NMD::SLLV             , 0,
+       0x0                 },        /* SLLV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000018, &NMD::MUL_32_          , 0,
+       0x0                 },        /* MUL[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000020, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000028, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(5) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000030, &NMD::MFC0             , 0,
+       0x0                 },        /* MFC0 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000038, &NMD::MFHC0            , 0,
+       CP0_ | MVH_         },        /* MFHC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000040, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(8) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000048, &NMD::SEH              , 0,
+       0x0                 },        /* SEH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000050, &NMD::SRLV             , 0,
+       0x0                 },        /* SRLV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000058, &NMD::MUH              , 0,
+       0x0                 },        /* MUH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000060, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000068, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(13) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000070, &NMD::MTC0             , 0,
+       CP0_                },        /* MTC0 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000078, &NMD::MTHC0            , 0,
+       CP0_ | MVH_         },        /* MTHC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000080, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000088, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(17) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000090, &NMD::SRAV             , 0,
+       0x0                 },        /* SRAV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000098, &NMD::MULU             , 0,
+       0x0                 },        /* MULU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000a0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000a8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(21) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000b0, &NMD::MFGC0            , 0,
+       CP0_ | VZ_          },        /* MFGC0 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000b8, &NMD::MFHGC0           , 0,
+       CP0_ | VZ_ | MVH_   },        /* MFHGC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000c0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000c8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(25) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000d0, &NMD::ROTRV            , 0,
+       0x0                 },        /* ROTRV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000d8, &NMD::MUHU             , 0,
+       0x0                 },        /* MUHU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000e0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000e8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(29) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000f0, &NMD::MTGC0            , 0,
+       CP0_ | VZ_          },        /* MTGC0 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000f8, &NMD::MTHGC0           , 0,
+       CP0_ | VZ_ | MVH_   },        /* MTHGC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000100, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(32) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000108, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(33) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000110, &NMD::ADD              , 0,
+       XMMS_               },        /* ADD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000118, &NMD::DIV              , 0,
+       0x0                 },        /* DIV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000120, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(36) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000128, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(37) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000130, &NMD::DMFC0            , 0,
+       CP0_ | MIPS64_      },        /* DMFC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000138, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(39) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000140, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(40) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000148, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(41) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000150, &NMD::ADDU_32_         , 0,
+       0x0                 },        /* ADDU[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000158, &NMD::MOD              , 0,
+       0x0                 },        /* MOD */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000160, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(44) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000168, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(45) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000170, &NMD::DMTC0            , 0,
+       CP0_ | MIPS64_      },        /* DMTC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000178, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(47) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000180, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(48) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000188, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(49) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000190, &NMD::SUB              , 0,
+       XMMS_               },        /* SUB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000198, &NMD::DIVU             , 0,
+       0x0                 },        /* DIVU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001a0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001a8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(53) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001b0, &NMD::DMFGC0           , 0,
+       CP0_ | MIPS64_ | VZ_},        /* DMFGC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001b8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(55) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001c0, &NMD::RDHWR            , 0,
+       XMMS_               },        /* RDHWR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001c8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(57) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001d0, &NMD::SUBU_32_         , 0,
+       0x0                 },        /* SUBU[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001d8, &NMD::MODU             , 0,
+       0x0                 },        /* MODU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001e0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001e8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(61) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001f0, &NMD::DMTGC0           , 0,
+       CP0_ | MIPS64_ | VZ_},        /* DMTGC0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001f8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(63) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000200, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(64) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000208, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(65) */
+    { pool                , P_CMOVE             , 2   , 32,
+       0xfc0003ff, 0x20000210, 0                      , 0,
+       0x0                 },        /* P.CMOVE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000218, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(67) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000220, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(68) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000228, &NMD::FORK             , 0,
+       MT_                 },        /* FORK */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000230, &NMD::MFTR             , 0,
+       MT_                 },        /* MFTR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000238, &NMD::MFHTR            , 0,
+       MT_                 },        /* MFHTR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000240, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(72) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000248, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(73) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000250, &NMD::AND_32_          , 0,
+       0x0                 },        /* AND[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000258, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(75) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000260, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(76) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000268, &NMD::YIELD            , 0,
+       MT_                 },        /* YIELD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000270, &NMD::MTTR             , 0,
+       MT_                 },        /* MTTR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000278, &NMD::MTHTR            , 0,
+       MT_                 },        /* MTHTR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000280, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(80) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000288, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(81) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000290, &NMD::OR_32_           , 0,
+       0x0                 },        /* OR[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000298, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(83) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002a0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(84) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002a8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(85) */
+    { pool                , P_MT_VPE            , 8   , 32,
+       0xfc0003ff, 0x200002b0, 0                      , 0,
+       0x0                 },        /* P.MT_VPE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002b8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(87) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002c0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(88) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002c8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(89) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002d0, &NMD::NOR              , 0,
+       0x0                 },        /* NOR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002d8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(91) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002e0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(92) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002e8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(93) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002f0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(94) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002f8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(95) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000300, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(96) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000308, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(97) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000310, &NMD::XOR_32_          , 0,
+       0x0                 },        /* XOR[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000318, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(99) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000320, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(100) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000328, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(101) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000330, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(102) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000338, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(103) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000340, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(104) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000348, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(105) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000350, &NMD::SLT              , 0,
+       0x0                 },        /* SLT */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000358, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(107) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000360, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(108) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000368, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(109) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000370, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(110) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000378, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(111) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000380, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(112) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000388, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(113) */
+    { pool                , P_SLTU              , 2   , 32,
+       0xfc0003ff, 0x20000390, 0                      , 0,
+       0x0                 },        /* P.SLTU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000398, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(115) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003a0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(116) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003a8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(117) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003b0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(118) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003b8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(119) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003c0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(120) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003c8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(121) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003d0, &NMD::SOV              , 0,
+       0x0                 },        /* SOV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003d8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(123) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003e0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(124) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003e8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(125) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003f0, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(126) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003f8, 0                      , 0,
+       0x0                 },        /* _POOL32A0~*(127) */
+};
+
+
+NMD::Pool NMD::ADDQ__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000000d, &NMD::ADDQ_PH          , 0,
+       DSP_                },        /* ADDQ.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000040d, &NMD::ADDQ_S_PH        , 0,
+       DSP_                },        /* ADDQ_S.PH */
+};
+
+
+NMD::Pool NMD::MUL__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000002d, &NMD::MUL_PH           , 0,
+       DSP_                },        /* MUL.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000042d, &NMD::MUL_S_PH         , 0,
+       DSP_                },        /* MUL_S.PH */
+};
+
+
+NMD::Pool NMD::ADDQH__R__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000004d, &NMD::ADDQH_PH         , 0,
+       DSP_                },        /* ADDQH.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000044d, &NMD::ADDQH_R_PH       , 0,
+       DSP_                },        /* ADDQH_R.PH */
+};
+
+
+NMD::Pool NMD::ADDQH__R__W[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000008d, &NMD::ADDQH_W          , 0,
+       DSP_                },        /* ADDQH.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000048d, &NMD::ADDQH_R_W        , 0,
+       DSP_                },        /* ADDQH_R.W */
+};
+
+
+NMD::Pool NMD::ADDU__S__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200000cd, &NMD::ADDU_QB          , 0,
+       DSP_                },        /* ADDU.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200004cd, &NMD::ADDU_S_QB        , 0,
+       DSP_                },        /* ADDU_S.QB */
+};
+
+
+NMD::Pool NMD::ADDU__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000010d, &NMD::ADDU_PH          , 0,
+       DSP_                },        /* ADDU.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000050d, &NMD::ADDU_S_PH        , 0,
+       DSP_                },        /* ADDU_S.PH */
+};
+
+
+NMD::Pool NMD::ADDUH__R__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000014d, &NMD::ADDUH_QB         , 0,
+       DSP_                },        /* ADDUH.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000054d, &NMD::ADDUH_R_QB       , 0,
+       DSP_                },        /* ADDUH_R.QB */
+};
+
+
+NMD::Pool NMD::SHRAV__R__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000018d, &NMD::SHRAV_PH         , 0,
+       DSP_                },        /* SHRAV.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000058d, &NMD::SHRAV_R_PH       , 0,
+       DSP_                },        /* SHRAV_R.PH */
+};
+
+
+NMD::Pool NMD::SHRAV__R__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200001cd, &NMD::SHRAV_QB         , 0,
+       DSP_                },        /* SHRAV.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200005cd, &NMD::SHRAV_R_QB       , 0,
+       DSP_                },        /* SHRAV_R.QB */
+};
+
+
+NMD::Pool NMD::SUBQ__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000020d, &NMD::SUBQ_PH          , 0,
+       DSP_                },        /* SUBQ.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000060d, &NMD::SUBQ_S_PH        , 0,
+       DSP_                },        /* SUBQ_S.PH */
+};
+
+
+NMD::Pool NMD::SUBQH__R__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000024d, &NMD::SUBQH_PH         , 0,
+       DSP_                },        /* SUBQH.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000064d, &NMD::SUBQH_R_PH       , 0,
+       DSP_                },        /* SUBQH_R.PH */
+};
+
+
+NMD::Pool NMD::SUBQH__R__W[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000028d, &NMD::SUBQH_W          , 0,
+       DSP_                },        /* SUBQH.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000068d, &NMD::SUBQH_R_W        , 0,
+       DSP_                },        /* SUBQH_R.W */
+};
+
+
+NMD::Pool NMD::SUBU__S__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200002cd, &NMD::SUBU_QB          , 0,
+       DSP_                },        /* SUBU.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200006cd, &NMD::SUBU_S_QB        , 0,
+       DSP_                },        /* SUBU_S.QB */
+};
+
+
+NMD::Pool NMD::SUBU__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000030d, &NMD::SUBU_PH          , 0,
+       DSP_                },        /* SUBU.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000070d, &NMD::SUBU_S_PH        , 0,
+       DSP_                },        /* SUBU_S.PH */
+};
+
+
+NMD::Pool NMD::SHRA__R__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000335, &NMD::SHRA_PH          , 0,
+       DSP_                },        /* SHRA.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000735, &NMD::SHRA_R_PH        , 0,
+       DSP_                },        /* SHRA_R.PH */
+};
+
+
+NMD::Pool NMD::SUBUH__R__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000034d, &NMD::SUBUH_QB         , 0,
+       DSP_                },        /* SUBUH.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000074d, &NMD::SUBUH_R_QB       , 0,
+       DSP_                },        /* SUBUH_R.QB */
+};
+
+
+NMD::Pool NMD::SHLLV__S__PH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000038d, &NMD::SHLLV_PH         , 0,
+       DSP_                },        /* SHLLV.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x2000078d, &NMD::SHLLV_S_PH       , 0,
+       DSP_                },        /* SHLLV_S.PH */
+};
+
+
+NMD::Pool NMD::SHLL__S__PH[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000fff, 0x200003b5, &NMD::SHLL_PH          , 0,
+       DSP_                },        /* SHLL.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x200007b5, 0                      , 0,
+       0x0                 },        /* SHLL[_S].PH~*(1) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000fff, 0x20000bb5, &NMD::SHLL_S_PH        , 0,
+       DSP_                },        /* SHLL_S.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x20000fb5, 0                      , 0,
+       0x0                 },        /* SHLL[_S].PH~*(3) */
+};
+
+
+NMD::Pool NMD::PRECR_SRA__R__PH_W[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200003cd, &NMD::PRECR_SRA_PH_W   , 0,
+       DSP_                },        /* PRECR_SRA.PH.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200007cd, &NMD::PRECR_SRA_R_PH_W , 0,
+       DSP_                },        /* PRECR_SRA_R.PH.W */
+};
+
+
+NMD::Pool NMD::_POOL32A5[128] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000005, &NMD::CMP_EQ_PH        , 0,
+       DSP_                },        /* CMP.EQ.PH */
+    { pool                , ADDQ__S__PH         , 2   , 32,
+       0xfc0003ff, 0x2000000d, 0                      , 0,
+       0x0                 },        /* ADDQ[_S].PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000015, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(2) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000001d, &NMD::SHILO            , 0,
+       DSP_                },        /* SHILO */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000025, &NMD::MULEQ_S_W_PHL    , 0,
+       DSP_                },        /* MULEQ_S.W.PHL */
+    { pool                , MUL__S__PH          , 2   , 32,
+       0xfc0003ff, 0x2000002d, 0                      , 0,
+       0x0                 },        /* MUL[_S].PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000035, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(6) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000003d, &NMD::REPL_PH          , 0,
+       DSP_                },        /* REPL.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000045, &NMD::CMP_LT_PH        , 0,
+       DSP_                },        /* CMP.LT.PH */
+    { pool                , ADDQH__R__PH        , 2   , 32,
+       0xfc0003ff, 0x2000004d, 0                      , 0,
+       0x0                 },        /* ADDQH[_R].PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000055, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000005d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(11) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000065, &NMD::MULEQ_S_W_PHR    , 0,
+       DSP_                },        /* MULEQ_S.W.PHR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000006d, &NMD::PRECR_QB_PH      , 0,
+       DSP_                },        /* PRECR.QB.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000075, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000007d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(15) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000085, &NMD::CMP_LE_PH        , 0,
+       DSP_                },        /* CMP.LE.PH */
+    { pool                , ADDQH__R__W         , 2   , 32,
+       0xfc0003ff, 0x2000008d, 0                      , 0,
+       0x0                 },        /* ADDQH[_R].W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000095, &NMD::MULEU_S_PH_QBL   , 0,
+       DSP_                },        /* MULEU_S.PH.QBL */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000009d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000a5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(20) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000ad, &NMD::PRECRQ_QB_PH     , 0,
+       DSP_                },        /* PRECRQ.QB.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000b5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000bd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(23) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000c5, &NMD::CMPGU_EQ_QB      , 0,
+       DSP_                },        /* CMPGU.EQ.QB */
+    { pool                , ADDU__S__QB         , 2   , 32,
+       0xfc0003ff, 0x200000cd, 0                      , 0,
+       0x0                 },        /* ADDU[_S].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000d5, &NMD::MULEU_S_PH_QBR   , 0,
+       DSP_                },        /* MULEU_S.PH.QBR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000dd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000e5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(28) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000ed, &NMD::PRECRQ_PH_W      , 0,
+       DSP_                },        /* PRECRQ.PH.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000f5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200000fd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(31) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000105, &NMD::CMPGU_LT_QB      , 0,
+       DSP_                },        /* CMPGU.LT.QB */
+    { pool                , ADDU__S__PH         , 2   , 32,
+       0xfc0003ff, 0x2000010d, 0                      , 0,
+       0x0                 },        /* ADDU[_S].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000115, &NMD::MULQ_RS_PH       , 0,
+       DSP_                },        /* MULQ_RS.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000011d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(35) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000125, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(36) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000012d, &NMD::PRECRQ_RS_PH_W   , 0,
+       DSP_                },        /* PRECRQ_RS.PH.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000135, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(38) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000013d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(39) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000145, &NMD::CMPGU_LE_QB      , 0,
+       DSP_                },        /* CMPGU.LE.QB */
+    { pool                , ADDUH__R__QB        , 2   , 32,
+       0xfc0003ff, 0x2000014d, 0                      , 0,
+       0x0                 },        /* ADDUH[_R].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000155, &NMD::MULQ_S_PH        , 0,
+       DSP_                },        /* MULQ_S.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000015d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(43) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000165, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(44) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000016d, &NMD::PRECRQU_S_QB_PH  , 0,
+       DSP_                },        /* PRECRQU_S.QB.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000175, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(46) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000017d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(47) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000185, &NMD::CMPGDU_EQ_QB     , 0,
+       DSP_                },        /* CMPGDU.EQ.QB */
+    { pool                , SHRAV__R__PH        , 2   , 32,
+       0xfc0003ff, 0x2000018d, 0                      , 0,
+       0x0                 },        /* SHRAV[_R].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000195, &NMD::MULQ_RS_W        , 0,
+       DSP_                },        /* MULQ_RS.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000019d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(51) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001a5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(52) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001ad, &NMD::PACKRL_PH        , 0,
+       DSP_                },        /* PACKRL.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001b5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(54) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001bd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(55) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001c5, &NMD::CMPGDU_LT_QB     , 0,
+       DSP_                },        /* CMPGDU.LT.QB */
+    { pool                , SHRAV__R__QB        , 2   , 32,
+       0xfc0003ff, 0x200001cd, 0                      , 0,
+       0x0                 },        /* SHRAV[_R].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001d5, &NMD::MULQ_S_W         , 0,
+       DSP_                },        /* MULQ_S.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001dd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(59) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001e5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(60) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001ed, &NMD::PICK_QB          , 0,
+       DSP_                },        /* PICK.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001f5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(62) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200001fd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(63) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000205, &NMD::CMPGDU_LE_QB     , 0,
+       DSP_                },        /* CMPGDU.LE.QB */
+    { pool                , SUBQ__S__PH         , 2   , 32,
+       0xfc0003ff, 0x2000020d, 0                      , 0,
+       0x0                 },        /* SUBQ[_S].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000215, &NMD::APPEND           , 0,
+       DSP_                },        /* APPEND */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000021d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(67) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000225, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(68) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000022d, &NMD::PICK_PH          , 0,
+       DSP_                },        /* PICK.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000235, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(70) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000023d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(71) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000245, &NMD::CMPU_EQ_QB       , 0,
+       DSP_                },        /* CMPU.EQ.QB */
+    { pool                , SUBQH__R__PH        , 2   , 32,
+       0xfc0003ff, 0x2000024d, 0                      , 0,
+       0x0                 },        /* SUBQH[_R].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000255, &NMD::PREPEND          , 0,
+       DSP_                },        /* PREPEND */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000025d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(75) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000265, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(76) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000026d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(77) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000275, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(78) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000027d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(79) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000285, &NMD::CMPU_LT_QB       , 0,
+       DSP_                },        /* CMPU.LT.QB */
+    { pool                , SUBQH__R__W         , 2   , 32,
+       0xfc0003ff, 0x2000028d, 0                      , 0,
+       0x0                 },        /* SUBQH[_R].W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000295, &NMD::MODSUB           , 0,
+       DSP_                },        /* MODSUB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000029d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(83) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002a5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(84) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002ad, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(85) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002b5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(86) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002bd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(87) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002c5, &NMD::CMPU_LE_QB       , 0,
+       DSP_                },        /* CMPU.LE.QB */
+    { pool                , SUBU__S__QB         , 2   , 32,
+       0xfc0003ff, 0x200002cd, 0                      , 0,
+       0x0                 },        /* SUBU[_S].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002d5, &NMD::SHRAV_R_W        , 0,
+       DSP_                },        /* SHRAV_R.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002dd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(91) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002e5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(92) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002ed, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(93) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002f5, &NMD::SHRA_R_W         , 0,
+       DSP_                },        /* SHRA_R.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200002fd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(95) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000305, &NMD::ADDQ_S_W         , 0,
+       DSP_                },        /* ADDQ_S.W */
+    { pool                , SUBU__S__PH         , 2   , 32,
+       0xfc0003ff, 0x2000030d, 0                      , 0,
+       0x0                 },        /* SUBU[_S].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000315, &NMD::SHRLV_PH         , 0,
+       DSP_                },        /* SHRLV.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000031d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(99) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000325, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(100) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000032d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(101) */
+    { pool                , SHRA__R__PH         , 2   , 32,
+       0xfc0003ff, 0x20000335, 0                      , 0,
+       0x0                 },        /* SHRA[_R].PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000033d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(103) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000345, &NMD::SUBQ_S_W         , 0,
+       DSP_                },        /* SUBQ_S.W */
+    { pool                , SUBUH__R__QB        , 2   , 32,
+       0xfc0003ff, 0x2000034d, 0                      , 0,
+       0x0                 },        /* SUBUH[_R].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000355, &NMD::SHRLV_QB         , 0,
+       DSP_                },        /* SHRLV.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000035d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(107) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000365, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(108) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000036d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(109) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000375, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(110) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000037d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(111) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000385, &NMD::ADDSC            , 0,
+       DSP_                },        /* ADDSC */
+    { pool                , SHLLV__S__PH        , 2   , 32,
+       0xfc0003ff, 0x2000038d, 0                      , 0,
+       0x0                 },        /* SHLLV[_S].PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x20000395, &NMD::SHLLV_QB         , 0,
+       DSP_                },        /* SHLLV.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x2000039d, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(115) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003a5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(116) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003ad, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(117) */
+    { pool                , SHLL__S__PH         , 4   , 32,
+       0xfc0003ff, 0x200003b5, 0                      , 0,
+       0x0                 },        /* SHLL[_S].PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003bd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(119) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003c5, &NMD::ADDWC            , 0,
+       DSP_                },        /* ADDWC */
+    { pool                , PRECR_SRA__R__PH_W  , 2   , 32,
+       0xfc0003ff, 0x200003cd, 0                      , 0,
+       0x0                 },        /* PRECR_SRA[_R].PH.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003d5, &NMD::SHLLV_S_W        , 0,
+       DSP_                },        /* SHLLV_S.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003dd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(123) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003e5, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(124) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003ed, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(125) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003f5, &NMD::SHLL_S_W         , 0,
+       DSP_                },        /* SHLL_S.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0x200003fd, 0                      , 0,
+       0x0                 },        /* _POOL32A5~*(127) */
+};
+
+
+NMD::Pool NMD::PP_LSX[16] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000007, &NMD::LBX              , 0,
+       0x0                 },        /* LBX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000087, &NMD::SBX              , 0,
+       XMMS_               },        /* SBX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000107, &NMD::LBUX             , 0,
+       0x0                 },        /* LBUX */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000187, 0                      , 0,
+       0x0                 },        /* PP.LSX~*(3) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000207, &NMD::LHX              , 0,
+       0x0                 },        /* LHX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000287, &NMD::SHX              , 0,
+       XMMS_               },        /* SHX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000307, &NMD::LHUX             , 0,
+       0x0                 },        /* LHUX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000387, &NMD::LWUX             , 0,
+       MIPS64_             },        /* LWUX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000407, &NMD::LWX              , 0,
+       0x0                 },        /* LWX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000487, &NMD::SWX              , 0,
+       XMMS_               },        /* SWX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000507, &NMD::LWC1X            , 0,
+       CP1_                },        /* LWC1X */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000587, &NMD::SWC1X            , 0,
+       CP1_                },        /* SWC1X */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000607, &NMD::LDX              , 0,
+       MIPS64_             },        /* LDX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000687, &NMD::SDX              , 0,
+       MIPS64_             },        /* SDX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000707, &NMD::LDC1X            , 0,
+       CP1_                },        /* LDC1X */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000787, &NMD::SDC1X            , 0,
+       CP1_                },        /* SDC1X */
+};
+
+
+NMD::Pool NMD::PP_LSXS[16] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000047, 0                      , 0,
+       0x0                 },        /* PP.LSXS~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0x200000c7, 0                      , 0,
+       0x0                 },        /* PP.LSXS~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000147, 0                      , 0,
+       0x0                 },        /* PP.LSXS~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0x200001c7, 0                      , 0,
+       0x0                 },        /* PP.LSXS~*(3) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000247, &NMD::LHXS             , 0,
+       0x0                 },        /* LHXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200002c7, &NMD::SHXS             , 0,
+       XMMS_               },        /* SHXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000347, &NMD::LHUXS            , 0,
+       0x0                 },        /* LHUXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200003c7, &NMD::LWUXS            , 0,
+       MIPS64_             },        /* LWUXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000447, &NMD::LWXS_32_         , 0,
+       0x0                 },        /* LWXS[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200004c7, &NMD::SWXS             , 0,
+       XMMS_               },        /* SWXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000547, &NMD::LWC1XS           , 0,
+       CP1_                },        /* LWC1XS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200005c7, &NMD::SWC1XS           , 0,
+       CP1_                },        /* SWC1XS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000647, &NMD::LDXS             , 0,
+       MIPS64_             },        /* LDXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200006c7, &NMD::SDXS             , 0,
+       MIPS64_             },        /* SDXS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x20000747, &NMD::LDC1XS           , 0,
+       CP1_                },        /* LDC1XS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0x200007c7, &NMD::SDC1XS           , 0,
+       CP1_                },        /* SDC1XS */
+};
+
+
+NMD::Pool NMD::P_LSX[2] = {
+    { pool                , PP_LSX              , 16  , 32,
+       0xfc00007f, 0x20000007, 0                      , 0,
+       0x0                 },        /* PP.LSX */
+    { pool                , PP_LSXS             , 16  , 32,
+       0xfc00007f, 0x20000047, 0                      , 0,
+       0x0                 },        /* PP.LSXS */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_0[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000007f, &NMD::MFHI_DSP_        , 0,
+       DSP_                },        /* MFHI[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000107f, &NMD::MFLO_DSP_        , 0,
+       DSP_                },        /* MFLO[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000207f, &NMD::MTHI_DSP_        , 0,
+       DSP_                },        /* MTHI[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000307f, &NMD::MTLO_DSP_        , 0,
+       DSP_                },        /* MTLO[DSP] */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_1[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000027f, &NMD::MTHLIP           , 0,
+       DSP_                },        /* MTHLIP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000127f, &NMD::SHILOV           , 0,
+       DSP_                },        /* SHILOV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0x2000227f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_1~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0x2000327f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_1~*(3) */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_3[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000067f, &NMD::RDDSP            , 0,
+       DSP_                },        /* RDDSP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000167f, &NMD::WRDSP            , 0,
+       DSP_                },        /* WRDSP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000267f, &NMD::EXTP             , 0,
+       DSP_                },        /* EXTP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x2000367f, &NMD::EXTPDP           , 0,
+       DSP_                },        /* EXTPDP */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_4[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc001fff, 0x2000087f, &NMD::SHLL_QB          , 0,
+       DSP_                },        /* SHLL.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc001fff, 0x2000187f, &NMD::SHRL_QB          , 0,
+       DSP_                },        /* SHRL.QB */
+};
+
+
+NMD::Pool NMD::MAQ_S_A__W_PHR[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20000a7f, &NMD::MAQ_S_W_PHR      , 0,
+       DSP_                },        /* MAQ_S.W.PHR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20002a7f, &NMD::MAQ_SA_W_PHR     , 0,
+       DSP_                },        /* MAQ_SA.W.PHR */
+};
+
+
+NMD::Pool NMD::MAQ_S_A__W_PHL[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20001a7f, &NMD::MAQ_S_W_PHL      , 0,
+       DSP_                },        /* MAQ_S.W.PHL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20003a7f, &NMD::MAQ_SA_W_PHL     , 0,
+       DSP_                },        /* MAQ_SA.W.PHL */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_5[2] = {
+    { pool                , MAQ_S_A__W_PHR      , 2   , 32,
+       0xfc001fff, 0x20000a7f, 0                      , 0,
+       0x0                 },        /* MAQ_S[A].W.PHR */
+    { pool                , MAQ_S_A__W_PHL      , 2   , 32,
+       0xfc001fff, 0x20001a7f, 0                      , 0,
+       0x0                 },        /* MAQ_S[A].W.PHL */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1_7[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20000e7f, &NMD::EXTR_W           , 0,
+       DSP_                },        /* EXTR.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20001e7f, &NMD::EXTR_R_W         , 0,
+       DSP_                },        /* EXTR_R.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20002e7f, &NMD::EXTR_RS_W        , 0,
+       DSP_                },        /* EXTR_RS.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20003e7f, &NMD::EXTR_S_H         , 0,
+       DSP_                },        /* EXTR_S.H */
+};
+
+
+NMD::Pool NMD::POOL32Axf_1[8] = {
+    { pool                , POOL32Axf_1_0       , 4   , 32,
+       0xfc000fff, 0x2000007f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_0 */
+    { pool                , POOL32Axf_1_1       , 4   , 32,
+       0xfc000fff, 0x2000027f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x2000047f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1~*(2) */
+    { pool                , POOL32Axf_1_3       , 4   , 32,
+       0xfc000fff, 0x2000067f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_3 */
+    { pool                , POOL32Axf_1_4       , 2   , 32,
+       0xfc000fff, 0x2000087f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_4 */
+    { pool                , POOL32Axf_1_5       , 2   , 32,
+       0xfc000fff, 0x20000a7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_5 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x20000c7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1~*(6) */
+    { pool                , POOL32Axf_1_7       , 4   , 32,
+       0xfc000fff, 0x20000e7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1_7 */
+};
+
+
+NMD::Pool NMD::POOL32Axf_2_DSP__0_7[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200000bf, &NMD::DPA_W_PH         , 0,
+       DSP_                },        /* DPA.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200002bf, &NMD::DPAQ_S_W_PH      , 0,
+       DSP_                },        /* DPAQ_S.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200004bf, &NMD::DPS_W_PH         , 0,
+       DSP_                },        /* DPS.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200006bf, &NMD::DPSQ_S_W_PH      , 0,
+       DSP_                },        /* DPSQ_S.W.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0x200008bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_0_7~*(4) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20000abf, &NMD::MADD_DSP_        , 0,
+       DSP_                },        /* MADD[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20000cbf, &NMD::MULT_DSP_        , 0,
+       DSP_                },        /* MULT[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20000ebf, &NMD::EXTRV_W          , 0,
+       DSP_                },        /* EXTRV.W */
+};
+
+
+NMD::Pool NMD::POOL32Axf_2_DSP__8_15[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200010bf, &NMD::DPAX_W_PH        , 0,
+       DSP_                },        /* DPAX.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200012bf, &NMD::DPAQ_SA_L_W      , 0,
+       DSP_                },        /* DPAQ_SA.L.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200014bf, &NMD::DPSX_W_PH        , 0,
+       DSP_                },        /* DPSX.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200016bf, &NMD::DPSQ_SA_L_W      , 0,
+       DSP_                },        /* DPSQ_SA.L.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0x200018bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_8_15~*(4) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20001abf, &NMD::MADDU_DSP_       , 0,
+       DSP_                },        /* MADDU[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20001cbf, &NMD::MULTU_DSP_       , 0,
+       DSP_                },        /* MULTU[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20001ebf, &NMD::EXTRV_R_W        , 0,
+       DSP_                },        /* EXTRV_R.W */
+};
+
+
+NMD::Pool NMD::POOL32Axf_2_DSP__16_23[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200020bf, &NMD::DPAU_H_QBL       , 0,
+       DSP_                },        /* DPAU.H.QBL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200022bf, &NMD::DPAQX_S_W_PH     , 0,
+       DSP_                },        /* DPAQX_S.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200024bf, &NMD::DPSU_H_QBL       , 0,
+       DSP_                },        /* DPSU.H.QBL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200026bf, &NMD::DPSQX_S_W_PH     , 0,
+       DSP_                },        /* DPSQX_S.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200028bf, &NMD::EXTPV            , 0,
+       DSP_                },        /* EXTPV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20002abf, &NMD::MSUB_DSP_        , 0,
+       DSP_                },        /* MSUB[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20002cbf, &NMD::MULSA_W_PH       , 0,
+       DSP_                },        /* MULSA.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20002ebf, &NMD::EXTRV_RS_W       , 0,
+       DSP_                },        /* EXTRV_RS.W */
+};
+
+
+NMD::Pool NMD::POOL32Axf_2_DSP__24_31[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200030bf, &NMD::DPAU_H_QBR       , 0,
+       DSP_                },        /* DPAU.H.QBR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200032bf, &NMD::DPAQX_SA_W_PH    , 0,
+       DSP_                },        /* DPAQX_SA.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200034bf, &NMD::DPSU_H_QBR       , 0,
+       DSP_                },        /* DPSU.H.QBR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200036bf, &NMD::DPSQX_SA_W_PH    , 0,
+       DSP_                },        /* DPSQX_SA.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x200038bf, &NMD::EXTPDPV          , 0,
+       DSP_                },        /* EXTPDPV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20003abf, &NMD::MSUBU_DSP_       , 0,
+       DSP_                },        /* MSUBU[DSP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20003cbf, &NMD::MULSAQ_S_W_PH    , 0,
+       DSP_                },        /* MULSAQ_S.W.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0x20003ebf, &NMD::EXTRV_S_H        , 0,
+       DSP_                },        /* EXTRV_S.H */
+};
+
+
+NMD::Pool NMD::POOL32Axf_2[4] = {
+    { pool                , POOL32Axf_2_DSP__0_7, 8   , 32,
+       0xfc0031ff, 0x200000bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_0_7 */
+    { pool                , POOL32Axf_2_DSP__8_15, 8   , 32,
+       0xfc0031ff, 0x200010bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_8_15 */
+    { pool                , POOL32Axf_2_DSP__16_23, 8   , 32,
+       0xfc0031ff, 0x200020bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_16_23 */
+    { pool                , POOL32Axf_2_DSP__24_31, 8   , 32,
+       0xfc0031ff, 0x200030bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2(DSP)_24_31 */
+};
+
+
+NMD::Pool NMD::POOL32Axf_4[128] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000013f, &NMD::ABSQ_S_QB        , 0,
+       DSP_                },        /* ABSQ_S.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000033f, &NMD::REPLV_PH         , 0,
+       DSP_                },        /* REPLV.PH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000053f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000073f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000093f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000d3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(7) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000113f, &NMD::ABSQ_S_PH        , 0,
+       DSP_                },        /* ABSQ_S.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000133f, &NMD::REPLV_QB         , 0,
+       DSP_                },        /* REPLV.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000153f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000173f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000193f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001d3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(15) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000213f, &NMD::ABSQ_S_W         , 0,
+       DSP_                },        /* ABSQ_S.W */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000233f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000253f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000273f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000293f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002d3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000313f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000333f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000353f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000373f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000393f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003d3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(31) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000413f, &NMD::INSV             , 0,
+       DSP_                },        /* INSV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000433f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(33) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000453f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(34) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000473f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(35) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000493f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(36) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004b3f, &NMD::CLO              , 0,
+       XMMS_               },        /* CLO */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004d3f, &NMD::MFC2             , 0,
+       CP2_                },        /* MFC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(39) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000513f, &NMD::PRECEQ_W_PHL     , 0,
+       DSP_                },        /* PRECEQ.W.PHL */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000533f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(41) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000553f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(42) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000573f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(43) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000593f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(44) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005b3f, &NMD::CLZ              , 0,
+       XMMS_               },        /* CLZ */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005d3f, &NMD::MTC2             , 0,
+       CP2_                },        /* MTC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(47) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000613f, &NMD::PRECEQ_W_PHR     , 0,
+       DSP_                },        /* PRECEQ.W.PHR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000633f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(49) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000653f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(50) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000673f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(51) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000693f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(53) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006d3f, &NMD::DMFC2            , 0,
+       CP2_                },        /* DMFC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(55) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000713f, &NMD::PRECEQU_PH_QBL   , 0,
+       DSP_                },        /* PRECEQU.PH.QBL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000733f, &NMD::PRECEQU_PH_QBLA  , 0,
+       DSP_                },        /* PRECEQU.PH.QBLA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000753f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(58) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000773f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(59) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000793f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(61) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007d3f, &NMD::DMTC2            , 0,
+       CP2_                },        /* DMTC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(63) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000813f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(64) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000833f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(65) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000853f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(66) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000873f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(67) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000893f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(68) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20008b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(69) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20008d3f, &NMD::MFHC2            , 0,
+       CP2_                },        /* MFHC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20008f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(71) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000913f, &NMD::PRECEQU_PH_QBR   , 0,
+       DSP_                },        /* PRECEQU.PH.QBR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000933f, &NMD::PRECEQU_PH_QBRA  , 0,
+       DSP_                },        /* PRECEQU.PH.QBRA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000953f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(74) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000973f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(75) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000993f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(76) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20009b3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(77) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x20009d3f, &NMD::MTHC2            , 0,
+       CP2_                },        /* MTHC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20009f3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(79) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000a13f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(80) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000a33f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(81) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000a53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(82) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000a73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(83) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000a93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(84) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ab3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(85) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ad3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(86) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000af3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(87) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000b13f, &NMD::PRECEU_PH_QBL    , 0,
+       DSP_                },        /* PRECEU.PH.QBL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000b33f, &NMD::PRECEU_PH_QBLA   , 0,
+       DSP_                },        /* PRECEU.PH.QBLA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000b53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(90) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000b73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(91) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000b93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(92) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000bb3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(93) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000bd3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(94) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000bf3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(95) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c13f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(96) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c33f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(97) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(98) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(99) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(100) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cb3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(101) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cd3f, &NMD::CFC2             , 0,
+       CP2_                },        /* CFC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cf3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(103) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d13f, &NMD::PRECEU_PH_QBR    , 0,
+       DSP_                },        /* PRECEU.PH.QBR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d33f, &NMD::PRECEU_PH_QBRA   , 0,
+       DSP_                },        /* PRECEU.PH.QBRA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(106) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(107) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(108) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000db3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(109) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000dd3f, &NMD::CTC2             , 0,
+       CP2_                },        /* CTC2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000df3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(111) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e13f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(112) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e33f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(113) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(114) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(115) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(116) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000eb3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(117) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ed3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(118) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ef3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(119) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f13f, &NMD::RADDU_W_QB       , 0,
+       DSP_                },        /* RADDU.W.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f33f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(121) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f53f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(122) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f73f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(123) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f93f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(124) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000fb3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(125) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000fd3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(126) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ff3f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4~*(127) */
+};
+
+
+NMD::Pool NMD::POOL32Axf_5_group0[32] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000017f, &NMD::TLBGP            , 0,
+       CP0_ | VZ_ | TLB_   },        /* TLBGP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000037f, &NMD::TLBP             , 0,
+       CP0_ | TLB_         },        /* TLBP */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000057f, &NMD::TLBGINV          , 0,
+       CP0_ | VZ_ | TLB_ | TLBINV_},        /* TLBGINV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000077f, &NMD::TLBINV           , 0,
+       CP0_ | TLB_ | TLBINV_},        /* TLBINV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000097f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20000f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(7) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000117f, &NMD::TLBGR            , 0,
+       CP0_ | VZ_ | TLB_   },        /* TLBGR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000137f, &NMD::TLBR             , 0,
+       CP0_ | TLB_         },        /* TLBR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000157f, &NMD::TLBGINVF         , 0,
+       CP0_ | VZ_ | TLB_ | TLBINV_},        /* TLBGINVF */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000177f, &NMD::TLBINVF          , 0,
+       CP0_ | TLB_ | TLBINV_},        /* TLBINVF */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000197f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20001f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(15) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000217f, &NMD::TLBGWI           , 0,
+       CP0_ | VZ_ | TLB_   },        /* TLBGWI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000237f, &NMD::TLBWI            , 0,
+       CP0_ | TLB_         },        /* TLBWI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000257f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000277f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000297f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20002f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(23) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000317f, &NMD::TLBGWR           , 0,
+       CP0_ | VZ_ | TLB_   },        /* TLBGWR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000337f, &NMD::TLBWR            , 0,
+       CP0_ | TLB_         },        /* TLBWR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000357f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000377f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000397f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20003f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0~*(31) */
+};
+
+
+NMD::Pool NMD::POOL32Axf_5_group1[32] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000417f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000437f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000457f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(2) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000477f, &NMD::DI               , 0,
+       0x0                 },        /* DI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000497f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20004f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000517f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000537f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000557f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(10) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000577f, &NMD::EI               , 0,
+       0x0                 },        /* EI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000597f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20005f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000617f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000637f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000657f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000677f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000697f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20006f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000717f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000737f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000757f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000777f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000797f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007b7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007d7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x20007f7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1~*(31) */
+};
+
+
+NMD::Pool NMD::ERETx[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc01ffff, 0x2000f37f, &NMD::ERET             , 0,
+       0x0                 },        /* ERET */
+    { instruction         , 0                   , 0   , 32,
+       0xfc01ffff, 0x2001f37f, &NMD::ERETNC           , 0,
+       0x0                 },        /* ERETNC */
+};
+
+
+NMD::Pool NMD::POOL32Axf_5_group3[32] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c17f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(0) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c37f, &NMD::WAIT             , 0,
+       0x0                 },        /* WAIT */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c57f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c77f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000c97f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cb7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cd7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000cf7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d17f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(8) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d37f, &NMD::IRET             , 0,
+       MCU_                },        /* IRET */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d57f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d77f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000d97f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000db7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000dd7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000df7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(15) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e17f, &NMD::RDPGPR           , 0,
+       CP0_                },        /* RDPGPR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e37f, &NMD::DERET            , 0,
+       EJTAG_              },        /* DERET */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e57f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e77f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000e97f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000eb7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ed7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ef7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(23) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f17f, &NMD::WRPGPR           , 0,
+       CP0_                },        /* WRPGPR */
+    { pool                , ERETx               , 2   , 32,
+       0xfc00ffff, 0x2000f37f, 0                      , 0,
+       0x0                 },        /* ERETx */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f57f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f77f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000f97f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000fb7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000fd7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0x2000ff7f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3~*(31) */
+};
+
+
+NMD::Pool NMD::POOL32Axf_5[4] = {
+    { pool                , POOL32Axf_5_group0  , 32  , 32,
+       0xfc00c1ff, 0x2000017f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group0 */
+    { pool                , POOL32Axf_5_group1  , 32  , 32,
+       0xfc00c1ff, 0x2000417f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00c1ff, 0x2000817f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5~*(2) */
+    { pool                , POOL32Axf_5_group3  , 32  , 32,
+       0xfc00c1ff, 0x2000c17f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5_group3 */
+};
+
+
+NMD::Pool NMD::SHRA__R__QB[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc001fff, 0x200001ff, &NMD::SHRA_QB          , 0,
+       DSP_                },        /* SHRA.QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc001fff, 0x200011ff, &NMD::SHRA_R_QB        , 0,
+       DSP_                },        /* SHRA_R.QB */
+};
+
+
+NMD::Pool NMD::POOL32Axf_7[8] = {
+    { pool                , SHRA__R__QB         , 2   , 32,
+       0xfc000fff, 0x200001ff, 0                      , 0,
+       0x0                 },        /* SHRA[_R].QB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000fff, 0x200003ff, &NMD::SHRL_PH          , 0,
+       DSP_                },        /* SHRL.PH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000fff, 0x200005ff, &NMD::REPL_QB          , 0,
+       DSP_                },        /* REPL.QB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x200007ff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x200009ff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x20000bff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x20000dff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000fff, 0x20000fff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7~*(7) */
+};
+
+
+NMD::Pool NMD::POOL32Axf[8] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0x2000003f, 0                      , 0,
+       0x0                 },        /* POOL32Axf~*(0) */
+    { pool                , POOL32Axf_1         , 8   , 32,
+       0xfc0001ff, 0x2000007f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_1 */
+    { pool                , POOL32Axf_2         , 4   , 32,
+       0xfc0001ff, 0x200000bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf_2 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0x200000ff, 0                      , 0,
+       0x0                 },        /* POOL32Axf~*(3) */
+    { pool                , POOL32Axf_4         , 128 , 32,
+       0xfc0001ff, 0x2000013f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_4 */
+    { pool                , POOL32Axf_5         , 4   , 32,
+       0xfc0001ff, 0x2000017f, 0                      , 0,
+       0x0                 },        /* POOL32Axf_5 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0x200001bf, 0                      , 0,
+       0x0                 },        /* POOL32Axf~*(6) */
+    { pool                , POOL32Axf_7         , 8   , 32,
+       0xfc0001ff, 0x200001ff, 0                      , 0,
+       0x0                 },        /* POOL32Axf_7 */
+};
+
+
+NMD::Pool NMD::_POOL32A7[8] = {
+    { pool                , P_LSX               , 2   , 32,
+       0xfc00003f, 0x20000007, 0                      , 0,
+       0x0                 },        /* P.LSX */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00003f, 0x2000000f, &NMD::LSA              , 0,
+       0x0                 },        /* LSA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0x20000017, 0                      , 0,
+       0x0                 },        /* _POOL32A7~*(2) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00003f, 0x2000001f, &NMD::EXTW             , 0,
+       0x0                 },        /* EXTW */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0x20000027, 0                      , 0,
+       0x0                 },        /* _POOL32A7~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0x2000002f, 0                      , 0,
+       0x0                 },        /* _POOL32A7~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0x20000037, 0                      , 0,
+       0x0                 },        /* _POOL32A7~*(6) */
+    { pool                , POOL32Axf           , 8   , 32,
+       0xfc00003f, 0x2000003f, 0                      , 0,
+       0x0                 },        /* POOL32Axf */
+};
+
+
+NMD::Pool NMD::P32A[8] = {
+    { pool                , _POOL32A0           , 128 , 32,
+       0xfc000007, 0x20000000, 0                      , 0,
+       0x0                 },        /* _POOL32A0 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000007, 0x20000001, &NMD::SPECIAL2         , 0,
+       UDI_                },        /* SPECIAL2 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000007, 0x20000002, &NMD::COP2_1           , 0,
+       CP2_                },        /* COP2_1 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000007, 0x20000003, &NMD::UDI              , 0,
+       UDI_                },        /* UDI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0x20000004, 0                      , 0,
+       0x0                 },        /* P32A~*(4) */
+    { pool                , _POOL32A5           , 128 , 32,
+       0xfc000007, 0x20000005, 0                      , 0,
+       0x0                 },        /* _POOL32A5 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0x20000006, 0                      , 0,
+       0x0                 },        /* P32A~*(6) */
+    { pool                , _POOL32A7           , 8   , 32,
+       0xfc000007, 0x20000007, 0                      , 0,
+       0x0                 },        /* _POOL32A7 */
+};
+
+
+NMD::Pool NMD::P_GP_D[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000007, 0x40000001, &NMD::LD_GP_           , 0,
+       MIPS64_             },        /* LD[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000007, 0x40000005, &NMD::SD_GP_           , 0,
+       MIPS64_             },        /* SD[GP] */
+};
+
+
+NMD::Pool NMD::P_GP_W[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000003, 0x40000000, &NMD::ADDIU_GP_W_      , 0,
+       0x0                 },        /* ADDIU[GP.W] */
+    { pool                , P_GP_D              , 2   , 32,
+       0xfc000003, 0x40000001, 0                      , 0,
+       0x0                 },        /* P.GP.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000003, 0x40000002, &NMD::LW_GP_           , 0,
+       0x0                 },        /* LW[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000003, 0x40000003, &NMD::SW_GP_           , 0,
+       0x0                 },        /* SW[GP] */
+};
+
+
+NMD::Pool NMD::POOL48I[32] = {
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600000000000ull, &NMD::LI_48_           , 0,
+       XMMS_               },        /* LI[48] */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600100000000ull, &NMD::ADDIU_48_        , 0,
+       XMMS_               },        /* ADDIU[48] */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600200000000ull, &NMD::ADDIU_GP48_      , 0,
+       XMMS_               },        /* ADDIU[GP48] */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600300000000ull, &NMD::ADDIUPC_48_      , 0,
+       XMMS_               },        /* ADDIUPC[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600400000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(4) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600500000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(5) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600600000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(6) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600700000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(7) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600800000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(8) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600900000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(9) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600a00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(10) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600b00000000ull, &NMD::LWPC_48_         , 0,
+       XMMS_               },        /* LWPC[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600c00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(12) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600d00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(13) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600e00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(14) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x600f00000000ull, &NMD::SWPC_48_         , 0,
+       XMMS_               },        /* SWPC[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601000000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(16) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601100000000ull, &NMD::DADDIU_48_       , 0,
+       MIPS64_             },        /* DADDIU[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601200000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(18) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601300000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(19) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601400000000ull, &NMD::DLUI_48_         , 0,
+       MIPS64_             },        /* DLUI[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601500000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(21) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601600000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(22) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601700000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(23) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601800000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(24) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601900000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(25) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601a00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(26) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601b00000000ull, &NMD::LDPC_48_         , 0,
+       MIPS64_             },        /* LDPC[48] */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601c00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(28) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601d00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(29) */
+    { reserved_block      , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601e00000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I~*(30) */
+    { instruction         , 0                   , 0   , 48,
+       0xfc1f00000000ull, 0x601f00000000ull, &NMD::SDPC_48_         , 0,
+       MIPS64_             },        /* SDPC[48] */
+};
+
+
+NMD::Pool NMD::PP_SR[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc10f003, 0x80003000, &NMD::SAVE_32_         , 0,
+       0x0                 },        /* SAVE[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f003, 0x80003001, 0                      , 0,
+       0x0                 },        /* PP.SR~*(1) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc10f003, 0x80003002, &NMD::RESTORE_32_      , 0,
+       0x0                 },        /* RESTORE[32] */
+    { return_instruction  , 0                   , 0   , 32,
+       0xfc10f003, 0x80003003, &NMD::RESTORE_JRC_32_  , 0,
+       0x0                 },        /* RESTORE.JRC[32] */
+};
+
+
+NMD::Pool NMD::P_SR_F[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc10f007, 0x80103000, &NMD::SAVEF            , 0,
+       CP1_                },        /* SAVEF */
+    { instruction         , 0                   , 0   , 32,
+       0xfc10f007, 0x80103001, &NMD::RESTOREF         , 0,
+       CP1_                },        /* RESTOREF */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103002, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103003, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103004, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103005, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103006, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc10f007, 0x80103007, 0                      , 0,
+       0x0                 },        /* P.SR.F~*(7) */
+};
+
+
+NMD::Pool NMD::P_SR[2] = {
+    { pool                , PP_SR               , 4   , 32,
+       0xfc10f000, 0x80003000, 0                      , 0,
+       0x0                 },        /* PP.SR */
+    { pool                , P_SR_F              , 8   , 32,
+       0xfc10f000, 0x80103000, 0                      , 0,
+       0x0                 },        /* P.SR.F */
+};
+
+
+NMD::Pool NMD::P_SLL[5] = {
+    { instruction         , 0                   , 0   , 32,
+       0xffe0f1ff, 0x8000c000, &NMD::NOP_32_          , 0,
+       0x0                 },        /* NOP[32] */
+    { instruction         , 0                   , 0   , 32,
+       0xffe0f1ff, 0x8000c003, &NMD::EHB              , 0,
+       0x0                 },        /* EHB */
+    { instruction         , 0                   , 0   , 32,
+       0xffe0f1ff, 0x8000c005, &NMD::PAUSE            , 0,
+       0x0                 },        /* PAUSE */
+    { instruction         , 0                   , 0   , 32,
+       0xffe0f1ff, 0x8000c006, &NMD::SYNC             , 0,
+       0x0                 },        /* SYNC */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c000, &NMD::SLL_32_          , 0,
+       0x0                 },        /* SLL[32] */
+};
+
+
+NMD::Pool NMD::P_SHIFT[16] = {
+    { pool                , P_SLL               , 5   , 32,
+       0xfc00f1e0, 0x8000c000, 0                      , 0,
+       0x0                 },        /* P.SLL */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c020, 0                      , 0,
+       0x0                 },        /* P.SHIFT~*(1) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c040, &NMD::SRL_32_          , 0,
+       0x0                 },        /* SRL[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c060, 0                      , 0,
+       0x0                 },        /* P.SHIFT~*(3) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c080, &NMD::SRA              , 0,
+       0x0                 },        /* SRA */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c0a0, 0                      , 0,
+       0x0                 },        /* P.SHIFT~*(5) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c0c0, &NMD::ROTR             , 0,
+       0x0                 },        /* ROTR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c0e0, 0                      , 0,
+       0x0                 },        /* P.SHIFT~*(7) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c100, &NMD::DSLL             , 0,
+       MIPS64_             },        /* DSLL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c120, &NMD::DSLL32           , 0,
+       MIPS64_             },        /* DSLL32 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c140, &NMD::DSRL             , 0,
+       MIPS64_             },        /* DSRL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c160, &NMD::DSRL32           , 0,
+       MIPS64_             },        /* DSRL32 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c180, &NMD::DSRA             , 0,
+       MIPS64_             },        /* DSRA */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c1a0, &NMD::DSRA32           , 0,
+       MIPS64_             },        /* DSRA32 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c1c0, &NMD::DROTR            , 0,
+       MIPS64_             },        /* DROTR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f1e0, 0x8000c1e0, &NMD::DROTR32          , 0,
+       MIPS64_             },        /* DROTR32 */
+};
+
+
+NMD::Pool NMD::P_ROTX[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000d000, &NMD::ROTX             , 0,
+       XMMS_               },        /* ROTX */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f820, 0x8000d020, 0                      , 0,
+       0x0                 },        /* P.ROTX~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f820, 0x8000d800, 0                      , 0,
+       0x0                 },        /* P.ROTX~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f820, 0x8000d820, 0                      , 0,
+       0x0                 },        /* P.ROTX~*(3) */
+};
+
+
+NMD::Pool NMD::P_INS[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000e000, &NMD::INS              , 0,
+       XMMS_               },        /* INS */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000e020, &NMD::DINSU            , 0,
+       MIPS64_             },        /* DINSU */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000e800, &NMD::DINSM            , 0,
+       MIPS64_             },        /* DINSM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000e820, &NMD::DINS             , 0,
+       MIPS64_             },        /* DINS */
+};
+
+
+NMD::Pool NMD::P_EXT[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000f000, &NMD::EXT              , 0,
+       XMMS_               },        /* EXT */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000f020, &NMD::DEXTU            , 0,
+       MIPS64_             },        /* DEXTU */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000f800, &NMD::DEXTM            , 0,
+       MIPS64_             },        /* DEXTM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f820, 0x8000f820, &NMD::DEXT             , 0,
+       MIPS64_             },        /* DEXT */
+};
+
+
+NMD::Pool NMD::P_U12[16] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80000000, &NMD::ORI              , 0,
+       0x0                 },        /* ORI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80001000, &NMD::XORI             , 0,
+       0x0                 },        /* XORI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80002000, &NMD::ANDI_32_         , 0,
+       0x0                 },        /* ANDI[32] */
+    { pool                , P_SR                , 2   , 32,
+       0xfc00f000, 0x80003000, 0                      , 0,
+       0x0                 },        /* P.SR */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80004000, &NMD::SLTI             , 0,
+       0x0                 },        /* SLTI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80005000, &NMD::SLTIU            , 0,
+       0x0                 },        /* SLTIU */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80006000, &NMD::SEQI             , 0,
+       0x0                 },        /* SEQI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x80007000, 0                      , 0,
+       0x0                 },        /* P.U12~*(7) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80008000, &NMD::ADDIU_NEG_       , 0,
+       0x0                 },        /* ADDIU[NEG] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x80009000, &NMD::DADDIU_U12_      , 0,
+       MIPS64_             },        /* DADDIU[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8000a000, &NMD::DADDIU_NEG_      , 0,
+       MIPS64_             },        /* DADDIU[NEG] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8000b000, &NMD::DROTX            , 0,
+       MIPS64_             },        /* DROTX */
+    { pool                , P_SHIFT             , 16  , 32,
+       0xfc00f000, 0x8000c000, 0                      , 0,
+       0x0                 },        /* P.SHIFT */
+    { pool                , P_ROTX              , 4   , 32,
+       0xfc00f000, 0x8000d000, 0                      , 0,
+       0x0                 },        /* P.ROTX */
+    { pool                , P_INS               , 4   , 32,
+       0xfc00f000, 0x8000e000, 0                      , 0,
+       0x0                 },        /* P.INS */
+    { pool                , P_EXT               , 4   , 32,
+       0xfc00f000, 0x8000f000, 0                      , 0,
+       0x0                 },        /* P.EXT */
+};
+
+
+NMD::Pool NMD::RINT_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000020, &NMD::RINT_S           , 0,
+       CP1_                },        /* RINT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000220, &NMD::RINT_D           , 0,
+       CP1_                },        /* RINT.D */
+};
+
+
+NMD::Pool NMD::ADD_fmt0[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000030, &NMD::ADD_S            , 0,
+       CP1_                },        /* ADD.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000230, 0                      , 0,
+       CP1_                },        /* ADD.fmt0~*(1) */
+};
+
+
+NMD::Pool NMD::SELEQZ_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000038, &NMD::SELEQZ_S         , 0,
+       CP1_                },        /* SELEQZ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000238, &NMD::SELEQZ_D         , 0,
+       CP1_                },        /* SELEQZ.D */
+};
+
+
+NMD::Pool NMD::CLASS_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000060, &NMD::CLASS_S          , 0,
+       CP1_                },        /* CLASS.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000260, &NMD::CLASS_D          , 0,
+       CP1_                },        /* CLASS.D */
+};
+
+
+NMD::Pool NMD::SUB_fmt0[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000070, &NMD::SUB_S            , 0,
+       CP1_                },        /* SUB.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000270, 0                      , 0,
+       CP1_                },        /* SUB.fmt0~*(1) */
+};
+
+
+NMD::Pool NMD::SELNEZ_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000078, &NMD::SELNEZ_S         , 0,
+       CP1_                },        /* SELNEZ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000278, &NMD::SELNEZ_D         , 0,
+       CP1_                },        /* SELNEZ.D */
+};
+
+
+NMD::Pool NMD::MUL_fmt0[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00000b0, &NMD::MUL_S            , 0,
+       CP1_                },        /* MUL.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00002b0, 0                      , 0,
+       CP1_                },        /* MUL.fmt0~*(1) */
+};
+
+
+NMD::Pool NMD::SEL_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00000b8, &NMD::SEL_S            , 0,
+       CP1_                },        /* SEL.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00002b8, &NMD::SEL_D            , 0,
+       CP1_                },        /* SEL.D */
+};
+
+
+NMD::Pool NMD::DIV_fmt0[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00000f0, &NMD::DIV_S            , 0,
+       CP1_                },        /* DIV.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00002f0, 0                      , 0,
+       CP1_                },        /* DIV.fmt0~*(1) */
+};
+
+
+NMD::Pool NMD::ADD_fmt1[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000130, &NMD::ADD_D            , 0,
+       CP1_                },        /* ADD.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000330, 0                      , 0,
+       CP1_                },        /* ADD.fmt1~*(1) */
+};
+
+
+NMD::Pool NMD::SUB_fmt1[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000170, &NMD::SUB_D            , 0,
+       CP1_                },        /* SUB.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa0000370, 0                      , 0,
+       CP1_                },        /* SUB.fmt1~*(1) */
+};
+
+
+NMD::Pool NMD::MUL_fmt1[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00001b0, &NMD::MUL_D            , 0,
+       CP1_                },        /* MUL.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00003b0, 0                      , 0,
+       CP1_                },        /* MUL.fmt1~*(1) */
+};
+
+
+NMD::Pool NMD::MADDF_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00001b8, &NMD::MADDF_S          , 0,
+       CP1_                },        /* MADDF.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00003b8, &NMD::MADDF_D          , 0,
+       CP1_                },        /* MADDF.D */
+};
+
+
+NMD::Pool NMD::DIV_fmt1[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00001f0, &NMD::DIV_D            , 0,
+       CP1_                },        /* DIV.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00003f0, 0                      , 0,
+       CP1_                },        /* DIV.fmt1~*(1) */
+};
+
+
+NMD::Pool NMD::MSUBF_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00001f8, &NMD::MSUBF_S          , 0,
+       CP1_                },        /* MSUBF.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0003ff, 0xa00003f8, &NMD::MSUBF_D          , 0,
+       CP1_                },        /* MSUBF.D */
+};
+
+
+NMD::Pool NMD::POOL32F_0[64] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000000, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000008, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000010, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000018, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(3) */
+    { pool                , RINT_fmt            , 2   , 32,
+       0xfc0001ff, 0xa0000020, 0                      , 0,
+       CP1_                },        /* RINT.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000028, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(5) */
+    { pool                , ADD_fmt0            , 2   , 32,
+       0xfc0001ff, 0xa0000030, 0                      , 0,
+       CP1_                },        /* ADD.fmt0 */
+    { pool                , SELEQZ_fmt          , 2   , 32,
+       0xfc0001ff, 0xa0000038, 0                      , 0,
+       CP1_                },        /* SELEQZ.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000040, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000048, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000050, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000058, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(11) */
+    { pool                , CLASS_fmt           , 2   , 32,
+       0xfc0001ff, 0xa0000060, 0                      , 0,
+       CP1_                },        /* CLASS.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000068, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(13) */
+    { pool                , SUB_fmt0            , 2   , 32,
+       0xfc0001ff, 0xa0000070, 0                      , 0,
+       CP1_                },        /* SUB.fmt0 */
+    { pool                , SELNEZ_fmt          , 2   , 32,
+       0xfc0001ff, 0xa0000078, 0                      , 0,
+       CP1_                },        /* SELNEZ.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000080, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000088, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000090, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000098, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000a0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000a8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(21) */
+    { pool                , MUL_fmt0            , 2   , 32,
+       0xfc0001ff, 0xa00000b0, 0                      , 0,
+       CP1_                },        /* MUL.fmt0 */
+    { pool                , SEL_fmt             , 2   , 32,
+       0xfc0001ff, 0xa00000b8, 0                      , 0,
+       CP1_                },        /* SEL.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000c0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000c8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000d0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000d8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000e0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000e8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(29) */
+    { pool                , DIV_fmt0            , 2   , 32,
+       0xfc0001ff, 0xa00000f0, 0                      , 0,
+       CP1_                },        /* DIV.fmt0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00000f8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(31) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000100, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(32) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000108, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(33) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000110, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(34) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000118, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(35) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000120, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(36) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000128, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(37) */
+    { pool                , ADD_fmt1            , 2   , 32,
+       0xfc0001ff, 0xa0000130, 0                      , 0,
+       CP1_                },        /* ADD.fmt1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000138, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(39) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000140, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(40) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000148, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(41) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000150, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(42) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000158, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(43) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000160, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(44) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000168, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(45) */
+    { pool                , SUB_fmt1            , 2   , 32,
+       0xfc0001ff, 0xa0000170, 0                      , 0,
+       CP1_                },        /* SUB.fmt1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000178, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(47) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000180, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(48) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000188, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(49) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000190, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(50) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa0000198, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(51) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001a0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001a8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(53) */
+    { pool                , MUL_fmt1            , 2   , 32,
+       0xfc0001ff, 0xa00001b0, 0                      , 0,
+       CP1_                },        /* MUL.fmt1 */
+    { pool                , MADDF_fmt           , 2   , 32,
+       0xfc0001ff, 0xa00001b8, 0                      , 0,
+       CP1_                },        /* MADDF.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001c0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(56) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001c8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(57) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001d0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(58) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001d8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(59) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001e0, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xa00001e8, 0                      , 0,
+       CP1_                },        /* POOL32F_0~*(61) */
+    { pool                , DIV_fmt1            , 2   , 32,
+       0xfc0001ff, 0xa00001f0, 0                      , 0,
+       CP1_                },        /* DIV.fmt1 */
+    { pool                , MSUBF_fmt           , 2   , 32,
+       0xfc0001ff, 0xa00001f8, 0                      , 0,
+       CP1_                },        /* MSUBF.fmt */
+};
+
+
+NMD::Pool NMD::MIN_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa0000003, &NMD::MIN_S            , 0,
+       CP1_                },        /* MIN.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa0000203, &NMD::MIN_D            , 0,
+       CP1_                },        /* MIN.D */
+};
+
+
+NMD::Pool NMD::MAX_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa000000b, &NMD::MAX_S            , 0,
+       CP1_                },        /* MAX.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa000020b, &NMD::MAX_D            , 0,
+       CP1_                },        /* MAX.D */
+};
+
+
+NMD::Pool NMD::MINA_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa0000023, &NMD::MINA_S           , 0,
+       CP1_                },        /* MINA.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa0000223, &NMD::MINA_D           , 0,
+       CP1_                },        /* MINA.D */
+};
+
+
+NMD::Pool NMD::MAXA_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa000002b, &NMD::MAXA_S           , 0,
+       CP1_                },        /* MAXA.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00023f, 0xa000022b, &NMD::MAXA_D           , 0,
+       CP1_                },        /* MAXA.D */
+};
+
+
+NMD::Pool NMD::CVT_L_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000013b, &NMD::CVT_L_S          , 0,
+       CP1_                },        /* CVT.L.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000413b, &NMD::CVT_L_D          , 0,
+       CP1_                },        /* CVT.L.D */
+};
+
+
+NMD::Pool NMD::RSQRT_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000023b, &NMD::RSQRT_S          , 0,
+       CP1_                },        /* RSQRT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000423b, &NMD::RSQRT_D          , 0,
+       CP1_                },        /* RSQRT.D */
+};
+
+
+NMD::Pool NMD::FLOOR_L_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000033b, &NMD::FLOOR_L_S        , 0,
+       CP1_                },        /* FLOOR.L.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000433b, &NMD::FLOOR_L_D        , 0,
+       CP1_                },        /* FLOOR.L.D */
+};
+
+
+NMD::Pool NMD::CVT_W_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000093b, &NMD::CVT_W_S          , 0,
+       CP1_                },        /* CVT.W.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000493b, &NMD::CVT_W_D          , 0,
+       CP1_                },        /* CVT.W.D */
+};
+
+
+NMD::Pool NMD::SQRT_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0000a3b, &NMD::SQRT_S           , 0,
+       CP1_                },        /* SQRT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0004a3b, &NMD::SQRT_D           , 0,
+       CP1_                },        /* SQRT.D */
+};
+
+
+NMD::Pool NMD::FLOOR_W_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0000b3b, &NMD::FLOOR_W_S        , 0,
+       CP1_                },        /* FLOOR.W.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0004b3b, &NMD::FLOOR_W_D        , 0,
+       CP1_                },        /* FLOOR.W.D */
+};
+
+
+NMD::Pool NMD::RECIP_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000123b, &NMD::RECIP_S          , 0,
+       CP1_                },        /* RECIP.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000523b, &NMD::RECIP_D          , 0,
+       CP1_                },        /* RECIP.D */
+};
+
+
+NMD::Pool NMD::CEIL_L_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000133b, &NMD::CEIL_L_S         , 0,
+       CP1_                },        /* CEIL.L.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000533b, &NMD::CEIL_L_D         , 0,
+       CP1_                },        /* CEIL.L.D */
+};
+
+
+NMD::Pool NMD::CEIL_W_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0001b3b, &NMD::CEIL_W_S         , 0,
+       CP1_                },        /* CEIL.W.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0005b3b, &NMD::CEIL_W_D         , 0,
+       CP1_                },        /* CEIL.W.D */
+};
+
+
+NMD::Pool NMD::TRUNC_L_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000233b, &NMD::TRUNC_L_S        , 0,
+       CP1_                },        /* TRUNC.L.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000633b, &NMD::TRUNC_L_D        , 0,
+       CP1_                },        /* TRUNC.L.D */
+};
+
+
+NMD::Pool NMD::TRUNC_W_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0002b3b, &NMD::TRUNC_W_S        , 0,
+       CP1_                },        /* TRUNC.W.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0006b3b, &NMD::TRUNC_W_D        , 0,
+       CP1_                },        /* TRUNC.W.D */
+};
+
+
+NMD::Pool NMD::ROUND_L_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000333b, &NMD::ROUND_L_S        , 0,
+       CP1_                },        /* ROUND.L.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000733b, &NMD::ROUND_L_D        , 0,
+       CP1_                },        /* ROUND.L.D */
+};
+
+
+NMD::Pool NMD::ROUND_W_fmt[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0003b3b, &NMD::ROUND_W_S        , 0,
+       CP1_                },        /* ROUND.W.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0007b3b, &NMD::ROUND_W_D        , 0,
+       CP1_                },        /* ROUND.W.D */
+};
+
+
+NMD::Pool NMD::POOL32Fxf_0[64] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000003b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(0) */
+    { pool                , CVT_L_fmt           , 2   , 32,
+       0xfc003fff, 0xa000013b, 0                      , 0,
+       CP1_                },        /* CVT.L.fmt */
+    { pool                , RSQRT_fmt           , 2   , 32,
+       0xfc003fff, 0xa000023b, 0                      , 0,
+       CP1_                },        /* RSQRT.fmt */
+    { pool                , FLOOR_L_fmt         , 2   , 32,
+       0xfc003fff, 0xa000033b, 0                      , 0,
+       CP1_                },        /* FLOOR.L.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000043b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000053b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000063b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000073b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000083b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(8) */
+    { pool                , CVT_W_fmt           , 2   , 32,
+       0xfc003fff, 0xa000093b, 0                      , 0,
+       CP1_                },        /* CVT.W.fmt */
+    { pool                , SQRT_fmt            , 2   , 32,
+       0xfc003fff, 0xa0000a3b, 0                      , 0,
+       CP1_                },        /* SQRT.fmt */
+    { pool                , FLOOR_W_fmt         , 2   , 32,
+       0xfc003fff, 0xa0000b3b, 0                      , 0,
+       CP1_                },        /* FLOOR.W.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0000c3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0000d3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0000e3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0000f3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(15) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000103b, &NMD::CFC1             , 0,
+       CP1_                },        /* CFC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000113b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(17) */
+    { pool                , RECIP_fmt           , 2   , 32,
+       0xfc003fff, 0xa000123b, 0                      , 0,
+       CP1_                },        /* RECIP.fmt */
+    { pool                , CEIL_L_fmt          , 2   , 32,
+       0xfc003fff, 0xa000133b, 0                      , 0,
+       CP1_                },        /* CEIL.L.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000143b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000153b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000163b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000173b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(23) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000183b, &NMD::CTC1             , 0,
+       CP1_                },        /* CTC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000193b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0001a3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(26) */
+    { pool                , CEIL_W_fmt          , 2   , 32,
+       0xfc003fff, 0xa0001b3b, 0                      , 0,
+       CP1_                },        /* CEIL.W.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0001c3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0001d3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0001e3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0001f3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(31) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000203b, &NMD::MFC1             , 0,
+       CP1_                },        /* MFC1 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000213b, &NMD::CVT_S_PL         , 0,
+       CP1_                },        /* CVT.S.PL */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000223b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(34) */
+    { pool                , TRUNC_L_fmt         , 2   , 32,
+       0xfc003fff, 0xa000233b, 0                      , 0,
+       CP1_                },        /* TRUNC.L.fmt */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000243b, &NMD::DMFC1            , 0,
+       CP1_ | MIPS64_      },        /* DMFC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000253b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(37) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000263b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(38) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000273b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(39) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000283b, &NMD::MTC1             , 0,
+       CP1_                },        /* MTC1 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000293b, &NMD::CVT_S_PU         , 0,
+       CP1_                },        /* CVT.S.PU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0002a3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(42) */
+    { pool                , TRUNC_W_fmt         , 2   , 32,
+       0xfc003fff, 0xa0002b3b, 0                      , 0,
+       CP1_                },        /* TRUNC.W.fmt */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa0002c3b, &NMD::DMTC1            , 0,
+       CP1_ | MIPS64_      },        /* DMTC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0002d3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(45) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0002e3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(46) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0002f3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(47) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000303b, &NMD::MFHC1            , 0,
+       CP1_                },        /* MFHC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000313b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(49) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000323b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(50) */
+    { pool                , ROUND_L_fmt         , 2   , 32,
+       0xfc003fff, 0xa000333b, 0                      , 0,
+       CP1_                },        /* ROUND.L.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000343b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000353b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(53) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000363b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(54) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000373b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(55) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc003fff, 0xa000383b, &NMD::MTHC1            , 0,
+       CP1_                },        /* MTHC1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa000393b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(57) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0003a3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(58) */
+    { pool                , ROUND_W_fmt         , 2   , 32,
+       0xfc003fff, 0xa0003b3b, 0                      , 0,
+       CP1_                },        /* ROUND.W.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0003c3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0003d3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(61) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0003e3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(62) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc003fff, 0xa0003f3b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0~*(63) */
+};
+
+
+NMD::Pool NMD::MOV_fmt[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000007b, &NMD::MOV_S            , 0,
+       CP1_                },        /* MOV.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000207b, &NMD::MOV_D            , 0,
+       CP1_                },        /* MOV.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa000407b, 0                      , 0,
+       CP1_                },        /* MOV.fmt~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa000607b, 0                      , 0,
+       CP1_                },        /* MOV.fmt~*(3) */
+};
+
+
+NMD::Pool NMD::ABS_fmt[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000037b, &NMD::ABS_S            , 0,
+       CP1_                },        /* ABS.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000237b, &NMD::ABS_D            , 0,
+       CP1_                },        /* ABS.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa000437b, 0                      , 0,
+       CP1_                },        /* ABS.fmt~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa000637b, 0                      , 0,
+       CP1_                },        /* ABS.fmt~*(3) */
+};
+
+
+NMD::Pool NMD::NEG_fmt[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0000b7b, &NMD::NEG_S            , 0,
+       CP1_                },        /* NEG.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0002b7b, &NMD::NEG_D            , 0,
+       CP1_                },        /* NEG.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa0004b7b, 0                      , 0,
+       CP1_                },        /* NEG.fmt~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa0006b7b, 0                      , 0,
+       CP1_                },        /* NEG.fmt~*(3) */
+};
+
+
+NMD::Pool NMD::CVT_D_fmt[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000137b, &NMD::CVT_D_S          , 0,
+       CP1_                },        /* CVT.D.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000337b, &NMD::CVT_D_W          , 0,
+       CP1_                },        /* CVT.D.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa000537b, &NMD::CVT_D_L          , 0,
+       CP1_                },        /* CVT.D.L */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa000737b, 0                      , 0,
+       CP1_                },        /* CVT.D.fmt~*(3) */
+};
+
+
+NMD::Pool NMD::CVT_S_fmt[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0001b7b, &NMD::CVT_S_D          , 0,
+       CP1_                },        /* CVT.S.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0003b7b, &NMD::CVT_S_W          , 0,
+       CP1_                },        /* CVT.S.W */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007fff, 0xa0005b7b, &NMD::CVT_S_L          , 0,
+       CP1_                },        /* CVT.S.L */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007fff, 0xa0007b7b, 0                      , 0,
+       CP1_                },        /* CVT.S.fmt~*(3) */
+};
+
+
+NMD::Pool NMD::POOL32Fxf_1[32] = {
+    { pool                , MOV_fmt             , 4   , 32,
+       0xfc001fff, 0xa000007b, 0                      , 0,
+       CP1_                },        /* MOV.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000017b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000027b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(2) */
+    { pool                , ABS_fmt             , 4   , 32,
+       0xfc001fff, 0xa000037b, 0                      , 0,
+       CP1_                },        /* ABS.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000047b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000057b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000067b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000077b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000087b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000097b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0000a7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(10) */
+    { pool                , NEG_fmt             , 4   , 32,
+       0xfc001fff, 0xa0000b7b, 0                      , 0,
+       CP1_                },        /* NEG.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0000c7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0000d7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0000e7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0000f7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000107b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000117b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000127b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(18) */
+    { pool                , CVT_D_fmt           , 4   , 32,
+       0xfc001fff, 0xa000137b, 0                      , 0,
+       CP1_                },        /* CVT.D.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000147b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000157b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000167b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000177b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000187b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa000197b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0001a7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(26) */
+    { pool                , CVT_S_fmt           , 4   , 32,
+       0xfc001fff, 0xa0001b7b, 0                      , 0,
+       CP1_                },        /* CVT.S.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0001c7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0001d7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0001e7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc001fff, 0xa0001f7b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1~*(31) */
+};
+
+
+NMD::Pool NMD::POOL32Fxf[4] = {
+    { pool                , POOL32Fxf_0         , 64  , 32,
+       0xfc0000ff, 0xa000003b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_0 */
+    { pool                , POOL32Fxf_1         , 32  , 32,
+       0xfc0000ff, 0xa000007b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf_1 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0000ff, 0xa00000bb, 0                      , 0,
+       CP1_                },        /* POOL32Fxf~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0000ff, 0xa00000fb, 0                      , 0,
+       CP1_                },        /* POOL32Fxf~*(3) */
+};
+
+
+NMD::Pool NMD::POOL32F_3[8] = {
+    { pool                , MIN_fmt             , 2   , 32,
+       0xfc00003f, 0xa0000003, 0                      , 0,
+       CP1_                },        /* MIN.fmt */
+    { pool                , MAX_fmt             , 2   , 32,
+       0xfc00003f, 0xa000000b, 0                      , 0,
+       CP1_                },        /* MAX.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa0000013, 0                      , 0,
+       CP1_                },        /* POOL32F_3~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa000001b, 0                      , 0,
+       CP1_                },        /* POOL32F_3~*(3) */
+    { pool                , MINA_fmt            , 2   , 32,
+       0xfc00003f, 0xa0000023, 0                      , 0,
+       CP1_                },        /* MINA.fmt */
+    { pool                , MAXA_fmt            , 2   , 32,
+       0xfc00003f, 0xa000002b, 0                      , 0,
+       CP1_                },        /* MAXA.fmt */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa0000033, 0                      , 0,
+       CP1_                },        /* POOL32F_3~*(6) */
+    { pool                , POOL32Fxf           , 4   , 32,
+       0xfc00003f, 0xa000003b, 0                      , 0,
+       CP1_                },        /* POOL32Fxf */
+};
+
+
+NMD::Pool NMD::CMP_condn_S[32] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000005, &NMD::CMP_AF_S         , 0,
+       CP1_                },        /* CMP.AF.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000045, &NMD::CMP_UN_S         , 0,
+       CP1_                },        /* CMP.UN.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000085, &NMD::CMP_EQ_S         , 0,
+       CP1_                },        /* CMP.EQ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00000c5, &NMD::CMP_UEQ_S        , 0,
+       CP1_                },        /* CMP.UEQ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000105, &NMD::CMP_LT_S         , 0,
+       CP1_                },        /* CMP.LT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000145, &NMD::CMP_ULT_S        , 0,
+       CP1_                },        /* CMP.ULT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000185, &NMD::CMP_LE_S         , 0,
+       CP1_                },        /* CMP.LE.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00001c5, &NMD::CMP_ULE_S        , 0,
+       CP1_                },        /* CMP.ULE.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000205, &NMD::CMP_SAF_S        , 0,
+       CP1_                },        /* CMP.SAF.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000245, &NMD::CMP_SUN_S        , 0,
+       CP1_                },        /* CMP.SUN.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000285, &NMD::CMP_SEQ_S        , 0,
+       CP1_                },        /* CMP.SEQ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00002c5, &NMD::CMP_SUEQ_S       , 0,
+       CP1_                },        /* CMP.SUEQ.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000305, &NMD::CMP_SLT_S        , 0,
+       CP1_                },        /* CMP.SLT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000345, &NMD::CMP_SULT_S       , 0,
+       CP1_                },        /* CMP.SULT.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000385, &NMD::CMP_SLE_S        , 0,
+       CP1_                },        /* CMP.SLE.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00003c5, &NMD::CMP_SULE_S       , 0,
+       CP1_                },        /* CMP.SULE.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000405, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(16) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000445, &NMD::CMP_OR_S         , 0,
+       CP1_                },        /* CMP.OR.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000485, &NMD::CMP_UNE_S        , 0,
+       CP1_                },        /* CMP.UNE.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00004c5, &NMD::CMP_NE_S         , 0,
+       CP1_                },        /* CMP.NE.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000505, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000545, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000585, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00005c5, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000605, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(24) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000645, &NMD::CMP_SOR_S        , 0,
+       CP1_                },        /* CMP.SOR.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000685, &NMD::CMP_SUNE_S       , 0,
+       CP1_                },        /* CMP.SUNE.S */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00006c5, &NMD::CMP_SNE_S        , 0,
+       CP1_                },        /* CMP.SNE.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000705, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000745, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000785, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00007c5, 0                      , 0,
+       CP1_                },        /* CMP.condn.S~*(31) */
+};
+
+
+NMD::Pool NMD::CMP_condn_D[32] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000015, &NMD::CMP_AF_D         , 0,
+       CP1_                },        /* CMP.AF.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000055, &NMD::CMP_UN_D         , 0,
+       CP1_                },        /* CMP.UN.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000095, &NMD::CMP_EQ_D         , 0,
+       CP1_                },        /* CMP.EQ.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00000d5, &NMD::CMP_UEQ_D        , 0,
+       CP1_                },        /* CMP.UEQ.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000115, &NMD::CMP_LT_D         , 0,
+       CP1_                },        /* CMP.LT.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000155, &NMD::CMP_ULT_D        , 0,
+       CP1_                },        /* CMP.ULT.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000195, &NMD::CMP_LE_D         , 0,
+       CP1_                },        /* CMP.LE.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00001d5, &NMD::CMP_ULE_D        , 0,
+       CP1_                },        /* CMP.ULE.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000215, &NMD::CMP_SAF_D        , 0,
+       CP1_                },        /* CMP.SAF.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000255, &NMD::CMP_SUN_D        , 0,
+       CP1_                },        /* CMP.SUN.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000295, &NMD::CMP_SEQ_D        , 0,
+       CP1_                },        /* CMP.SEQ.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00002d5, &NMD::CMP_SUEQ_D       , 0,
+       CP1_                },        /* CMP.SUEQ.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000315, &NMD::CMP_SLT_D        , 0,
+       CP1_                },        /* CMP.SLT.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000355, &NMD::CMP_SULT_D       , 0,
+       CP1_                },        /* CMP.SULT.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000395, &NMD::CMP_SLE_D        , 0,
+       CP1_                },        /* CMP.SLE.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00003d5, &NMD::CMP_SULE_D       , 0,
+       CP1_                },        /* CMP.SULE.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000415, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(16) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000455, &NMD::CMP_OR_D         , 0,
+       CP1_                },        /* CMP.OR.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000495, &NMD::CMP_UNE_D        , 0,
+       CP1_                },        /* CMP.UNE.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00004d5, &NMD::CMP_NE_D         , 0,
+       CP1_                },        /* CMP.NE.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000515, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000555, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000595, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00005d5, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000615, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(24) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000655, &NMD::CMP_SOR_D        , 0,
+       CP1_                },        /* CMP.SOR.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000695, &NMD::CMP_SUNE_D       , 0,
+       CP1_                },        /* CMP.SUNE.D */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00006d5, &NMD::CMP_SNE_D        , 0,
+       CP1_                },        /* CMP.SNE.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000715, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000755, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa0000795, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0007ff, 0xa00007d5, 0                      , 0,
+       CP1_                },        /* CMP.condn.D~*(31) */
+};
+
+
+NMD::Pool NMD::POOL32F_5[8] = {
+    { pool                , CMP_condn_S         , 32  , 32,
+       0xfc00003f, 0xa0000005, 0                      , 0,
+       CP1_                },        /* CMP.condn.S */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa000000d, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(1) */
+    { pool                , CMP_condn_D         , 32  , 32,
+       0xfc00003f, 0xa0000015, 0                      , 0,
+       CP1_                },        /* CMP.condn.D */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa000001d, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa0000025, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa000002d, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa0000035, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xa000003d, 0                      , 0,
+       CP1_                },        /* POOL32F_5~*(7) */
+};
+
+
+NMD::Pool NMD::POOL32F[8] = {
+    { pool                , POOL32F_0           , 64  , 32,
+       0xfc000007, 0xa0000000, 0                      , 0,
+       CP1_                },        /* POOL32F_0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xa0000001, 0                      , 0,
+       CP1_                },        /* POOL32F~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xa0000002, 0                      , 0,
+       CP1_                },        /* POOL32F~*(2) */
+    { pool                , POOL32F_3           , 8   , 32,
+       0xfc000007, 0xa0000003, 0                      , 0,
+       CP1_                },        /* POOL32F_3 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xa0000004, 0                      , 0,
+       CP1_                },        /* POOL32F~*(4) */
+    { pool                , POOL32F_5           , 8   , 32,
+       0xfc000007, 0xa0000005, 0                      , 0,
+       CP1_                },        /* POOL32F_5 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xa0000006, 0                      , 0,
+       CP1_                },        /* POOL32F~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xa0000007, 0                      , 0,
+       CP1_                },        /* POOL32F~*(7) */
+};
+
+
+NMD::Pool NMD::POOL32S_0[64] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000000, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(0) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000008, &NMD::DLSA             , 0,
+       MIPS64_             },        /* DLSA */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000010, &NMD::DSLLV            , 0,
+       MIPS64_             },        /* DSLLV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000018, &NMD::DMUL             , 0,
+       MIPS64_             },        /* DMUL */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000020, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000028, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000030, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000038, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000040, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000048, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(9) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000050, &NMD::DSRLV            , 0,
+       MIPS64_             },        /* DSRLV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000058, &NMD::DMUH             , 0,
+       MIPS64_             },        /* DMUH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000060, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000068, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000070, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000078, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000080, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000088, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(17) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000090, &NMD::DSRAV            , 0,
+       MIPS64_             },        /* DSRAV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000098, &NMD::DMULU            , 0,
+       MIPS64_             },        /* DMULU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000a0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000a8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000b0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000b8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000c0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000c8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(25) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000d0, &NMD::DROTRV           , 0,
+       MIPS64_             },        /* DROTRV */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000d8, &NMD::DMUHU            , 0,
+       MIPS64_             },        /* DMUHU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000e0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000e8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000f0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000f8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(31) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000100, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(32) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000108, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(33) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000110, &NMD::DADD             , 0,
+       MIPS64_             },        /* DADD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000118, &NMD::DDIV             , 0,
+       MIPS64_             },        /* DDIV */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000120, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(36) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000128, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(37) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000130, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(38) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000138, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(39) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000140, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(40) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000148, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(41) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000150, &NMD::DADDU            , 0,
+       MIPS64_             },        /* DADDU */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000158, &NMD::DMOD             , 0,
+       MIPS64_             },        /* DMOD */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000160, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(44) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000168, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(45) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000170, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(46) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000178, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(47) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000180, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(48) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000188, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(49) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000190, &NMD::DSUB             , 0,
+       MIPS64_             },        /* DSUB */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc0000198, &NMD::DDIVU            , 0,
+       MIPS64_             },        /* DDIVU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001a0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001a8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(53) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001b0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(54) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001b8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(55) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001c0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(56) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001c8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(57) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001d0, &NMD::DSUBU            , 0,
+       MIPS64_             },        /* DSUBU */
+    { instruction         , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001d8, &NMD::DMODU            , 0,
+       MIPS64_             },        /* DMODU */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001e0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001e8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(61) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001f0, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(62) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001f8, 0                      , 0,
+       0x0                 },        /* POOL32S_0~*(63) */
+};
+
+
+NMD::Pool NMD::POOL32Sxf_4[128] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000013c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000033c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000053c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000073c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000093c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0000b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0000d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0000f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000113c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000133c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000153c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000173c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000193c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0001b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0001d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0001f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000213c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000233c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000253c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000273c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000293c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0002b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0002d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0002f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000313c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000333c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000353c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000373c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000393c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0003b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0003d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0003f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(31) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000413c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(32) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000433c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(33) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000453c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(34) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000473c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(35) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000493c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(36) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0004b3c, &NMD::DCLO             , 0,
+       MIPS64_             },        /* DCLO */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0004d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(38) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0004f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(39) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000513c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(40) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000533c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(41) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000553c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(42) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000573c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(43) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000593c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(44) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0005b3c, &NMD::DCLZ             , 0,
+       MIPS64_             },        /* DCLZ */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0005d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(46) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0005f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(47) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000613c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(48) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000633c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(49) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000653c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(50) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000673c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(51) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000693c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(52) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0006b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(53) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0006d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(54) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0006f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(55) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000713c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(56) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000733c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(57) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000753c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(58) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000773c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(59) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000793c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(60) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0007b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(61) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0007d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(62) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0007f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(63) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000813c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(64) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000833c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(65) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000853c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(66) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000873c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(67) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000893c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(68) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0008b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(69) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0008d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(70) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0008f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(71) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000913c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(72) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000933c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(73) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000953c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(74) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000973c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(75) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000993c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(76) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0009b3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(77) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0009d3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(78) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc0009f3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(79) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000a13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(80) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000a33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(81) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000a53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(82) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000a73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(83) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000a93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(84) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000ab3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(85) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000ad3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(86) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000af3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(87) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000b13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(88) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000b33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(89) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000b53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(90) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000b73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(91) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000b93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(92) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000bb3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(93) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000bd3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(94) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000bf3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(95) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000c13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(96) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000c33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(97) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000c53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(98) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000c73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(99) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000c93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(100) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000cb3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(101) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000cd3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(102) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000cf3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(103) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000d13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(104) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000d33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(105) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000d53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(106) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000d73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(107) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000d93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(108) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000db3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(109) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000dd3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(110) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000df3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(111) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000e13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(112) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000e33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(113) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000e53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(114) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000e73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(115) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000e93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(116) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000eb3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(117) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000ed3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(118) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000ef3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(119) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000f13c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(120) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000f33c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(121) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000f53c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(122) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000f73c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(123) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000f93c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(124) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000fb3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(125) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000fd3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(126) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00ffff, 0xc000ff3c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4~*(127) */
+};
+
+
+NMD::Pool NMD::POOL32Sxf[8] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc000003c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc000007c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000bc, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00000fc, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(3) */
+    { pool                , POOL32Sxf_4         , 128 , 32,
+       0xfc0001ff, 0xc000013c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf_4 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc000017c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001bc, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc0001ff, 0xc00001fc, 0                      , 0,
+       0x0                 },        /* POOL32Sxf~*(7) */
+};
+
+
+NMD::Pool NMD::POOL32S_4[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00003f, 0xc0000004, &NMD::EXTD             , 0,
+       MIPS64_             },        /* EXTD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00003f, 0xc000000c, &NMD::EXTD32           , 0,
+       MIPS64_             },        /* EXTD32 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xc0000014, 0                      , 0,
+       0x0                 },        /* POOL32S_4~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xc000001c, 0                      , 0,
+       0x0                 },        /* POOL32S_4~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xc0000024, 0                      , 0,
+       0x0                 },        /* POOL32S_4~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xc000002c, 0                      , 0,
+       0x0                 },        /* POOL32S_4~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00003f, 0xc0000034, 0                      , 0,
+       0x0                 },        /* POOL32S_4~*(6) */
+    { pool                , POOL32Sxf           , 8   , 32,
+       0xfc00003f, 0xc000003c, 0                      , 0,
+       0x0                 },        /* POOL32Sxf */
+};
+
+
+NMD::Pool NMD::POOL32S[8] = {
+    { pool                , POOL32S_0           , 64  , 32,
+       0xfc000007, 0xc0000000, 0                      , 0,
+       0x0                 },        /* POOL32S_0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000001, 0                      , 0,
+       0x0                 },        /* POOL32S~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000002, 0                      , 0,
+       0x0                 },        /* POOL32S~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000003, 0                      , 0,
+       0x0                 },        /* POOL32S~*(3) */
+    { pool                , POOL32S_4           , 8   , 32,
+       0xfc000007, 0xc0000004, 0                      , 0,
+       0x0                 },        /* POOL32S_4 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000005, 0                      , 0,
+       0x0                 },        /* POOL32S~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000006, 0                      , 0,
+       0x0                 },        /* POOL32S~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000007, 0xc0000007, 0                      , 0,
+       0x0                 },        /* POOL32S~*(7) */
+};
+
+
+NMD::Pool NMD::P_LUI[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000002, 0xe0000000, &NMD::LUI              , 0,
+       0x0                 },        /* LUI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000002, 0xe0000002, &NMD::ALUIPC           , 0,
+       0x0                 },        /* ALUIPC */
+};
+
+
+NMD::Pool NMD::P_GP_LH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0001, 0x44100000, &NMD::LH_GP_           , 0,
+       0x0                 },        /* LH[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0001, 0x44100001, &NMD::LHU_GP_          , 0,
+       0x0                 },        /* LHU[GP] */
+};
+
+
+NMD::Pool NMD::P_GP_SH[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0001, 0x44140000, &NMD::SH_GP_           , 0,
+       0x0                 },        /* SH[GP] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1c0001, 0x44140001, 0                      , 0,
+       0x0                 },        /* P.GP.SH~*(1) */
+};
+
+
+NMD::Pool NMD::P_GP_CP1[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0003, 0x44180000, &NMD::LWC1_GP_         , 0,
+       CP1_                },        /* LWC1[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0003, 0x44180001, &NMD::SWC1_GP_         , 0,
+       CP1_                },        /* SWC1[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0003, 0x44180002, &NMD::LDC1_GP_         , 0,
+       CP1_                },        /* LDC1[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0003, 0x44180003, &NMD::SDC1_GP_         , 0,
+       CP1_                },        /* SDC1[GP] */
+};
+
+
+NMD::Pool NMD::P_GP_M64[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0003, 0x441c0000, &NMD::LWU_GP_          , 0,
+       MIPS64_             },        /* LWU[GP] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1c0003, 0x441c0001, 0                      , 0,
+       0x0                 },        /* P.GP.M64~*(1) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1c0003, 0x441c0002, 0                      , 0,
+       0x0                 },        /* P.GP.M64~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1c0003, 0x441c0003, 0                      , 0,
+       0x0                 },        /* P.GP.M64~*(3) */
+};
+
+
+NMD::Pool NMD::P_GP_BH[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0000, 0x44000000, &NMD::LB_GP_           , 0,
+       0x0                 },        /* LB[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0000, 0x44040000, &NMD::SB_GP_           , 0,
+       0x0                 },        /* SB[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0000, 0x44080000, &NMD::LBU_GP_          , 0,
+       0x0                 },        /* LBU[GP] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc1c0000, 0x440c0000, &NMD::ADDIU_GP_B_      , 0,
+       0x0                 },        /* ADDIU[GP.B] */
+    { pool                , P_GP_LH             , 2   , 32,
+       0xfc1c0000, 0x44100000, 0                      , 0,
+       0x0                 },        /* P.GP.LH */
+    { pool                , P_GP_SH             , 2   , 32,
+       0xfc1c0000, 0x44140000, 0                      , 0,
+       0x0                 },        /* P.GP.SH */
+    { pool                , P_GP_CP1            , 4   , 32,
+       0xfc1c0000, 0x44180000, 0                      , 0,
+       0x0                 },        /* P.GP.CP1 */
+    { pool                , P_GP_M64            , 4   , 32,
+       0xfc1c0000, 0x441c0000, 0                      , 0,
+       0x0                 },        /* P.GP.M64 */
+};
+
+
+NMD::Pool NMD::P_LS_U12[16] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84000000, &NMD::LB_U12_          , 0,
+       0x0                 },        /* LB[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84001000, &NMD::SB_U12_          , 0,
+       0x0                 },        /* SB[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84002000, &NMD::LBU_U12_         , 0,
+       0x0                 },        /* LBU[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84003000, &NMD::PREF_U12_        , 0,
+       0x0                 },        /* PREF[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84004000, &NMD::LH_U12_          , 0,
+       0x0                 },        /* LH[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84005000, &NMD::SH_U12_          , 0,
+       0x0                 },        /* SH[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84006000, &NMD::LHU_U12_         , 0,
+       0x0                 },        /* LHU[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84007000, &NMD::LWU_U12_         , 0,
+       MIPS64_             },        /* LWU[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84008000, &NMD::LW_U12_          , 0,
+       0x0                 },        /* LW[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x84009000, &NMD::SW_U12_          , 0,
+       0x0                 },        /* SW[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400a000, &NMD::LWC1_U12_        , 0,
+       CP1_                },        /* LWC1[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400b000, &NMD::SWC1_U12_        , 0,
+       CP1_                },        /* SWC1[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400c000, &NMD::LD_U12_          , 0,
+       MIPS64_             },        /* LD[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400d000, &NMD::SD_U12_          , 0,
+       MIPS64_             },        /* SD[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400e000, &NMD::LDC1_U12_        , 0,
+       CP1_                },        /* LDC1[U12] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc00f000, 0x8400f000, &NMD::SDC1_U12_        , 0,
+       CP1_                },        /* SDC1[U12] */
+};
+
+
+NMD::Pool NMD::P_PREF_S9_[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xffe07f00, 0xa7e01800, &NMD::SYNCI            , 0,
+       0x0                 },        /* SYNCI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4001800, &NMD::PREF_S9_         , &NMD::PREF_S9__cond    ,
+       0x0                 },        /* PREF[S9] */
+};
+
+
+NMD::Pool NMD::P_LS_S0[16] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000000, &NMD::LB_S9_           , 0,
+       0x0                 },        /* LB[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000800, &NMD::SB_S9_           , 0,
+       0x0                 },        /* SB[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4001000, &NMD::LBU_S9_          , 0,
+       0x0                 },        /* LBU[S9] */
+    { pool                , P_PREF_S9_          , 2   , 32,
+       0xfc007f00, 0xa4001800, 0                      , 0,
+       0x0                 },        /* P.PREF[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002000, &NMD::LH_S9_           , 0,
+       0x0                 },        /* LH[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002800, &NMD::SH_S9_           , 0,
+       0x0                 },        /* SH[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003000, &NMD::LHU_S9_          , 0,
+       0x0                 },        /* LHU[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003800, &NMD::LWU_S9_          , 0,
+       MIPS64_             },        /* LWU[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004000, &NMD::LW_S9_           , 0,
+       0x0                 },        /* LW[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004800, &NMD::SW_S9_           , 0,
+       0x0                 },        /* SW[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4005000, &NMD::LWC1_S9_         , 0,
+       CP1_                },        /* LWC1[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4005800, &NMD::SWC1_S9_         , 0,
+       CP1_                },        /* SWC1[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006000, &NMD::LD_S9_           , 0,
+       MIPS64_             },        /* LD[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006800, &NMD::SD_S9_           , 0,
+       MIPS64_             },        /* SD[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4007000, &NMD::LDC1_S9_         , 0,
+       CP1_                },        /* LDC1[S9] */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4007800, &NMD::SDC1_S9_         , 0,
+       CP1_                },        /* SDC1[S9] */
+};
+
+
+NMD::Pool NMD::ASET_ACLR[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfe007f00, 0xa4001100, &NMD::ASET             , 0,
+       MCU_                },        /* ASET */
+    { instruction         , 0                   , 0   , 32,
+       0xfe007f00, 0xa6001100, &NMD::ACLR             , 0,
+       MCU_                },        /* ACLR */
+};
+
+
+NMD::Pool NMD::P_LL[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005100, &NMD::LL               , 0,
+       0x0                 },        /* LL */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005101, &NMD::LLWP             , 0,
+       XNP_                },        /* LLWP */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005102, 0                      , 0,
+       0x0                 },        /* P.LL~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005103, 0                      , 0,
+       0x0                 },        /* P.LL~*(3) */
+};
+
+
+NMD::Pool NMD::P_SC[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005900, &NMD::SC               , 0,
+       0x0                 },        /* SC */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005901, &NMD::SCWP             , 0,
+       XNP_                },        /* SCWP */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005902, 0                      , 0,
+       0x0                 },        /* P.SC~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005903, 0                      , 0,
+       0x0                 },        /* P.SC~*(3) */
+};
+
+
+NMD::Pool NMD::P_LLD[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007100, &NMD::LLD              , 0,
+       MIPS64_             },        /* LLD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007101, &NMD::LLDP             , 0,
+       MIPS64_             },        /* LLDP */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007102, 0                      , 0,
+       0x0                 },        /* P.LLD~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007103, 0                      , 0,
+       0x0                 },        /* P.LLD~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007104, 0                      , 0,
+       0x0                 },        /* P.LLD~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007105, 0                      , 0,
+       0x0                 },        /* P.LLD~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007106, 0                      , 0,
+       0x0                 },        /* P.LLD~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007107, 0                      , 0,
+       0x0                 },        /* P.LLD~*(7) */
+};
+
+
+NMD::Pool NMD::P_SCD[8] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007900, &NMD::SCD              , 0,
+       MIPS64_             },        /* SCD */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007901, &NMD::SCDP             , 0,
+       MIPS64_             },        /* SCDP */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007902, 0                      , 0,
+       0x0                 },        /* P.SCD~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007903, 0                      , 0,
+       0x0                 },        /* P.SCD~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007904, 0                      , 0,
+       0x0                 },        /* P.SCD~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007905, 0                      , 0,
+       0x0                 },        /* P.SCD~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007906, 0                      , 0,
+       0x0                 },        /* P.SCD~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f07, 0xa4007907, 0                      , 0,
+       0x0                 },        /* P.SCD~*(7) */
+};
+
+
+NMD::Pool NMD::P_LS_S1[16] = {
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000100, 0                      , 0,
+       0x0                 },        /* P.LS.S1~*(0) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000900, 0                      , 0,
+       0x0                 },        /* P.LS.S1~*(1) */
+    { pool                , ASET_ACLR           , 2   , 32,
+       0xfc007f00, 0xa4001100, 0                      , 0,
+       0x0                 },        /* ASET_ACLR */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4001900, 0                      , 0,
+       0x0                 },        /* P.LS.S1~*(3) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002100, &NMD::UALH             , 0,
+       XMMS_               },        /* UALH */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002900, &NMD::UASH             , 0,
+       XMMS_               },        /* UASH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003100, 0                      , 0,
+       0x0                 },        /* P.LS.S1~*(6) */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003900, &NMD::CACHE            , 0,
+       CP0_                },        /* CACHE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004100, &NMD::LWC2             , 0,
+       CP2_                },        /* LWC2 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004900, &NMD::SWC2             , 0,
+       CP2_                },        /* SWC2 */
+    { pool                , P_LL                , 4   , 32,
+       0xfc007f00, 0xa4005100, 0                      , 0,
+       0x0                 },        /* P.LL */
+    { pool                , P_SC                , 4   , 32,
+       0xfc007f00, 0xa4005900, 0                      , 0,
+       0x0                 },        /* P.SC */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006100, &NMD::LDC2             , 0,
+       CP2_                },        /* LDC2 */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006900, &NMD::SDC2             , 0,
+       CP2_                },        /* SDC2 */
+    { pool                , P_LLD               , 8   , 32,
+       0xfc007f00, 0xa4007100, 0                      , 0,
+       0x0                 },        /* P.LLD */
+    { pool                , P_SCD               , 8   , 32,
+       0xfc007f00, 0xa4007900, 0                      , 0,
+       0x0                 },        /* P.SCD */
+};
+
+
+NMD::Pool NMD::P_PREFE[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xffe07f00, 0xa7e01a00, &NMD::SYNCIE           , 0,
+       CP0_ | EVA_         },        /* SYNCIE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4001a00, &NMD::PREFE            , &NMD::PREFE_cond       ,
+       CP0_ | EVA_         },        /* PREFE */
+};
+
+
+NMD::Pool NMD::P_LLE[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005200, &NMD::LLE              , 0,
+       CP0_ | EVA_         },        /* LLE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005201, &NMD::LLWPE            , 0,
+       CP0_ | EVA_         },        /* LLWPE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005202, 0                      , 0,
+       0x0                 },        /* P.LLE~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005203, 0                      , 0,
+       0x0                 },        /* P.LLE~*(3) */
+};
+
+
+NMD::Pool NMD::P_SCE[4] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005a00, &NMD::SCE              , 0,
+       CP0_ | EVA_         },        /* SCE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005a01, &NMD::SCWPE            , 0,
+       CP0_ | EVA_         },        /* SCWPE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005a02, 0                      , 0,
+       0x0                 },        /* P.SCE~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f03, 0xa4005a03, 0                      , 0,
+       0x0                 },        /* P.SCE~*(3) */
+};
+
+
+NMD::Pool NMD::P_LS_E0[16] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000200, &NMD::LBE              , 0,
+       CP0_ | EVA_         },        /* LBE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4000a00, &NMD::SBE              , 0,
+       CP0_ | EVA_         },        /* SBE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4001200, &NMD::LBUE             , 0,
+       CP0_ | EVA_         },        /* LBUE */
+    { pool                , P_PREFE             , 2   , 32,
+       0xfc007f00, 0xa4001a00, 0                      , 0,
+       0x0                 },        /* P.PREFE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002200, &NMD::LHE              , 0,
+       CP0_ | EVA_         },        /* LHE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4002a00, &NMD::SHE              , 0,
+       CP0_ | EVA_         },        /* SHE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003200, &NMD::LHUE             , 0,
+       CP0_ | EVA_         },        /* LHUE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4003a00, &NMD::CACHEE           , 0,
+       CP0_ | EVA_         },        /* CACHEE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004200, &NMD::LWE              , 0,
+       CP0_ | EVA_         },        /* LWE */
+    { instruction         , 0                   , 0   , 32,
+       0xfc007f00, 0xa4004a00, &NMD::SWE              , 0,
+       CP0_ | EVA_         },        /* SWE */
+    { pool                , P_LLE               , 4   , 32,
+       0xfc007f00, 0xa4005200, 0                      , 0,
+       0x0                 },        /* P.LLE */
+    { pool                , P_SCE               , 4   , 32,
+       0xfc007f00, 0xa4005a00, 0                      , 0,
+       0x0                 },        /* P.SCE */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006200, 0                      , 0,
+       0x0                 },        /* P.LS.E0~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4006a00, 0                      , 0,
+       0x0                 },        /* P.LS.E0~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4007200, 0                      , 0,
+       0x0                 },        /* P.LS.E0~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc007f00, 0xa4007a00, 0                      , 0,
+       0x0                 },        /* P.LS.E0~*(15) */
+};
+
+
+NMD::Pool NMD::P_LS_WM[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000400, &NMD::LWM              , 0,
+       XMMS_               },        /* LWM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000c00, &NMD::SWM              , 0,
+       XMMS_               },        /* SWM */
+};
+
+
+NMD::Pool NMD::P_LS_UAWM[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000500, &NMD::UALWM            , 0,
+       XMMS_               },        /* UALWM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000d00, &NMD::UASWM            , 0,
+       XMMS_               },        /* UASWM */
+};
+
+
+NMD::Pool NMD::P_LS_DM[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000600, &NMD::LDM              , 0,
+       MIPS64_             },        /* LDM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000e00, &NMD::SDM              , 0,
+       MIPS64_             },        /* SDM */
+};
+
+
+NMD::Pool NMD::P_LS_UADM[2] = {
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000700, &NMD::UALDM            , 0,
+       MIPS64_             },        /* UALDM */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000f00, 0xa4000f00, &NMD::UASDM            , 0,
+       MIPS64_             },        /* UASDM */
+};
+
+
+NMD::Pool NMD::P_LS_S9[8] = {
+    { pool                , P_LS_S0             , 16  , 32,
+       0xfc000700, 0xa4000000, 0                      , 0,
+       0x0                 },        /* P.LS.S0 */
+    { pool                , P_LS_S1             , 16  , 32,
+       0xfc000700, 0xa4000100, 0                      , 0,
+       0x0                 },        /* P.LS.S1 */
+    { pool                , P_LS_E0             , 16  , 32,
+       0xfc000700, 0xa4000200, 0                      , 0,
+       0x0                 },        /* P.LS.E0 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000700, 0xa4000300, 0                      , 0,
+       0x0                 },        /* P.LS.S9~*(3) */
+    { pool                , P_LS_WM             , 2   , 32,
+       0xfc000700, 0xa4000400, 0                      , 0,
+       0x0                 },        /* P.LS.WM */
+    { pool                , P_LS_UAWM           , 2   , 32,
+       0xfc000700, 0xa4000500, 0                      , 0,
+       0x0                 },        /* P.LS.UAWM */
+    { pool                , P_LS_DM             , 2   , 32,
+       0xfc000700, 0xa4000600, 0                      , 0,
+       0x0                 },        /* P.LS.DM */
+    { pool                , P_LS_UADM           , 2   , 32,
+       0xfc000700, 0xa4000700, 0                      , 0,
+       0x0                 },        /* P.LS.UADM */
+};
+
+
+NMD::Pool NMD::P_BAL[2] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfe000000, 0x28000000, &NMD::BC_32_           , 0,
+       0x0                 },        /* BC[32] */
+    { call_instruction    , 0                   , 0   , 32,
+       0xfe000000, 0x2a000000, &NMD::BALC_32_         , 0,
+       0x0                 },        /* BALC[32] */
+};
+
+
+NMD::Pool NMD::P_BALRSC[2] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xffe0f000, 0x48008000, &NMD::BRSC             , 0,
+       0x0                 },        /* BRSC */
+    { call_instruction    , 0                   , 0   , 32,
+       0xfc00f000, 0x48008000, &NMD::BALRSC           , &NMD::BALRSC_cond      ,
+       0x0                 },        /* BALRSC */
+};
+
+
+NMD::Pool NMD::P_J[16] = {
+    { call_instruction    , 0                   , 0   , 32,
+       0xfc00f000, 0x48000000, &NMD::JALRC_32_        , 0,
+       0x0                 },        /* JALRC[32] */
+    { call_instruction    , 0                   , 0   , 32,
+       0xfc00f000, 0x48001000, &NMD::JALRC_HB         , 0,
+       0x0                 },        /* JALRC.HB */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48002000, 0                      , 0,
+       0x0                 },        /* P.J~*(2) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48003000, 0                      , 0,
+       0x0                 },        /* P.J~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48004000, 0                      , 0,
+       0x0                 },        /* P.J~*(4) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48005000, 0                      , 0,
+       0x0                 },        /* P.J~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48006000, 0                      , 0,
+       0x0                 },        /* P.J~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48007000, 0                      , 0,
+       0x0                 },        /* P.J~*(7) */
+    { pool                , P_BALRSC            , 2   , 32,
+       0xfc00f000, 0x48008000, 0                      , 0,
+       0x0                 },        /* P.BALRSC */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x48009000, 0                      , 0,
+       0x0                 },        /* P.J~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800a000, 0                      , 0,
+       0x0                 },        /* P.J~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800b000, 0                      , 0,
+       0x0                 },        /* P.J~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800c000, 0                      , 0,
+       0x0                 },        /* P.J~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800d000, 0                      , 0,
+       0x0                 },        /* P.J~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800e000, 0                      , 0,
+       0x0                 },        /* P.J~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00f000, 0x4800f000, 0                      , 0,
+       0x0                 },        /* P.J~*(15) */
+};
+
+
+NMD::Pool NMD::P_BR3A[32] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1fc000, 0x88004000, &NMD::BC1EQZC          , 0,
+       CP1_                },        /* BC1EQZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1fc000, 0x88014000, &NMD::BC1NEZC          , 0,
+       CP1_                },        /* BC1NEZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1fc000, 0x88024000, &NMD::BC2EQZC          , 0,
+       CP2_                },        /* BC2EQZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1fc000, 0x88034000, &NMD::BC2NEZC          , 0,
+       CP2_                },        /* BC2NEZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1fc000, 0x88044000, &NMD::BPOSGE32C        , 0,
+       DSP_                },        /* BPOSGE32C */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88054000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(5) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88064000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(6) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88074000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88084000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(8) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88094000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(9) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880a4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(10) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880b4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880c4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(12) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880d4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(13) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880e4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(14) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x880f4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88104000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(16) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88114000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(17) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88124000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(18) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88134000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88144000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(20) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88154000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(21) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88164000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(22) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88174000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88184000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(24) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x88194000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881a4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(26) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881b4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881c4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(28) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881d4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(29) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881e4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc1fc000, 0x881f4000, 0                      , 0,
+       0x0                 },        /* P.BR3A~*(31) */
+};
+
+
+NMD::Pool NMD::P_BR1[4] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0x88000000, &NMD::BEQC_32_         , 0,
+       0x0                 },        /* BEQC[32] */
+    { pool                , P_BR3A              , 32  , 32,
+       0xfc00c000, 0x88004000, 0                      , 0,
+       0x0                 },        /* P.BR3A */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0x88008000, &NMD::BGEC             , 0,
+       0x0                 },        /* BGEC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0x8800c000, &NMD::BGEUC            , 0,
+       0x0                 },        /* BGEUC */
+};
+
+
+NMD::Pool NMD::P_BR2[4] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0xa8000000, &NMD::BNEC_32_         , 0,
+       0x0                 },        /* BNEC[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc00c000, 0xa8004000, 0                      , 0,
+       0x0                 },        /* P.BR2~*(1) */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0xa8008000, &NMD::BLTC             , 0,
+       0x0                 },        /* BLTC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc00c000, 0xa800c000, &NMD::BLTUC            , 0,
+       0x0                 },        /* BLTUC */
+};
+
+
+NMD::Pool NMD::P_BRI[8] = {
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8000000, &NMD::BEQIC            , 0,
+       0x0                 },        /* BEQIC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8040000, &NMD::BBEQZC           , 0,
+       XMMS_               },        /* BBEQZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8080000, &NMD::BGEIC            , 0,
+       0x0                 },        /* BGEIC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc80c0000, &NMD::BGEIUC           , 0,
+       0x0                 },        /* BGEIUC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8100000, &NMD::BNEIC            , 0,
+       0x0                 },        /* BNEIC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8140000, &NMD::BBNEZC           , 0,
+       XMMS_               },        /* BBNEZC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc8180000, &NMD::BLTIC            , 0,
+       0x0                 },        /* BLTIC */
+    { branch_instruction  , 0                   , 0   , 32,
+       0xfc1c0000, 0xc81c0000, &NMD::BLTIUC           , 0,
+       0x0                 },        /* BLTIUC */
+};
+
+
+NMD::Pool NMD::P32[32] = {
+    { pool                , P_ADDIU             , 2   , 32,
+       0xfc000000, 0x00000000, 0                      , 0,
+       0x0                 },        /* P.ADDIU */
+    { pool                , P32A                , 8   , 32,
+       0xfc000000, 0x20000000, 0                      , 0,
+       0x0                 },        /* P32A */
+    { pool                , P_GP_W              , 4   , 32,
+       0xfc000000, 0x40000000, 0                      , 0,
+       0x0                 },        /* P.GP.W */
+    { pool                , POOL48I             , 32  , 48,
+       0xfc0000000000ull, 0x600000000000ull, 0                      , 0,
+       0x0                 },        /* POOL48I */
+    { pool                , P_U12               , 16  , 32,
+       0xfc000000, 0x80000000, 0                      , 0,
+       0x0                 },        /* P.U12 */
+    { pool                , POOL32F             , 8   , 32,
+       0xfc000000, 0xa0000000, 0                      , 0,
+       CP1_                },        /* POOL32F */
+    { pool                , POOL32S             , 8   , 32,
+       0xfc000000, 0xc0000000, 0                      , 0,
+       0x0                 },        /* POOL32S */
+    { pool                , P_LUI               , 2   , 32,
+       0xfc000000, 0xe0000000, 0                      , 0,
+       0x0                 },        /* P.LUI */
+    { instruction         , 0                   , 0   , 32,
+       0xfc000000, 0x04000000, &NMD::ADDIUPC_32_      , 0,
+       0x0                 },        /* ADDIUPC[32] */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x24000000, 0                      , 0,
+       0x0                 },        /* P32~*(5) */
+    { pool                , P_GP_BH             , 8   , 32,
+       0xfc000000, 0x44000000, 0                      , 0,
+       0x0                 },        /* P.GP.BH */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x64000000, 0                      , 0,
+       0x0                 },        /* P32~*(13) */
+    { pool                , P_LS_U12            , 16  , 32,
+       0xfc000000, 0x84000000, 0                      , 0,
+       0x0                 },        /* P.LS.U12 */
+    { pool                , P_LS_S9             , 8   , 32,
+       0xfc000000, 0xa4000000, 0                      , 0,
+       0x0                 },        /* P.LS.S9 */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xc4000000, 0                      , 0,
+       0x0                 },        /* P32~*(25) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xe4000000, 0                      , 0,
+       0x0                 },        /* P32~*(29) */
+    { call_instruction    , 0                   , 0   , 32,
+       0xfc000000, 0x08000000, &NMD::MOVE_BALC        , 0,
+       XMMS_               },        /* MOVE.BALC */
+    { pool                , P_BAL               , 2   , 32,
+       0xfc000000, 0x28000000, 0                      , 0,
+       0x0                 },        /* P.BAL */
+    { pool                , P_J                 , 16  , 32,
+       0xfc000000, 0x48000000, 0                      , 0,
+       0x0                 },        /* P.J */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x68000000, 0                      , 0,
+       0x0                 },        /* P32~*(14) */
+    { pool                , P_BR1               , 4   , 32,
+       0xfc000000, 0x88000000, 0                      , 0,
+       0x0                 },        /* P.BR1 */
+    { pool                , P_BR2               , 4   , 32,
+       0xfc000000, 0xa8000000, 0                      , 0,
+       0x0                 },        /* P.BR2 */
+    { pool                , P_BRI               , 8   , 32,
+       0xfc000000, 0xc8000000, 0                      , 0,
+       0x0                 },        /* P.BRI */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xe8000000, 0                      , 0,
+       0x0                 },        /* P32~*(30) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x0c000000, 0                      , 0,
+       0x0                 },        /* P32~*(3) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x2c000000, 0                      , 0,
+       0x0                 },        /* P32~*(7) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x4c000000, 0                      , 0,
+       0x0                 },        /* P32~*(11) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x6c000000, 0                      , 0,
+       0x0                 },        /* P32~*(15) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0x8c000000, 0                      , 0,
+       0x0                 },        /* P32~*(19) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xac000000, 0                      , 0,
+       0x0                 },        /* P32~*(23) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xcc000000, 0                      , 0,
+       0x0                 },        /* P32~*(27) */
+    { reserved_block      , 0                   , 0   , 32,
+       0xfc000000, 0xec000000, 0                      , 0,
+       0x0                 },        /* P32~*(31) */
+};
+
+
+NMD::Pool NMD::P16_SYSCALL[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfffc    , 0x1008    , &NMD::SYSCALL_16_      , 0,
+       0x0                 },        /* SYSCALL[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfffc    , 0x100c    , &NMD::HYPCALL_16_      , 0,
+       CP0_ | VZ_          },        /* HYPCALL[16] */
+};
+
+
+NMD::Pool NMD::P16_RI[4] = {
+    { reserved_block      , 0                   , 0   , 16,
+       0xfff8    , 0x1000    , 0                      , 0,
+       0x0                 },        /* P16.RI~*(0) */
+    { pool                , P16_SYSCALL         , 2   , 16,
+       0xfff8    , 0x1008    , 0                      , 0,
+       0x0                 },        /* P16.SYSCALL */
+    { instruction         , 0                   , 0   , 16,
+       0xfff8    , 0x1010    , &NMD::BREAK_16_        , 0,
+       0x0                 },        /* BREAK[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfff8    , 0x1018    , &NMD::SDBBP_16_        , 0,
+       EJTAG_              },        /* SDBBP[16] */
+};
+
+
+NMD::Pool NMD::P16_MV[2] = {
+    { pool                , P16_RI              , 4   , 16,
+       0xffe0    , 0x1000    , 0                      , 0,
+       0x0                 },        /* P16.RI */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x1000    , &NMD::MOVE             , &NMD::MOVE_cond        ,
+       0x0                 },        /* MOVE */
+};
+
+
+NMD::Pool NMD::P16_SHIFT[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc08    , 0x3000    , &NMD::SLL_16_          , 0,
+       0x0                 },        /* SLL[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc08    , 0x3008    , &NMD::SRL_16_          , 0,
+       0x0                 },        /* SRL[16] */
+};
+
+
+NMD::Pool NMD::POOL16C_00[4] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc0f    , 0x5000    , &NMD::NOT_16_          , 0,
+       0x0                 },        /* NOT[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc0f    , 0x5004    , &NMD::XOR_16_          , 0,
+       0x0                 },        /* XOR[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc0f    , 0x5008    , &NMD::AND_16_          , 0,
+       0x0                 },        /* AND[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc0f    , 0x500c    , &NMD::OR_16_           , 0,
+       0x0                 },        /* OR[16] */
+};
+
+
+NMD::Pool NMD::POOL16C_0[2] = {
+    { pool                , POOL16C_00          , 4   , 16,
+       0xfc03    , 0x5000    , 0                      , 0,
+       0x0                 },        /* POOL16C_00 */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc03    , 0x5002    , 0                      , 0,
+       0x0                 },        /* POOL16C_0~*(1) */
+};
+
+
+NMD::Pool NMD::P16C[2] = {
+    { pool                , POOL16C_0           , 2   , 16,
+       0xfc01    , 0x5000    , 0                      , 0,
+       0x0                 },        /* POOL16C_0 */
+    { instruction         , 0                   , 0   , 16,
+       0xfc01    , 0x5001    , &NMD::LWXS_16_         , 0,
+       0x0                 },        /* LWXS[16] */
+};
+
+
+NMD::Pool NMD::P16_A1[2] = {
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc40    , 0x7000    , 0                      , 0,
+       0x0                 },        /* P16.A1~*(0) */
+    { instruction         , 0                   , 0   , 16,
+       0xfc40    , 0x7040    , &NMD::ADDIU_R1_SP_     , 0,
+       0x0                 },        /* ADDIU[R1.SP] */
+};
+
+
+NMD::Pool NMD::P_ADDIU_RS5_[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xffe8    , 0x9008    , &NMD::NOP_16_          , 0,
+       0x0                 },        /* NOP[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc08    , 0x9008    , &NMD::ADDIU_RS5_       , &NMD::ADDIU_RS5__cond  ,
+       0x0                 },        /* ADDIU[RS5] */
+};
+
+
+NMD::Pool NMD::P16_A2[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc08    , 0x9000    , &NMD::ADDIU_R2_        , 0,
+       0x0                 },        /* ADDIU[R2] */
+    { pool                , P_ADDIU_RS5_        , 2   , 16,
+       0xfc08    , 0x9008    , 0                      , 0,
+       0x0                 },        /* P.ADDIU[RS5] */
+};
+
+
+NMD::Pool NMD::P16_ADDU[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc01    , 0xb000    , &NMD::ADDU_16_         , 0,
+       0x0                 },        /* ADDU[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc01    , 0xb001    , &NMD::SUBU_16_         , 0,
+       0x0                 },        /* SUBU[16] */
+};
+
+
+NMD::Pool NMD::P16_JRC[2] = {
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc1f    , 0xd800    , &NMD::JRC              , 0,
+       0x0                 },        /* JRC */
+    { call_instruction    , 0                   , 0   , 16,
+       0xfc1f    , 0xd810    , &NMD::JALRC_16_        , 0,
+       0x0                 },        /* JALRC[16] */
+};
+
+
+NMD::Pool NMD::P16_BR1[2] = {
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc00    , 0xd800    , &NMD::BEQC_16_         , &NMD::BEQC_16__cond    ,
+       XMMS_               },        /* BEQC[16] */
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc00    , 0xd800    , &NMD::BNEC_16_         , &NMD::BNEC_16__cond    ,
+       XMMS_               },        /* BNEC[16] */
+};
+
+
+NMD::Pool NMD::P16_BR[2] = {
+    { pool                , P16_JRC             , 2   , 16,
+       0xfc0f    , 0xd800    , 0                      , 0,
+       0x0                 },        /* P16.JRC */
+    { pool                , P16_BR1             , 2   , 16,
+       0xfc00    , 0xd800    , 0                      , &NMD::P16_BR1_cond     ,
+       0x0                 },        /* P16.BR1 */
+};
+
+
+NMD::Pool NMD::P16_SR[2] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfd00    , 0x1c00    , &NMD::SAVE_16_         , 0,
+       0x0                 },        /* SAVE[16] */
+    { return_instruction  , 0                   , 0   , 16,
+       0xfd00    , 0x1d00    , &NMD::RESTORE_JRC_16_  , 0,
+       0x0                 },        /* RESTORE.JRC[16] */
+};
+
+
+NMD::Pool NMD::P16_4X4[4] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfd08    , 0x3c00    , &NMD::ADDU_4X4_        , 0,
+       XMMS_               },        /* ADDU[4X4] */
+    { instruction         , 0                   , 0   , 16,
+       0xfd08    , 0x3c08    , &NMD::MUL_4X4_         , 0,
+       XMMS_               },        /* MUL[4X4] */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfd08    , 0x3d00    , 0                      , 0,
+       0x0                 },        /* P16.4X4~*(2) */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfd08    , 0x3d08    , 0                      , 0,
+       0x0                 },        /* P16.4X4~*(3) */
+};
+
+
+NMD::Pool NMD::P16_LB[4] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc0c    , 0x5c00    , &NMD::LB_16_           , 0,
+       0x0                 },        /* LB[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc0c    , 0x5c04    , &NMD::SB_16_           , 0,
+       0x0                 },        /* SB[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc0c    , 0x5c08    , &NMD::LBU_16_          , 0,
+       0x0                 },        /* LBU[16] */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc0c    , 0x5c0c    , 0                      , 0,
+       0x0                 },        /* P16.LB~*(3) */
+};
+
+
+NMD::Pool NMD::P16_LH[4] = {
+    { instruction         , 0                   , 0   , 16,
+       0xfc09    , 0x7c00    , &NMD::LH_16_           , 0,
+       0x0                 },        /* LH[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc09    , 0x7c01    , &NMD::SH_16_           , 0,
+       0x0                 },        /* SH[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc09    , 0x7c08    , &NMD::LHU_16_          , 0,
+       0x0                 },        /* LHU[16] */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc09    , 0x7c09    , 0                      , 0,
+       0x0                 },        /* P16.LH~*(3) */
+};
+
+
+NMD::Pool NMD::P16[32] = {
+    { pool                , P16_MV              , 2   , 16,
+       0xfc00    , 0x1000    , 0                      , 0,
+       0x0                 },        /* P16.MV */
+    { pool                , P16_SHIFT           , 2   , 16,
+       0xfc00    , 0x3000    , 0                      , 0,
+       0x0                 },        /* P16.SHIFT */
+    { pool                , P16C                , 2   , 16,
+       0xfc00    , 0x5000    , 0                      , 0,
+       0x0                 },        /* P16C */
+    { pool                , P16_A1              , 2   , 16,
+       0xfc00    , 0x7000    , 0                      , 0,
+       0x0                 },        /* P16.A1 */
+    { pool                , P16_A2              , 2   , 16,
+       0xfc00    , 0x9000    , 0                      , 0,
+       0x0                 },        /* P16.A2 */
+    { pool                , P16_ADDU            , 2   , 16,
+       0xfc00    , 0xb000    , 0                      , 0,
+       0x0                 },        /* P16.ADDU */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xd000    , &NMD::LI_16_           , 0,
+       0x0                 },        /* LI[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xf000    , &NMD::ANDI_16_         , 0,
+       0x0                 },        /* ANDI[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x1400    , &NMD::LW_16_           , 0,
+       0x0                 },        /* LW[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x3400    , &NMD::LW_SP_           , 0,
+       0x0                 },        /* LW[SP] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x5400    , &NMD::LW_GP16_         , 0,
+       0x0                 },        /* LW[GP16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x7400    , &NMD::LW_4X4_          , 0,
+       XMMS_               },        /* LW[4X4] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0x9400    , &NMD::SW_16_           , 0,
+       0x0                 },        /* SW[16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xb400    , &NMD::SW_SP_           , 0,
+       0x0                 },        /* SW[SP] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xd400    , &NMD::SW_GP16_         , 0,
+       0x0                 },        /* SW[GP16] */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xf400    , &NMD::SW_4X4_          , 0,
+       XMMS_               },        /* SW[4X4] */
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc00    , 0x1800    , &NMD::BC_16_           , 0,
+       0x0                 },        /* BC[16] */
+    { call_instruction    , 0                   , 0   , 16,
+       0xfc00    , 0x3800    , &NMD::BALC_16_         , 0,
+       0x0                 },        /* BALC[16] */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc00    , 0x5800    , 0                      , 0,
+       0x0                 },        /* P16~*(10) */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc00    , 0x7800    , 0                      , 0,
+       0x0                 },        /* P16~*(14) */
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc00    , 0x9800    , &NMD::BEQZC_16_        , 0,
+       0x0                 },        /* BEQZC[16] */
+    { branch_instruction  , 0                   , 0   , 16,
+       0xfc00    , 0xb800    , &NMD::BNEZC_16_        , 0,
+       0x0                 },        /* BNEZC[16] */
+    { pool                , P16_BR              , 2   , 16,
+       0xfc00    , 0xd800    , 0                      , 0,
+       0x0                 },        /* P16.BR */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc00    , 0xf800    , 0                      , 0,
+       0x0                 },        /* P16~*(30) */
+    { pool                , P16_SR              , 2   , 16,
+       0xfc00    , 0x1c00    , 0                      , 0,
+       0x0                 },        /* P16.SR */
+    { pool                , P16_4X4             , 4   , 16,
+       0xfc00    , 0x3c00    , 0                      , 0,
+       0x0                 },        /* P16.4X4 */
+    { pool                , P16_LB              , 4   , 16,
+       0xfc00    , 0x5c00    , 0                      , 0,
+       0x0                 },        /* P16.LB */
+    { pool                , P16_LH              , 4   , 16,
+       0xfc00    , 0x7c00    , 0                      , 0,
+       0x0                 },        /* P16.LH */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc00    , 0x9c00    , 0                      , 0,
+       0x0                 },        /* P16~*(19) */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xbc00    , &NMD::MOVEP            , 0,
+       XMMS_               },        /* MOVEP */
+    { reserved_block      , 0                   , 0   , 16,
+       0xfc00    , 0xdc00    , 0                      , 0,
+       0x0                 },        /* P16~*(27) */
+    { instruction         , 0                   , 0   , 16,
+       0xfc00    , 0xfc00    , &NMD::MOVEP_REV_       , 0,
+       XMMS_               },        /* MOVEP[REV] */
+};
+
+
+NMD::Pool NMD::MAJOR[2] = {
+    { pool                , P32                 , 32  , 32,
+       0x10000000, 0x00000000, 0                      , 0,
+       0x0                 },        /* P32 */
+    { pool                , P16                 , 32  , 16,
+       0x1000    , 0x1000    , 0                      , 0,
+       0x0                 },        /* P16 */
+};
+
+
+extern "C"
+{
+    int nanomips_dis(char *buf,
+                     unsigned address,
+                     unsigned short one,
+                     unsigned short two,
+                     unsigned short three)
+    {
+        std::string disasm;
+        uint16 bits[3] = {one, two, three};
+
+        NMD::TABLE_ENTRY_TYPE type;
+        NMD d(address, NMD::ALL_ATTRIBUTES);
+        int size = d.Disassemble(bits, disasm, type);
+
+        strcpy(buf, disasm.c_str());
+        return size;
+    }
+}
diff --git a/disas/nanomips.h b/disas/nanomips.h
new file mode 100644
index 0000000..9f5bc9d
--- /dev/null
+++ b/disas/nanomips.h
@@ -0,0 +1,1208 @@
+
+#ifndef NANOMIPS_DISASSEMBLER_H
+#define NANOMIPS_DISASSEMBLER_H
+
+#include <string>
+#ifdef INCLUDE_STANDALONE_UNIT_TEST
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef long long int64;
+typedef unsigned long long uint64;
+
+namespace img
+{
+    typedef unsigned long long address;
+}
+#else
+#include "imgleeds/imgleeds/address.h"
+#endif
+
+
+
+class NMD
+{
+public:
+    enum TABLE_ENTRY_TYPE {
+        instruction,
+        call_instruction,
+        branch_instruction,
+        return_instruction,
+        reserved_block,
+        pool,
+    };
+    enum TABLE_ATTRIBUTE_TYPE {
+        MIPS64_    = 0x00000001,
+        XNP_       = 0x00000002,
+        XMMS_      = 0x00000004,
+        EVA_       = 0x00000008,
+        DSP_       = 0x00000010,
+        MT_        = 0x00000020,
+        EJTAG_     = 0x00000040,
+        TLBINV_    = 0x00000080,
+        CP0_       = 0x00000100,
+        CP1_       = 0x00000200,
+        CP2_       = 0x00000400,
+        UDI_       = 0x00000800,
+        MCU_       = 0x00001000,
+        VZ_        = 0x00002000,
+        TLB_       = 0x00004000,
+        MVH_       = 0x00008000,
+        ALL_ATTRIBUTES = 0xffffffffull,
+    };
+
+
+    NMD(img::address pc, TABLE_ATTRIBUTE_TYPE requested_instruction_catagories)
+        : m_pc(pc)
+        , m_requested_instruction_catagories(requested_instruction_catagories)
+    {
+    }
+
+    int Disassemble(const uint16 *data, std::string & dis,
+                    TABLE_ENTRY_TYPE & type);
+
+private:
+    img::address           m_pc;
+    TABLE_ATTRIBUTE_TYPE   m_requested_instruction_catagories;
+
+    typedef std::string
+            (NMD:: *disassembly_function)(uint64 instruction);
+    typedef bool
+            (NMD:: *conditional_function)(uint64 instruction);
+
+    struct Pool {
+        TABLE_ENTRY_TYPE     type;
+        struct Pool          *next_table;
+        int                  next_table_size;
+        int                  instructions_size;
+        uint64               mask;
+        uint64               value;
+        disassembly_function disassembly;
+        conditional_function condition;
+        uint64               attributes;
+    };
+
+    uint64 extract_op_code_value(const uint16 *data, int size);
+    int Disassemble(const uint16 *data, std::string & dis,
+                    TABLE_ENTRY_TYPE & type, const Pool *table, int table_size);
+
+    uint64 renumber_registers(uint64 index, uint64 *register_list,
+                              size_t register_list_size);
+    uint64 encode_gpr3(uint64 d);
+    uint64 encode_gpr3_store(uint64 d);
+    uint64 encode_rd1_from_rd(uint64 d);
+    uint64 encode_gpr4_zero(uint64 d);
+    uint64 encode_gpr4(uint64 d);
+    uint64 encode_rd2_reg1(uint64 d);
+    uint64 encode_rd2_reg2(uint64 d);
+
+    uint64 copy(uint64 d);
+    int64 copy(int64 d);
+    int64 neg_copy(uint64 d);
+    int64 neg_copy(int64 d);
+    uint64 encode_rs3_and_check_rs3_ge_rt3(uint64 d);
+    uint64 encode_rs3_and_check_rs3_lt_rt3(uint64 d);
+    uint64 encode_s_from_address(uint64 d);
+    uint64 encode_u_from_address(uint64 d);
+    uint64 encode_s_from_s_hi(uint64 d);
+    uint64 encode_count3_from_count(uint64 d);
+    uint64 encode_shift3_from_shift(uint64 d);
+    int64 encode_eu_from_s_li16(uint64 d);
+    uint64 encode_msbd_from_size(uint64 d);
+    uint64 encode_eu_from_u_andi16(uint64 d);
+
+    uint64 encode_msbd_from_pos_and_size(uint64 d);
+
+    uint64 encode_rt1_from_rt(uint64 d);
+    uint64 encode_lsb_from_pos_and_size(uint64 d);
+
+    std::string save_restore_list(uint64 rt, uint64 count, uint64 gp);
+
+    std::string GPR(uint64 reg);
+    std::string FPR(uint64 reg);
+    std::string AC(uint64 reg);
+    std::string IMMEDIATE(uint64 value);
+    std::string IMMEDIATE(int64 value);
+    std::string CPR(uint64 reg);
+    std::string ADDRESS(uint64 value, int instruction_size);
+
+    uint64 extr_codeil0il0bs19Fmsb18(
+               uint64 instruction);
+    uint64 extr_shift3il0il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil3il3bs9Fmsb11(
+               uint64 instruction);
+    uint64 extr_countil0il0bs4Fmsb3(
+               uint64 instruction);
+    uint64 extr_rtz3il7il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil1il1bs17Fmsb17(
+               uint64 instruction);
+    int64 extr_sil11il0bs10Tmsb9(
+               uint64 instruction);
+    int64 extr_sil0il11bs1_il1il1bs10Tmsb11(
+               uint64 instruction);
+    uint64 extr_uil10il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_rtz4il21il0bs3_il25il3bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_sail11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_shiftil0il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_shiftxil7il1bs4Fmsb4(
+               uint64 instruction);
+    uint64 extr_hintil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_count3il12il0bs3Fmsb2(
+               uint64 instruction);
+    int64 extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(
+               uint64 instruction);
+    int64 extr_sil0il7bs1_il1il1bs6Tmsb7(
+               uint64 instruction);
+    uint64 extr_u2il9il0bs2Fmsb1(
+               uint64 instruction);
+    uint64 extr_codeil16il0bs10Fmsb9(
+               uint64 instruction);
+    uint64 extr_rsil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil1il1bs2Fmsb2(
+               uint64 instruction);
+    uint64 extr_stripeil6il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_xil17il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_xil2il0bs1_il15il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_acil14il0bs2Fmsb1(
+               uint64 instruction);
+    uint64 extr_shiftil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_rd1il24il0bs1Fmsb0(
+               uint64 instruction);
+    int64 extr_sil0il10bs1_il1il1bs9Tmsb10(
+               uint64 instruction);
+    uint64 extr_euil0il0bs7Fmsb6(
+               uint64 instruction);
+    uint64 extr_shiftil0il0bs6Fmsb5(
+               uint64 instruction);
+    uint64 extr_xil10il0bs6Fmsb5(
+               uint64 instruction);
+    uint64 extr_countil16il0bs4Fmsb3(
+               uint64 instruction);
+    uint64 extr_codeil0il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_xil10il0bs4_il22il0bs4Fmsb3(
+               uint64 instruction);
+    uint64 extr_uil0il0bs12Fmsb11(
+               uint64 instruction);
+    uint64 extr_rsil0il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil3il3bs18Fmsb20(
+               uint64 instruction);
+    uint64 extr_xil12il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_uil0il2bs4Fmsb5(
+               uint64 instruction);
+    uint64 extr_cofunil3il0bs23Fmsb22(
+               uint64 instruction);
+    uint64 extr_uil0il2bs3Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil10il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_rd3il1il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_sail12il0bs4Fmsb3(
+               uint64 instruction);
+    uint64 extr_rtil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_ruil3il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil9il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil0il0bs18Fmsb17(
+               uint64 instruction);
+    uint64 extr_xil14il0bs1_il15il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_rsz4il0il0bs3_il4il3bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_xil24il0bs1Fmsb0(
+               uint64 instruction);
+    int64 extr_sil0il21bs1_il1il1bs20Tmsb21(
+               uint64 instruction);
+    uint64 extr_opil3il0bs23Fmsb22(
+               uint64 instruction);
+    uint64 extr_rs4il0il0bs3_il4il3bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_bitil21il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_rtil37il0bs5Fmsb4(
+               uint64 instruction);
+    int64 extr_sil16il0bs6Tmsb5(
+               uint64 instruction);
+    uint64 extr_xil6il0bs3_il10il0bs1Fmsb2(
+               uint64 instruction);
+    uint64 extr_rd2il3il1bs1_il8il0bs1Fmsb1(
+               uint64 instruction);
+    uint64 extr_xil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_codeil0il0bs18Fmsb17(
+               uint64 instruction);
+    uint64 extr_xil0il0bs12Fmsb11(
+               uint64 instruction);
+    uint64 extr_sizeil16il0bs5Fmsb4(
+               uint64 instruction);
+    int64 extr_sil2il2bs6_il15il8bs1Tmsb8(
+               uint64 instruction);
+    uint64 extr_uil0il0bs16Fmsb15(
+               uint64 instruction);
+    uint64 extr_fsil16il0bs5Fmsb4(
+               uint64 instruction);
+    int64 extr_sil0il0bs8_il15il8bs1Tmsb8(
+               uint64 instruction);
+    uint64 extr_stypeil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_rt1il9il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_hsil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil10il0bs1_il14il0bs2Fmsb1(
+               uint64 instruction);
+    uint64 extr_selil11il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_lsbil0il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil14il0bs2Fmsb1(
+               uint64 instruction);
+    uint64 extr_gpil2il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_rt3il7il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_ftil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil11il0bs7Fmsb6(
+               uint64 instruction);
+    uint64 extr_csil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil16il0bs10Fmsb9(
+               uint64 instruction);
+    uint64 extr_rt4il5il0bs3_il9il3bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_msbdil6il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil0il2bs6Fmsb7(
+               uint64 instruction);
+    uint64 extr_xil17il0bs9Fmsb8(
+               uint64 instruction);
+    uint64 extr_sail13il0bs3Fmsb2(
+               uint64 instruction);
+    int64 extr_sil0il14bs1_il1il1bs13Tmsb14(
+               uint64 instruction);
+    uint64 extr_rs3il4il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil0il32bs32Fmsb63(
+               uint64 instruction);
+    uint64 extr_shiftil6il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_csil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_shiftxil6il0bs6Fmsb5(
+               uint64 instruction);
+    uint64 extr_rtil5il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_opil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil0il2bs7Fmsb8(
+               uint64 instruction);
+    uint64 extr_bitil11il0bs6Fmsb5(
+               uint64 instruction);
+    uint64 extr_xil10il0bs1_il11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_maskil14il0bs7Fmsb6(
+               uint64 instruction);
+    uint64 extr_euil0il0bs4Fmsb3(
+               uint64 instruction);
+    uint64 extr_uil4il4bs4Fmsb7(
+               uint64 instruction);
+    int64 extr_sil3il3bs5_il15il8bs1Tmsb8(
+               uint64 instruction);
+    uint64 extr_ftil11il0bs5Fmsb4(
+               uint64 instruction);
+    int64 extr_sil0il16bs16_il16il0bs16Tmsb31(
+               uint64 instruction);
+    uint64 extr_uil13il0bs8Fmsb7(
+               uint64 instruction);
+    uint64 extr_xil15il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_xil11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_uil2il2bs16Fmsb17(
+               uint64 instruction);
+    uint64 extr_rdil11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_c0sil16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_codeil0il0bs2Fmsb1(
+               uint64 instruction);
+    int64 extr_sil0il25bs1_il1il1bs24Tmsb25(
+               uint64 instruction);
+    uint64 extr_xil0il0bs3_il4il0bs1Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil0il0bs2Fmsb1(
+               uint64 instruction);
+    uint64 extr_uil3il3bs1_il8il2bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_xil9il0bs3_il16il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_fdil11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil6il0bs3Fmsb2(
+               uint64 instruction);
+    uint64 extr_uil0il2bs5Fmsb6(
+               uint64 instruction);
+    uint64 extr_rtz4il5il0bs3_il9il3bs1Fmsb3(
+               uint64 instruction);
+    uint64 extr_selil11il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_ctil21il0bs5Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil11il0bs1Fmsb0(
+               uint64 instruction);
+    uint64 extr_uil2il2bs19Fmsb20(
+               uint64 instruction);
+    int64 extr_sil0il0bs3_il4il3bs1Tmsb3(
+               uint64 instruction);
+    uint64 extr_uil0il1bs4Fmsb4(
+               uint64 instruction);
+    uint64 extr_xil9il0bs2Fmsb1(
+               uint64 instruction);
+
+    bool BNEC_16__cond(uint64 instruction);
+    bool ADDIU_32__cond(uint64 instruction);
+    bool P16_BR1_cond(uint64 instruction);
+    bool ADDIU_RS5__cond(uint64 instruction);
+    bool BEQC_16__cond(uint64 instruction);
+    bool SLTU_cond(uint64 instruction);
+    bool PREF_S9__cond(uint64 instruction);
+    bool BALRSC_cond(uint64 instruction);
+    bool MOVE_cond(uint64 instruction);
+    bool PREFE_cond(uint64 instruction);
+
+    std::string SIGRIE(uint64 instruction);
+    std::string SYSCALL_32_(uint64 instruction);
+    std::string HYPCALL(uint64 instruction);
+    std::string BREAK_32_(uint64 instruction);
+    std::string SDBBP_32_(uint64 instruction);
+    std::string ADDIU_32_(uint64 instruction);
+    std::string TEQ(uint64 instruction);
+    std::string TNE(uint64 instruction);
+    std::string SEB(uint64 instruction);
+    std::string SLLV(uint64 instruction);
+    std::string MUL_32_(uint64 instruction);
+    std::string MFC0(uint64 instruction);
+    std::string MFHC0(uint64 instruction);
+    std::string SEH(uint64 instruction);
+    std::string SRLV(uint64 instruction);
+    std::string MUH(uint64 instruction);
+    std::string MTC0(uint64 instruction);
+    std::string MTHC0(uint64 instruction);
+    std::string SRAV(uint64 instruction);
+    std::string MULU(uint64 instruction);
+    std::string MFGC0(uint64 instruction);
+    std::string MFHGC0(uint64 instruction);
+    std::string ROTRV(uint64 instruction);
+    std::string MUHU(uint64 instruction);
+    std::string MTGC0(uint64 instruction);
+    std::string MTHGC0(uint64 instruction);
+    std::string ADD(uint64 instruction);
+    std::string DIV(uint64 instruction);
+    std::string DMFC0(uint64 instruction);
+    std::string ADDU_32_(uint64 instruction);
+    std::string MOD(uint64 instruction);
+    std::string DMTC0(uint64 instruction);
+    std::string SUB(uint64 instruction);
+    std::string DIVU(uint64 instruction);
+    std::string DMFGC0(uint64 instruction);
+    std::string RDHWR(uint64 instruction);
+    std::string SUBU_32_(uint64 instruction);
+    std::string MODU(uint64 instruction);
+    std::string DMTGC0(uint64 instruction);
+    std::string MOVZ(uint64 instruction);
+    std::string MOVN(uint64 instruction);
+    std::string FORK(uint64 instruction);
+    std::string MFTR(uint64 instruction);
+    std::string MFHTR(uint64 instruction);
+    std::string AND_32_(uint64 instruction);
+    std::string YIELD(uint64 instruction);
+    std::string MTTR(uint64 instruction);
+    std::string MTHTR(uint64 instruction);
+    std::string OR_32_(uint64 instruction);
+    std::string DMT(uint64 instruction);
+    std::string DVPE(uint64 instruction);
+    std::string EMT(uint64 instruction);
+    std::string EVPE(uint64 instruction);
+    std::string NOR(uint64 instruction);
+    std::string XOR_32_(uint64 instruction);
+    std::string SLT(uint64 instruction);
+    std::string DVP(uint64 instruction);
+    std::string EVP(uint64 instruction);
+    std::string SLTU(uint64 instruction);
+    std::string SOV(uint64 instruction);
+    std::string SPECIAL2(uint64 instruction);
+    std::string COP2_1(uint64 instruction);
+    std::string UDI(uint64 instruction);
+    std::string CMP_EQ_PH(uint64 instruction);
+    std::string ADDQ_PH(uint64 instruction);
+    std::string ADDQ_S_PH(uint64 instruction);
+    std::string SHILO(uint64 instruction);
+    std::string MULEQ_S_W_PHL(uint64 instruction);
+    std::string MUL_PH(uint64 instruction);
+    std::string MUL_S_PH(uint64 instruction);
+    std::string REPL_PH(uint64 instruction);
+    std::string CMP_LT_PH(uint64 instruction);
+    std::string ADDQH_PH(uint64 instruction);
+    std::string ADDQH_R_PH(uint64 instruction);
+    std::string MULEQ_S_W_PHR(uint64 instruction);
+    std::string PRECR_QB_PH(uint64 instruction);
+    std::string CMP_LE_PH(uint64 instruction);
+    std::string ADDQH_W(uint64 instruction);
+    std::string ADDQH_R_W(uint64 instruction);
+    std::string MULEU_S_PH_QBL(uint64 instruction);
+    std::string PRECRQ_QB_PH(uint64 instruction);
+    std::string CMPGU_EQ_QB(uint64 instruction);
+    std::string ADDU_QB(uint64 instruction);
+    std::string ADDU_S_QB(uint64 instruction);
+    std::string MULEU_S_PH_QBR(uint64 instruction);
+    std::string PRECRQ_PH_W(uint64 instruction);
+    std::string CMPGU_LT_QB(uint64 instruction);
+    std::string ADDU_PH(uint64 instruction);
+    std::string ADDU_S_PH(uint64 instruction);
+    std::string MULQ_RS_PH(uint64 instruction);
+    std::string PRECRQ_RS_PH_W(uint64 instruction);
+    std::string CMPGU_LE_QB(uint64 instruction);
+    std::string ADDUH_QB(uint64 instruction);
+    std::string ADDUH_R_QB(uint64 instruction);
+    std::string MULQ_S_PH(uint64 instruction);
+    std::string PRECRQU_S_QB_PH(uint64 instruction);
+    std::string CMPGDU_EQ_QB(uint64 instruction);
+    std::string SHRAV_PH(uint64 instruction);
+    std::string SHRAV_R_PH(uint64 instruction);
+    std::string MULQ_RS_W(uint64 instruction);
+    std::string PACKRL_PH(uint64 instruction);
+    std::string CMPGDU_LT_QB(uint64 instruction);
+    std::string SHRAV_QB(uint64 instruction);
+    std::string SHRAV_R_QB(uint64 instruction);
+    std::string MULQ_S_W(uint64 instruction);
+    std::string PICK_QB(uint64 instruction);
+    std::string CMPGDU_LE_QB(uint64 instruction);
+    std::string SUBQ_PH(uint64 instruction);
+    std::string SUBQ_S_PH(uint64 instruction);
+    std::string APPEND(uint64 instruction);
+    std::string PICK_PH(uint64 instruction);
+    std::string CMPU_EQ_QB(uint64 instruction);
+    std::string SUBQH_PH(uint64 instruction);
+    std::string SUBQH_R_PH(uint64 instruction);
+    std::string PREPEND(uint64 instruction);
+    std::string CMPU_LT_QB(uint64 instruction);
+    std::string SUBQH_W(uint64 instruction);
+    std::string SUBQH_R_W(uint64 instruction);
+    std::string MODSUB(uint64 instruction);
+    std::string CMPU_LE_QB(uint64 instruction);
+    std::string SUBU_QB(uint64 instruction);
+    std::string SUBU_S_QB(uint64 instruction);
+    std::string SHRAV_R_W(uint64 instruction);
+    std::string SHRA_R_W(uint64 instruction);
+    std::string ADDQ_S_W(uint64 instruction);
+    std::string SUBU_PH(uint64 instruction);
+    std::string SUBU_S_PH(uint64 instruction);
+    std::string SHRLV_PH(uint64 instruction);
+    std::string SHRA_PH(uint64 instruction);
+    std::string SHRA_R_PH(uint64 instruction);
+    std::string SUBQ_S_W(uint64 instruction);
+    std::string SUBUH_QB(uint64 instruction);
+    std::string SUBUH_R_QB(uint64 instruction);
+    std::string SHRLV_QB(uint64 instruction);
+    std::string ADDSC(uint64 instruction);
+    std::string SHLLV_PH(uint64 instruction);
+    std::string SHLLV_S_PH(uint64 instruction);
+    std::string SHLLV_QB(uint64 instruction);
+    std::string SHLL_PH(uint64 instruction);
+    std::string SHLL_S_PH(uint64 instruction);
+    std::string ADDWC(uint64 instruction);
+    std::string PRECR_SRA_PH_W(uint64 instruction);
+    std::string PRECR_SRA_R_PH_W(uint64 instruction);
+    std::string SHLLV_S_W(uint64 instruction);
+    std::string SHLL_S_W(uint64 instruction);
+    std::string LBX(uint64 instruction);
+    std::string SBX(uint64 instruction);
+    std::string LBUX(uint64 instruction);
+    std::string LHX(uint64 instruction);
+    std::string SHX(uint64 instruction);
+    std::string LHUX(uint64 instruction);
+    std::string LWUX(uint64 instruction);
+    std::string LWX(uint64 instruction);
+    std::string SWX(uint64 instruction);
+    std::string LWC1X(uint64 instruction);
+    std::string SWC1X(uint64 instruction);
+    std::string LDX(uint64 instruction);
+    std::string SDX(uint64 instruction);
+    std::string LDC1X(uint64 instruction);
+    std::string SDC1X(uint64 instruction);
+    std::string LHXS(uint64 instruction);
+    std::string SHXS(uint64 instruction);
+    std::string LHUXS(uint64 instruction);
+    std::string LWUXS(uint64 instruction);
+    std::string LWXS_32_(uint64 instruction);
+    std::string SWXS(uint64 instruction);
+    std::string LWC1XS(uint64 instruction);
+    std::string SWC1XS(uint64 instruction);
+    std::string LDXS(uint64 instruction);
+    std::string SDXS(uint64 instruction);
+    std::string LDC1XS(uint64 instruction);
+    std::string SDC1XS(uint64 instruction);
+    std::string LSA(uint64 instruction);
+    std::string EXTW(uint64 instruction);
+    std::string MFHI_DSP_(uint64 instruction);
+    std::string MFLO_DSP_(uint64 instruction);
+    std::string MTHI_DSP_(uint64 instruction);
+    std::string MTLO_DSP_(uint64 instruction);
+    std::string MTHLIP(uint64 instruction);
+    std::string SHILOV(uint64 instruction);
+    std::string RDDSP(uint64 instruction);
+    std::string WRDSP(uint64 instruction);
+    std::string EXTP(uint64 instruction);
+    std::string EXTPDP(uint64 instruction);
+    std::string SHLL_QB(uint64 instruction);
+    std::string SHRL_QB(uint64 instruction);
+    std::string MAQ_S_W_PHR(uint64 instruction);
+    std::string MAQ_SA_W_PHR(uint64 instruction);
+    std::string MAQ_S_W_PHL(uint64 instruction);
+    std::string MAQ_SA_W_PHL(uint64 instruction);
+    std::string EXTR_W(uint64 instruction);
+    std::string EXTR_R_W(uint64 instruction);
+    std::string EXTR_RS_W(uint64 instruction);
+    std::string EXTR_S_H(uint64 instruction);
+    std::string DPA_W_PH(uint64 instruction);
+    std::string DPAQ_S_W_PH(uint64 instruction);
+    std::string DPS_W_PH(uint64 instruction);
+    std::string DPSQ_S_W_PH(uint64 instruction);
+    std::string MADD_DSP_(uint64 instruction);
+    std::string MULT_DSP_(uint64 instruction);
+    std::string EXTRV_W(uint64 instruction);
+    std::string DPAX_W_PH(uint64 instruction);
+    std::string DPAQ_SA_L_W(uint64 instruction);
+    std::string DPSX_W_PH(uint64 instruction);
+    std::string DPSQ_SA_L_W(uint64 instruction);
+    std::string MADDU_DSP_(uint64 instruction);
+    std::string MULTU_DSP_(uint64 instruction);
+    std::string EXTRV_R_W(uint64 instruction);
+    std::string DPAU_H_QBL(uint64 instruction);
+    std::string DPAQX_S_W_PH(uint64 instruction);
+    std::string DPSU_H_QBL(uint64 instruction);
+    std::string DPSQX_S_W_PH(uint64 instruction);
+    std::string EXTPV(uint64 instruction);
+    std::string MSUB_DSP_(uint64 instruction);
+    std::string MULSA_W_PH(uint64 instruction);
+    std::string EXTRV_RS_W(uint64 instruction);
+    std::string DPAU_H_QBR(uint64 instruction);
+    std::string DPAQX_SA_W_PH(uint64 instruction);
+    std::string DPSU_H_QBR(uint64 instruction);
+    std::string DPSQX_SA_W_PH(uint64 instruction);
+    std::string EXTPDPV(uint64 instruction);
+    std::string MSUBU_DSP_(uint64 instruction);
+    std::string MULSAQ_S_W_PH(uint64 instruction);
+    std::string EXTRV_S_H(uint64 instruction);
+    std::string ABSQ_S_QB(uint64 instruction);
+    std::string REPLV_PH(uint64 instruction);
+    std::string ABSQ_S_PH(uint64 instruction);
+    std::string REPLV_QB(uint64 instruction);
+    std::string ABSQ_S_W(uint64 instruction);
+    std::string INSV(uint64 instruction);
+    std::string CLO(uint64 instruction);
+    std::string MFC2(uint64 instruction);
+    std::string PRECEQ_W_PHL(uint64 instruction);
+    std::string CLZ(uint64 instruction);
+    std::string MTC2(uint64 instruction);
+    std::string PRECEQ_W_PHR(uint64 instruction);
+    std::string DMFC2(uint64 instruction);
+    std::string PRECEQU_PH_QBL(uint64 instruction);
+    std::string PRECEQU_PH_QBLA(uint64 instruction);
+    std::string DMTC2(uint64 instruction);
+    std::string MFHC2(uint64 instruction);
+    std::string PRECEQU_PH_QBR(uint64 instruction);
+    std::string PRECEQU_PH_QBRA(uint64 instruction);
+    std::string MTHC2(uint64 instruction);
+    std::string PRECEU_PH_QBL(uint64 instruction);
+    std::string PRECEU_PH_QBLA(uint64 instruction);
+    std::string CFC2(uint64 instruction);
+    std::string PRECEU_PH_QBR(uint64 instruction);
+    std::string PRECEU_PH_QBRA(uint64 instruction);
+    std::string CTC2(uint64 instruction);
+    std::string RADDU_W_QB(uint64 instruction);
+    std::string TLBGP(uint64 instruction);
+    std::string TLBP(uint64 instruction);
+    std::string TLBGINV(uint64 instruction);
+    std::string TLBINV(uint64 instruction);
+    std::string TLBGR(uint64 instruction);
+    std::string TLBR(uint64 instruction);
+    std::string TLBGINVF(uint64 instruction);
+    std::string TLBINVF(uint64 instruction);
+    std::string TLBGWI(uint64 instruction);
+    std::string TLBWI(uint64 instruction);
+    std::string TLBGWR(uint64 instruction);
+    std::string TLBWR(uint64 instruction);
+    std::string DI(uint64 instruction);
+    std::string EI(uint64 instruction);
+    std::string WAIT(uint64 instruction);
+    std::string IRET(uint64 instruction);
+    std::string RDPGPR(uint64 instruction);
+    std::string DERET(uint64 instruction);
+    std::string WRPGPR(uint64 instruction);
+    std::string ERET(uint64 instruction);
+    std::string ERETNC(uint64 instruction);
+    std::string SHRA_QB(uint64 instruction);
+    std::string SHRA_R_QB(uint64 instruction);
+    std::string SHRL_PH(uint64 instruction);
+    std::string REPL_QB(uint64 instruction);
+    std::string ADDIU_GP_W_(uint64 instruction);
+    std::string LD_GP_(uint64 instruction);
+    std::string SD_GP_(uint64 instruction);
+    std::string LW_GP_(uint64 instruction);
+    std::string SW_GP_(uint64 instruction);
+    std::string LI_48_(uint64 instruction);
+    std::string ADDIU_48_(uint64 instruction);
+    std::string ADDIU_GP48_(uint64 instruction);
+    std::string ADDIUPC_48_(uint64 instruction);
+    std::string LWPC_48_(uint64 instruction);
+    std::string SWPC_48_(uint64 instruction);
+    std::string DADDIU_48_(uint64 instruction);
+    std::string DLUI_48_(uint64 instruction);
+    std::string LDPC_48_(uint64 instruction);
+    std::string SDPC_48_(uint64 instruction);
+    std::string ORI(uint64 instruction);
+    std::string XORI(uint64 instruction);
+    std::string ANDI_32_(uint64 instruction);
+    std::string SAVE_32_(uint64 instruction);
+    std::string RESTORE_32_(uint64 instruction);
+    std::string RESTORE_JRC_32_(uint64 instruction);
+    std::string SAVEF(uint64 instruction);
+    std::string RESTOREF(uint64 instruction);
+    std::string SLTI(uint64 instruction);
+    std::string SLTIU(uint64 instruction);
+    std::string SEQI(uint64 instruction);
+    std::string ADDIU_NEG_(uint64 instruction);
+    std::string DADDIU_U12_(uint64 instruction);
+    std::string DADDIU_NEG_(uint64 instruction);
+    std::string DROTX(uint64 instruction);
+    std::string NOP_32_(uint64 instruction);
+    std::string EHB(uint64 instruction);
+    std::string PAUSE(uint64 instruction);
+    std::string SYNC(uint64 instruction);
+    std::string SLL_32_(uint64 instruction);
+    std::string SRL_32_(uint64 instruction);
+    std::string SRA(uint64 instruction);
+    std::string ROTR(uint64 instruction);
+    std::string DSLL(uint64 instruction);
+    std::string DSLL32(uint64 instruction);
+    std::string DSRL(uint64 instruction);
+    std::string DSRL32(uint64 instruction);
+    std::string DSRA(uint64 instruction);
+    std::string DSRA32(uint64 instruction);
+    std::string DROTR(uint64 instruction);
+    std::string DROTR32(uint64 instruction);
+    std::string ROTX(uint64 instruction);
+    std::string INS(uint64 instruction);
+    std::string DINSU(uint64 instruction);
+    std::string DINSM(uint64 instruction);
+    std::string DINS(uint64 instruction);
+    std::string EXT(uint64 instruction);
+    std::string DEXTU(uint64 instruction);
+    std::string DEXTM(uint64 instruction);
+    std::string DEXT(uint64 instruction);
+    std::string RINT_S(uint64 instruction);
+    std::string RINT_D(uint64 instruction);
+    std::string ADD_S(uint64 instruction);
+    std::string SELEQZ_S(uint64 instruction);
+    std::string SELEQZ_D(uint64 instruction);
+    std::string CLASS_S(uint64 instruction);
+    std::string CLASS_D(uint64 instruction);
+    std::string SUB_S(uint64 instruction);
+    std::string SELNEZ_S(uint64 instruction);
+    std::string SELNEZ_D(uint64 instruction);
+    std::string MUL_S(uint64 instruction);
+    std::string SEL_S(uint64 instruction);
+    std::string SEL_D(uint64 instruction);
+    std::string DIV_S(uint64 instruction);
+    std::string ADD_D(uint64 instruction);
+    std::string SUB_D(uint64 instruction);
+    std::string MUL_D(uint64 instruction);
+    std::string MADDF_S(uint64 instruction);
+    std::string MADDF_D(uint64 instruction);
+    std::string DIV_D(uint64 instruction);
+    std::string MSUBF_S(uint64 instruction);
+    std::string MSUBF_D(uint64 instruction);
+    std::string MIN_S(uint64 instruction);
+    std::string MIN_D(uint64 instruction);
+    std::string MAX_S(uint64 instruction);
+    std::string MAX_D(uint64 instruction);
+    std::string MINA_S(uint64 instruction);
+    std::string MINA_D(uint64 instruction);
+    std::string MAXA_S(uint64 instruction);
+    std::string MAXA_D(uint64 instruction);
+    std::string CVT_L_S(uint64 instruction);
+    std::string CVT_L_D(uint64 instruction);
+    std::string RSQRT_S(uint64 instruction);
+    std::string RSQRT_D(uint64 instruction);
+    std::string FLOOR_L_S(uint64 instruction);
+    std::string FLOOR_L_D(uint64 instruction);
+    std::string CVT_W_S(uint64 instruction);
+    std::string CVT_W_D(uint64 instruction);
+    std::string SQRT_S(uint64 instruction);
+    std::string SQRT_D(uint64 instruction);
+    std::string FLOOR_W_S(uint64 instruction);
+    std::string FLOOR_W_D(uint64 instruction);
+    std::string CFC1(uint64 instruction);
+    std::string RECIP_S(uint64 instruction);
+    std::string RECIP_D(uint64 instruction);
+    std::string CEIL_L_S(uint64 instruction);
+    std::string CEIL_L_D(uint64 instruction);
+    std::string CTC1(uint64 instruction);
+    std::string CEIL_W_S(uint64 instruction);
+    std::string CEIL_W_D(uint64 instruction);
+    std::string MFC1(uint64 instruction);
+    std::string CVT_S_PL(uint64 instruction);
+    std::string TRUNC_L_S(uint64 instruction);
+    std::string TRUNC_L_D(uint64 instruction);
+    std::string DMFC1(uint64 instruction);
+    std::string MTC1(uint64 instruction);
+    std::string CVT_S_PU(uint64 instruction);
+    std::string TRUNC_W_S(uint64 instruction);
+    std::string TRUNC_W_D(uint64 instruction);
+    std::string DMTC1(uint64 instruction);
+    std::string MFHC1(uint64 instruction);
+    std::string ROUND_L_S(uint64 instruction);
+    std::string ROUND_L_D(uint64 instruction);
+    std::string MTHC1(uint64 instruction);
+    std::string ROUND_W_S(uint64 instruction);
+    std::string ROUND_W_D(uint64 instruction);
+    std::string MOV_S(uint64 instruction);
+    std::string MOV_D(uint64 instruction);
+    std::string ABS_S(uint64 instruction);
+    std::string ABS_D(uint64 instruction);
+    std::string NEG_S(uint64 instruction);
+    std::string NEG_D(uint64 instruction);
+    std::string CVT_D_S(uint64 instruction);
+    std::string CVT_D_W(uint64 instruction);
+    std::string CVT_D_L(uint64 instruction);
+    std::string CVT_S_D(uint64 instruction);
+    std::string CVT_S_W(uint64 instruction);
+    std::string CVT_S_L(uint64 instruction);
+    std::string CMP_AF_S(uint64 instruction);
+    std::string CMP_UN_S(uint64 instruction);
+    std::string CMP_EQ_S(uint64 instruction);
+    std::string CMP_UEQ_S(uint64 instruction);
+    std::string CMP_LT_S(uint64 instruction);
+    std::string CMP_ULT_S(uint64 instruction);
+    std::string CMP_LE_S(uint64 instruction);
+    std::string CMP_ULE_S(uint64 instruction);
+    std::string CMP_SAF_S(uint64 instruction);
+    std::string CMP_SUN_S(uint64 instruction);
+    std::string CMP_SEQ_S(uint64 instruction);
+    std::string CMP_SUEQ_S(uint64 instruction);
+    std::string CMP_SLT_S(uint64 instruction);
+    std::string CMP_SULT_S(uint64 instruction);
+    std::string CMP_SLE_S(uint64 instruction);
+    std::string CMP_SULE_S(uint64 instruction);
+    std::string CMP_OR_S(uint64 instruction);
+    std::string CMP_UNE_S(uint64 instruction);
+    std::string CMP_NE_S(uint64 instruction);
+    std::string CMP_SOR_S(uint64 instruction);
+    std::string CMP_SUNE_S(uint64 instruction);
+    std::string CMP_SNE_S(uint64 instruction);
+    std::string CMP_AF_D(uint64 instruction);
+    std::string CMP_UN_D(uint64 instruction);
+    std::string CMP_EQ_D(uint64 instruction);
+    std::string CMP_UEQ_D(uint64 instruction);
+    std::string CMP_LT_D(uint64 instruction);
+    std::string CMP_ULT_D(uint64 instruction);
+    std::string CMP_LE_D(uint64 instruction);
+    std::string CMP_ULE_D(uint64 instruction);
+    std::string CMP_SAF_D(uint64 instruction);
+    std::string CMP_SUN_D(uint64 instruction);
+    std::string CMP_SEQ_D(uint64 instruction);
+    std::string CMP_SUEQ_D(uint64 instruction);
+    std::string CMP_SLT_D(uint64 instruction);
+    std::string CMP_SULT_D(uint64 instruction);
+    std::string CMP_SLE_D(uint64 instruction);
+    std::string CMP_SULE_D(uint64 instruction);
+    std::string CMP_OR_D(uint64 instruction);
+    std::string CMP_UNE_D(uint64 instruction);
+    std::string CMP_NE_D(uint64 instruction);
+    std::string CMP_SOR_D(uint64 instruction);
+    std::string CMP_SUNE_D(uint64 instruction);
+    std::string CMP_SNE_D(uint64 instruction);
+    std::string DLSA(uint64 instruction);
+    std::string DSLLV(uint64 instruction);
+    std::string DMUL(uint64 instruction);
+    std::string DSRLV(uint64 instruction);
+    std::string DMUH(uint64 instruction);
+    std::string DSRAV(uint64 instruction);
+    std::string DMULU(uint64 instruction);
+    std::string DROTRV(uint64 instruction);
+    std::string DMUHU(uint64 instruction);
+    std::string DADD(uint64 instruction);
+    std::string DDIV(uint64 instruction);
+    std::string DADDU(uint64 instruction);
+    std::string DMOD(uint64 instruction);
+    std::string DSUB(uint64 instruction);
+    std::string DDIVU(uint64 instruction);
+    std::string DSUBU(uint64 instruction);
+    std::string DMODU(uint64 instruction);
+    std::string EXTD(uint64 instruction);
+    std::string EXTD32(uint64 instruction);
+    std::string DCLO(uint64 instruction);
+    std::string DCLZ(uint64 instruction);
+    std::string LUI(uint64 instruction);
+    std::string ALUIPC(uint64 instruction);
+    std::string ADDIUPC_32_(uint64 instruction);
+    std::string LB_GP_(uint64 instruction);
+    std::string SB_GP_(uint64 instruction);
+    std::string LBU_GP_(uint64 instruction);
+    std::string ADDIU_GP_B_(uint64 instruction);
+    std::string LH_GP_(uint64 instruction);
+    std::string LHU_GP_(uint64 instruction);
+    std::string SH_GP_(uint64 instruction);
+    std::string LWC1_GP_(uint64 instruction);
+    std::string SWC1_GP_(uint64 instruction);
+    std::string LDC1_GP_(uint64 instruction);
+    std::string SDC1_GP_(uint64 instruction);
+    std::string LWU_GP_(uint64 instruction);
+    std::string LB_U12_(uint64 instruction);
+    std::string SB_U12_(uint64 instruction);
+    std::string LBU_U12_(uint64 instruction);
+    std::string PREF_U12_(uint64 instruction);
+    std::string LH_U12_(uint64 instruction);
+    std::string SH_U12_(uint64 instruction);
+    std::string LHU_U12_(uint64 instruction);
+    std::string LWU_U12_(uint64 instruction);
+    std::string LW_U12_(uint64 instruction);
+    std::string SW_U12_(uint64 instruction);
+    std::string LWC1_U12_(uint64 instruction);
+    std::string SWC1_U12_(uint64 instruction);
+    std::string LD_U12_(uint64 instruction);
+    std::string SD_U12_(uint64 instruction);
+    std::string LDC1_U12_(uint64 instruction);
+    std::string SDC1_U12_(uint64 instruction);
+    std::string LB_S9_(uint64 instruction);
+    std::string SB_S9_(uint64 instruction);
+    std::string LBU_S9_(uint64 instruction);
+    std::string SYNCI(uint64 instruction);
+    std::string PREF_S9_(uint64 instruction);
+    std::string LH_S9_(uint64 instruction);
+    std::string SH_S9_(uint64 instruction);
+    std::string LHU_S9_(uint64 instruction);
+    std::string LWU_S9_(uint64 instruction);
+    std::string LW_S9_(uint64 instruction);
+    std::string SW_S9_(uint64 instruction);
+    std::string LWC1_S9_(uint64 instruction);
+    std::string SWC1_S9_(uint64 instruction);
+    std::string LD_S9_(uint64 instruction);
+    std::string SD_S9_(uint64 instruction);
+    std::string LDC1_S9_(uint64 instruction);
+    std::string SDC1_S9_(uint64 instruction);
+    std::string ASET(uint64 instruction);
+    std::string ACLR(uint64 instruction);
+    std::string UALH(uint64 instruction);
+    std::string UASH(uint64 instruction);
+    std::string CACHE(uint64 instruction);
+    std::string LWC2(uint64 instruction);
+    std::string SWC2(uint64 instruction);
+    std::string LL(uint64 instruction);
+    std::string LLWP(uint64 instruction);
+    std::string SC(uint64 instruction);
+    std::string SCWP(uint64 instruction);
+    std::string LDC2(uint64 instruction);
+    std::string SDC2(uint64 instruction);
+    std::string LLD(uint64 instruction);
+    std::string LLDP(uint64 instruction);
+    std::string SCD(uint64 instruction);
+    std::string SCDP(uint64 instruction);
+    std::string LBE(uint64 instruction);
+    std::string SBE(uint64 instruction);
+    std::string LBUE(uint64 instruction);
+    std::string SYNCIE(uint64 instruction);
+    std::string PREFE(uint64 instruction);
+    std::string LHE(uint64 instruction);
+    std::string SHE(uint64 instruction);
+    std::string LHUE(uint64 instruction);
+    std::string CACHEE(uint64 instruction);
+    std::string LWE(uint64 instruction);
+    std::string SWE(uint64 instruction);
+    std::string LLE(uint64 instruction);
+    std::string LLWPE(uint64 instruction);
+    std::string SCE(uint64 instruction);
+    std::string SCWPE(uint64 instruction);
+    std::string LWM(uint64 instruction);
+    std::string SWM(uint64 instruction);
+    std::string UALWM(uint64 instruction);
+    std::string UASWM(uint64 instruction);
+    std::string LDM(uint64 instruction);
+    std::string SDM(uint64 instruction);
+    std::string UALDM(uint64 instruction);
+    std::string UASDM(uint64 instruction);
+    std::string MOVE_BALC(uint64 instruction);
+    std::string BC_32_(uint64 instruction);
+    std::string BALC_32_(uint64 instruction);
+    std::string JALRC_32_(uint64 instruction);
+    std::string JALRC_HB(uint64 instruction);
+    std::string BRSC(uint64 instruction);
+    std::string BALRSC(uint64 instruction);
+    std::string BEQC_32_(uint64 instruction);
+    std::string BC1EQZC(uint64 instruction);
+    std::string BC1NEZC(uint64 instruction);
+    std::string BC2EQZC(uint64 instruction);
+    std::string BC2NEZC(uint64 instruction);
+    std::string BPOSGE32C(uint64 instruction);
+    std::string BGEC(uint64 instruction);
+    std::string BGEUC(uint64 instruction);
+    std::string BNEC_32_(uint64 instruction);
+    std::string BLTC(uint64 instruction);
+    std::string BLTUC(uint64 instruction);
+    std::string BEQIC(uint64 instruction);
+    std::string BBEQZC(uint64 instruction);
+    std::string BGEIC(uint64 instruction);
+    std::string BGEIUC(uint64 instruction);
+    std::string BNEIC(uint64 instruction);
+    std::string BBNEZC(uint64 instruction);
+    std::string BLTIC(uint64 instruction);
+    std::string BLTIUC(uint64 instruction);
+    std::string SYSCALL_16_(uint64 instruction);
+    std::string HYPCALL_16_(uint64 instruction);
+    std::string BREAK_16_(uint64 instruction);
+    std::string SDBBP_16_(uint64 instruction);
+    std::string MOVE(uint64 instruction);
+    std::string SLL_16_(uint64 instruction);
+    std::string SRL_16_(uint64 instruction);
+    std::string NOT_16_(uint64 instruction);
+    std::string XOR_16_(uint64 instruction);
+    std::string AND_16_(uint64 instruction);
+    std::string OR_16_(uint64 instruction);
+    std::string LWXS_16_(uint64 instruction);
+    std::string ADDIU_R1_SP_(uint64 instruction);
+    std::string ADDIU_R2_(uint64 instruction);
+    std::string NOP_16_(uint64 instruction);
+    std::string ADDIU_RS5_(uint64 instruction);
+    std::string ADDU_16_(uint64 instruction);
+    std::string SUBU_16_(uint64 instruction);
+    std::string LI_16_(uint64 instruction);
+    std::string ANDI_16_(uint64 instruction);
+    std::string LW_16_(uint64 instruction);
+    std::string LW_SP_(uint64 instruction);
+    std::string LW_GP16_(uint64 instruction);
+    std::string LW_4X4_(uint64 instruction);
+    std::string SW_16_(uint64 instruction);
+    std::string SW_SP_(uint64 instruction);
+    std::string SW_GP16_(uint64 instruction);
+    std::string SW_4X4_(uint64 instruction);
+    std::string BC_16_(uint64 instruction);
+    std::string BALC_16_(uint64 instruction);
+    std::string BEQZC_16_(uint64 instruction);
+    std::string BNEZC_16_(uint64 instruction);
+    std::string JRC(uint64 instruction);
+    std::string JALRC_16_(uint64 instruction);
+    std::string BEQC_16_(uint64 instruction);
+    std::string BNEC_16_(uint64 instruction);
+    std::string SAVE_16_(uint64 instruction);
+    std::string RESTORE_JRC_16_(uint64 instruction);
+    std::string ADDU_4X4_(uint64 instruction);
+    std::string MUL_4X4_(uint64 instruction);
+    std::string LB_16_(uint64 instruction);
+    std::string SB_16_(uint64 instruction);
+    std::string LBU_16_(uint64 instruction);
+    std::string LH_16_(uint64 instruction);
+    std::string SH_16_(uint64 instruction);
+    std::string LHU_16_(uint64 instruction);
+    std::string MOVEP(uint64 instruction);
+    std::string MOVEP_REV_(uint64 instruction);
+
+    static Pool P_SYSCALL[2];
+    static Pool P_RI[4];
+    static Pool P_ADDIU[2];
+    static Pool P_TRAP[2];
+    static Pool P_CMOVE[2];
+    static Pool P_D_MT_VPE[2];
+    static Pool P_E_MT_VPE[2];
+    static Pool _P_MT_VPE[2];
+    static Pool P_MT_VPE[8];
+    static Pool P_DVP[2];
+    static Pool P_SLTU[2];
+    static Pool _POOL32A0[128];
+    static Pool ADDQ__S__PH[2];
+    static Pool MUL__S__PH[2];
+    static Pool ADDQH__R__PH[2];
+    static Pool ADDQH__R__W[2];
+    static Pool ADDU__S__QB[2];
+    static Pool ADDU__S__PH[2];
+    static Pool ADDUH__R__QB[2];
+    static Pool SHRAV__R__PH[2];
+    static Pool SHRAV__R__QB[2];
+    static Pool SUBQ__S__PH[2];
+    static Pool SUBQH__R__PH[2];
+    static Pool SUBQH__R__W[2];
+    static Pool SUBU__S__QB[2];
+    static Pool SUBU__S__PH[2];
+    static Pool SHRA__R__PH[2];
+    static Pool SUBUH__R__QB[2];
+    static Pool SHLLV__S__PH[2];
+    static Pool SHLL__S__PH[4];
+    static Pool PRECR_SRA__R__PH_W[2];
+    static Pool _POOL32A5[128];
+    static Pool PP_LSX[16];
+    static Pool PP_LSXS[16];
+    static Pool P_LSX[2];
+    static Pool POOL32Axf_1_0[4];
+    static Pool POOL32Axf_1_1[4];
+    static Pool POOL32Axf_1_3[4];
+    static Pool POOL32Axf_1_4[2];
+    static Pool MAQ_S_A__W_PHR[2];
+    static Pool MAQ_S_A__W_PHL[2];
+    static Pool POOL32Axf_1_5[2];
+    static Pool POOL32Axf_1_7[4];
+    static Pool POOL32Axf_1[8];
+    static Pool POOL32Axf_2_DSP__0_7[8];
+    static Pool POOL32Axf_2_DSP__8_15[8];
+    static Pool POOL32Axf_2_DSP__16_23[8];
+    static Pool POOL32Axf_2_DSP__24_31[8];
+    static Pool POOL32Axf_2[4];
+    static Pool POOL32Axf_4[128];
+    static Pool POOL32Axf_5_group0[32];
+    static Pool POOL32Axf_5_group1[32];
+    static Pool ERETx[2];
+    static Pool POOL32Axf_5_group3[32];
+    static Pool POOL32Axf_5[4];
+    static Pool SHRA__R__QB[2];
+    static Pool POOL32Axf_7[8];
+    static Pool POOL32Axf[8];
+    static Pool _POOL32A7[8];
+    static Pool P32A[8];
+    static Pool P_GP_D[2];
+    static Pool P_GP_W[4];
+    static Pool POOL48I[32];
+    static Pool PP_SR[4];
+    static Pool P_SR_F[8];
+    static Pool P_SR[2];
+    static Pool P_SLL[5];
+    static Pool P_SHIFT[16];
+    static Pool P_ROTX[4];
+    static Pool P_INS[4];
+    static Pool P_EXT[4];
+    static Pool P_U12[16];
+    static Pool RINT_fmt[2];
+    static Pool ADD_fmt0[2];
+    static Pool SELEQZ_fmt[2];
+    static Pool CLASS_fmt[2];
+    static Pool SUB_fmt0[2];
+    static Pool SELNEZ_fmt[2];
+    static Pool MUL_fmt0[2];
+    static Pool SEL_fmt[2];
+    static Pool DIV_fmt0[2];
+    static Pool ADD_fmt1[2];
+    static Pool SUB_fmt1[2];
+    static Pool MUL_fmt1[2];
+    static Pool MADDF_fmt[2];
+    static Pool DIV_fmt1[2];
+    static Pool MSUBF_fmt[2];
+    static Pool POOL32F_0[64];
+    static Pool MIN_fmt[2];
+    static Pool MAX_fmt[2];
+    static Pool MINA_fmt[2];
+    static Pool MAXA_fmt[2];
+    static Pool CVT_L_fmt[2];
+    static Pool RSQRT_fmt[2];
+    static Pool FLOOR_L_fmt[2];
+    static Pool CVT_W_fmt[2];
+    static Pool SQRT_fmt[2];
+    static Pool FLOOR_W_fmt[2];
+    static Pool RECIP_fmt[2];
+    static Pool CEIL_L_fmt[2];
+    static Pool CEIL_W_fmt[2];
+    static Pool TRUNC_L_fmt[2];
+    static Pool TRUNC_W_fmt[2];
+    static Pool ROUND_L_fmt[2];
+    static Pool ROUND_W_fmt[2];
+    static Pool POOL32Fxf_0[64];
+    static Pool MOV_fmt[4];
+    static Pool ABS_fmt[4];
+    static Pool NEG_fmt[4];
+    static Pool CVT_D_fmt[4];
+    static Pool CVT_S_fmt[4];
+    static Pool POOL32Fxf_1[32];
+    static Pool POOL32Fxf[4];
+    static Pool POOL32F_3[8];
+    static Pool CMP_condn_S[32];
+    static Pool CMP_condn_D[32];
+    static Pool POOL32F_5[8];
+    static Pool POOL32F[8];
+    static Pool POOL32S_0[64];
+    static Pool POOL32Sxf_4[128];
+    static Pool POOL32Sxf[8];
+    static Pool POOL32S_4[8];
+    static Pool POOL32S[8];
+    static Pool P_LUI[2];
+    static Pool P_GP_LH[2];
+    static Pool P_GP_SH[2];
+    static Pool P_GP_CP1[4];
+    static Pool P_GP_M64[4];
+    static Pool P_GP_BH[8];
+    static Pool P_LS_U12[16];
+    static Pool P_PREF_S9_[2];
+    static Pool P_LS_S0[16];
+    static Pool ASET_ACLR[2];
+    static Pool P_LL[4];
+    static Pool P_SC[4];
+    static Pool P_LLD[8];
+    static Pool P_SCD[8];
+    static Pool P_LS_S1[16];
+    static Pool P_PREFE[2];
+    static Pool P_LLE[4];
+    static Pool P_SCE[4];
+    static Pool P_LS_E0[16];
+    static Pool P_LS_WM[2];
+    static Pool P_LS_UAWM[2];
+    static Pool P_LS_DM[2];
+    static Pool P_LS_UADM[2];
+    static Pool P_LS_S9[8];
+    static Pool P_BAL[2];
+    static Pool P_BALRSC[2];
+    static Pool P_J[16];
+    static Pool P_BR3A[32];
+    static Pool P_BR1[4];
+    static Pool P_BR2[4];
+    static Pool P_BRI[8];
+    static Pool P32[32];
+    static Pool P16_SYSCALL[2];
+    static Pool P16_RI[4];
+    static Pool P16_MV[2];
+    static Pool P16_SHIFT[2];
+    static Pool POOL16C_00[4];
+    static Pool POOL16C_0[2];
+    static Pool P16C[2];
+    static Pool P16_A1[2];
+    static Pool P_ADDIU_RS5_[2];
+    static Pool P16_A2[2];
+    static Pool P16_ADDU[2];
+    static Pool P16_JRC[2];
+    static Pool P16_BR1[2];
+    static Pool P16_BR[2];
+    static Pool P16_SR[2];
+    static Pool P16_4X4[4];
+    static Pool P16_LB[4];
+    static Pool P16_LH[4];
+    static Pool P16[32];
+    static Pool MAJOR[2];
+
+
+};
+
+#endif
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 1f69a6e..4c41e9c 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -387,6 +387,7 @@ typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
 int print_insn_tci(bfd_vma, disassemble_info*);
 int print_insn_big_mips         (bfd_vma, disassemble_info*);
 int print_insn_little_mips      (bfd_vma, disassemble_info*);
+int print_insn_micromips        (bfd_vma, disassemble_info*);
 int print_insn_i386             (bfd_vma, disassemble_info*);
 int print_insn_m68k             (bfd_vma, disassemble_info*);
 int print_insn_z8001            (bfd_vma, disassemble_info*);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 497706b..f309eb9 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -113,11 +113,19 @@ static void mips_cpu_reset(CPUState *s)
 }
 
 static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info) {
+    MIPSCPU *cpu = MIPS_CPU(s);
+    CPUMIPSState *env = &cpu->env;
+
+    if (!(env->hflags & MIPS_HFLAG_M16) &&
+        !(env->insn_flags & ISA_NANOMIPS32)) {
 #ifdef TARGET_WORDS_BIGENDIAN
-    info->print_insn = print_insn_big_mips;
+        info->print_insn = print_insn_big_mips;
 #else
-    info->print_insn = print_insn_little_mips;
+        info->print_insn = print_insn_little_mips;
 #endif
+    } else {
+        info->print_insn = print_insn_micromips;
+    }
 }
 
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (50 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 51/87] disas: Add support for microMIPS and nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 13:01   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 53/87] target/mips: Add updating BadInstr, BadInstrP, BadInstrX " Aleksandar Markovic
                   ` (36 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Matthew Fortune <matthew.fortune@mips.com>

ISA mode bit (LSB of address) is no longer required but is also
masked to allow for tools transition. The flag has_isa_mode has the
key role in the implementation.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 3282fca..e4427e4 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1471,6 +1471,7 @@ typedef struct DisasContext {
     bool mrp;
     bool nan2008;
     bool abs2008;
+    bool has_isa_mode;
 } DisasContext;
 
 #define DISAS_STOP       DISAS_TARGET_0
@@ -4674,7 +4675,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
 
     if (blink > 0) {
         int post_delay = insn_bytes + delayslot_size;
-        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
+        int lowbit = ctx->has_isa_mode && !!(ctx->hflags & MIPS_HFLAG_M16);
 
         tcg_gen_movi_tl(cpu_gpr[blink],
                         ctx->base.pc_next + post_delay + lowbit);
@@ -11171,7 +11172,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
     int bcond_compute = 0;
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
-    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
+    int m16_lowbit = ctx->has_isa_mode && ((ctx->hflags & MIPS_HFLAG_M16) != 0);
 
     if (ctx->hflags & MIPS_HFLAG_BMASK) {
 #ifdef MIPS_DEBUG_DISAS
@@ -24970,6 +24971,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
+    ctx->has_isa_mode = ((env->CP0_Config3 >> CP0C3_MMAR) & 0x7) < 3;
     restore_cpu_state(env, ctx);
 #ifdef CONFIG_USER_ONLY
         ctx->mem_idx = MIPS_HFLAG_UM;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 53/87] target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (51 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() " Aleksandar Markovic
                   ` (35 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Update BadInstr, BadInstrP,and BadInstrX registers for nanoMIPS.
The same support for pre-nanoMIPS remains unimplemented.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/helper.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index e215af9..b25e000 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -682,6 +682,31 @@ static void set_hflags_for_handler (CPUMIPSState *env)
 
 static inline void set_badinstr_registers(CPUMIPSState *env)
 {
+    if (env->insn_flags & ISA_NANOMIPS32) {
+        if (env->CP0_Config3 & (1 << CP0C3_BI)) {
+            uint32_t instr = (cpu_lduw_code(env, env->active_tc.PC)) << 16;
+            if ((instr & 0x10000000) == 0) {
+                instr |= cpu_lduw_code(env, env->active_tc.PC + 2);
+            }
+            env->CP0_BadInstr = instr;
+
+            if ((instr & 0xFC000000) == 0x60000000) {
+                instr = cpu_lduw_code(env, env->active_tc.PC + 4) << 16;
+                env->CP0_BadInstrX = instr;
+            }
+        }
+        if ((env->CP0_Config3 & (1 << CP0C3_BP)) &&
+            (env->hflags & MIPS_HFLAG_BMASK)) {
+            if (!(env->hflags & MIPS_HFLAG_B16)) {
+                env->CP0_BadInstrP = cpu_ldl_code(env, env->active_tc.PC - 4);
+            } else {
+                env->CP0_BadInstrP =
+                    (cpu_lduw_code(env, env->active_tc.PC - 2)) << 16;
+            }
+        }
+        return;
+    }
+
     if (env->hflags & MIPS_HFLAG_M16) {
         /* TODO: add BadInstr support for microMIPS */
         return;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (52 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 53/87] target/mips: Add updating BadInstr, BadInstrP, BadInstrX " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:56   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() " Aleksandar Markovic
                   ` (34 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: James Hogan <james.hogan@mips.com>

We shouldn't set the ISA bit in CP0_EPC for nanoMIPS.

Signed-off-by: James Hogan <james.hogan@mips.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index b25e000..b429671 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -656,7 +656,8 @@ target_ulong exception_resume_pc (CPUMIPSState *env)
     target_ulong bad_pc;
     target_ulong isa_mode;
 
-    isa_mode = !!(env->hflags & MIPS_HFLAG_M16);
+    isa_mode = env->hflags & MIPS_HFLAG_M16 &&
+                !(env->insn_flags & ISA_NANOMIPS32);
     bad_pc = env->active_tc.PC | isa_mode;
     if (env->hflags & MIPS_HFLAG_BMASK) {
         /* If the exception was raised from a delay slot, come back to
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (53 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:05   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 56/87] target/mips: Adjust set_pc() " Aleksandar Markovic
                   ` (33 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: James Hogan <james.hogan@mips.com>

We shouldn't clear M16 mode when entering an interrupt on nanoMIPS,
otherwise we'll start interpreting the code as normal MIPS code.

Signed-off-by: James Hogan <james.hogan@mips.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index b429671..0c15e65 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -671,6 +671,9 @@ target_ulong exception_resume_pc (CPUMIPSState *env)
 #if !defined(CONFIG_USER_ONLY)
 static void set_hflags_for_handler (CPUMIPSState *env)
 {
+    if (env->insn_flags & ISA_NANOMIPS32) {
+        return;
+    }
     /* Exception handlers are entered in 32-bit mode.  */
     env->hflags &= ~(MIPS_HFLAG_M16);
     /* ...except that microMIPS lets you choose.  */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 56/87] target/mips: Adjust set_pc() for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (54 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 57/87] target/mips: Fix ERET/ERETNC behavior related to ADEL exception Aleksandar Markovic
                   ` (32 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: James Hogan <james.hogan@mips.com>

ERET and ERETNC shouldn't clear MIPS_HFLAG_M16 for nanoMIPS since there
is no ISA bit, so fix set_pc() to skip the hflags update.

Signed-off-by: James Hogan <james.hogan@mips.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
---
 target/mips/op_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index b3eef9f..53c1eea 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2392,6 +2392,9 @@ static void debug_post_eret(CPUMIPSState *env)
 static void set_pc(CPUMIPSState *env, target_ulong error_pc)
 {
     env->active_tc.PC = error_pc & ~(target_ulong)1;
+    if (env->insn_flags & ISA_NANOMIPS32) {
+        return;
+    }
     if (error_pc & 1) {
         env->hflags |= MIPS_HFLAG_M16;
     } else {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 57/87] target/mips: Fix ERET/ERETNC behavior related to ADEL exception
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (55 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 56/87] target/mips: Adjust set_pc() " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field Aleksandar Markovic
                   ` (31 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Yongbok Kim <yongbok.kim@mips.com>

Fix ERET/ERETNC so that ADEL exception can be raised.

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/op_helper.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 53c1eea..65935e7 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2430,10 +2430,12 @@ void helper_eretnc(CPUMIPSState *env)
 void helper_deret(CPUMIPSState *env)
 {
     debug_pre_eret(env);
-    set_pc(env, env->CP0_DEPC);
 
     env->hflags &= ~MIPS_HFLAG_DM;
     compute_hflags(env);
+
+    set_pc(env, env->CP0_DEPC);
+
     debug_post_eret(env);
 }
 #endif /* !CONFIG_USER_ONLY */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (56 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 57/87] target/mips: Fix ERET/ERETNC behavior related to ADEL exception Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:55   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 59/87] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too Aleksandar Markovic
                   ` (30 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Value 249 is registered as valid for usage for nanoMIPS executables.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 include/elf.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index 28a5a63..312f68a 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -143,6 +143,8 @@ typedef int64_t  Elf64_Sxword;
 
 #define EM_RISCV        243     /* RISC-V */
 
+#define EM_NANOMIPS     249     /* Wave Computing nanoMIPS */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 59/87] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (57 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS Aleksandar Markovic
                   ` (29 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Starting from nanoMIPS introduction, machine variant can be
EM_MIPS or EM_NANOMIPS.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/elfload.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index df07055..8638612 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -853,6 +853,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
 #endif
 #define ELF_ARCH    EM_MIPS
 
+#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_NANOMIPS)
+
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
 {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (58 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 59/87] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS Aleksandar Markovic
                   ` (28 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

nanoMIPS is always NaN2008 compliant, and rules for checking
FCR31's NAN2008 bit are obsoleted.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/cpu_loop.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 1d3dc9e..c9c20cf 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -747,6 +747,9 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
     if (regs->cp0_epc & 1) {
         env->hflags |= MIPS_HFLAG_M16;
     }
+    if (env->insn_flags & ISA_NANOMIPS32) {
+        return;
+    }
     if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
         ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
         if ((env->active_fpu.fcr31_rw_bitmask &
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (59 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:28   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board Aleksandar Markovic
                   ` (27 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Modify load_elf32()/load_elf64() to treat EM_NANOMIPS as equal to
EM_MIPS.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 include/hw/elf_ops.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index b6e19e3..81cecaf 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -327,6 +327,14 @@ static int glue(load_elf, SZ)(const char *name, int fd,
                 }
             }
             break;
+        case EM_MIPS:
+        case EM_NANOMIPS:
+            if ((ehdr.e_machine != EM_MIPS) &&
+                (ehdr.e_machine != EM_NANOMIPS)) {
+                ret = ELF_LOAD_WRONG_ARCH;
+                goto fail;
+            }
+            break;
         default:
             if (elf_machine != ehdr.e_machine) {
                 ret = ELF_LOAD_WRONG_ARCH;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (60 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 11:59   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 63/87] mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader Aleksandar Markovic
                   ` (26 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Matthew Fortune <matthew.fortune@mips.com>

Add basic nanoMIPS boot code for Malta.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 hw/mips/mips_malta.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 3 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 3467451..2e851d9 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -599,6 +599,59 @@ static void network_init(PCIBus *pci_bus)
     }
 }
 
+static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr,
+                                      int64_t kernel_entry)
+{
+    uint16_t *p;
+
+    /* Small bootloader */
+    p = (uint16_t *)base;
+
+#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f)
+#define NM_HI2(VAL) \
+            (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1))
+#define NM_LO(VAL)  ((VAL) & 0xfff)
+
+    stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+
+    /* to_here: */
+    stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */
+    stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64));
+    stw_p(p++, NM_HI2(ENVP_ADDR - 64));
+                                /* lui sp,%hi(ENVP_ADDR - 64) */
+    stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64));
+                                /* ori sp,sp,%lo(ENVP_ADDR - 64) */
+    stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR));
+    stw_p(p++, NM_HI2(ENVP_ADDR));
+                                /* lui a1,%hi(ENVP_ADDR) */
+    stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR));
+                                /* ori a1,a1,%lo(ENVP_ADDR) */
+    stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8));
+    stw_p(p++, NM_HI2(ENVP_ADDR + 8));
+                                /* lui a2,%hi(ENVP_ADDR + 8) */
+    stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8));
+                                /* ori a2,a2,%lo(ENVP_ADDR + 8) */
+    stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size));
+    stw_p(p++, NM_HI2(loaderparams.ram_low_size));
+                                /* lui a3,%hi(loaderparams.ram_low_size) */
+    stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size));
+                                /* ori a3,a3,%lo(loaderparams.ram_low_size) */
+    stw_p(p++, 0xe320 | NM_HI1(kernel_entry));
+    stw_p(p++, NM_HI2(kernel_entry));
+                                /* lui t9,%hi(kernel_entry) */
+    stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry));
+                                /* ori t9,t9,%lo(kernel_entry) */
+    stw_p(p++, 0x4bf9); stw_p(p++, 0x0000);
+                                /* jalrc   t8 */
+}
+
 /* ROM and pseudo bootloader
 
    The following code implements a very very simple bootloader. It first
@@ -620,7 +673,6 @@ static void network_init(PCIBus *pci_bus)
      a2 - 32-bit address of the environment variables table
      a3 - RAM size in bytes
 */
-
 static void write_bootloader(uint8_t *base, int64_t run_addr,
                              int64_t kernel_entry)
 {
@@ -1096,8 +1148,13 @@ void mips_malta_init(MachineState *machine)
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
 
-        write_bootloader(memory_region_get_ram_ptr(bios),
-                         bootloader_run_addr, kernel_entry);
+        if (!cpu_supports_isa(machine->cpu_type, ISA_NANOMIPS32)) {
+            write_bootloader(memory_region_get_ram_ptr(bios),
+                             bootloader_run_addr, kernel_entry);
+        } else {
+            write_bootloader_nanomips(memory_region_get_ram_ptr(bios),
+                                      bootloader_run_addr, kernel_entry);
+        }
         if (kvm_enabled()) {
             /* Write the bootloader code @ the end of RAM, 1MB reserved */
             write_bootloader(memory_region_get_ram_ptr(ram_low_preio) +
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 63/87] mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (61 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 64/87] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal Aleksandar Markovic
                   ` (25 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Paul Burton <pburton@wavecomp.com>

Setup the GT64120 BARs in the nanoMIPS bootloader, in the same way that
they are setup in the MIPS32 bootloader. This is necessary for Linux to
be able to access peripherals, including the UART.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Paul Burton <pburton@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 hw/mips/mips_malta.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 160 insertions(+), 17 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2e851d9..f261dd6 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -609,47 +609,190 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr,
 
 #define NM_HI1(VAL) (((VAL) >> 16) & 0x1f)
 #define NM_HI2(VAL) \
-            (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1))
+          (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1))
 #define NM_LO(VAL)  ((VAL) & 0xfff)
 
-    stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
-    stw_p(p++, 0x8000); stw_p(p++, 0xc000); /* nop */
+    stw_p(p++, 0x2800); stw_p(p++, 0x001c);
+                                /* bc to_here */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
+    stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop */
 
     /* to_here: */
-    stw_p(p++, 0x0080); stw_p(p++, 0x0002); /* li a0,2 */
+    stw_p(p++, 0x0080); stw_p(p++, 0x0002);
+                                /* li a0,2                      */
+
     stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64));
+
     stw_p(p++, NM_HI2(ENVP_ADDR - 64));
-                                /* lui sp,%hi(ENVP_ADDR - 64) */
+                                /* lui sp,%hi(ENVP_ADDR - 64)   */
+
     stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_ADDR - 64));
                                 /* ori sp,sp,%lo(ENVP_ADDR - 64) */
+
     stw_p(p++, 0xe0a0 | NM_HI1(ENVP_ADDR));
+
     stw_p(p++, NM_HI2(ENVP_ADDR));
-                                /* lui a1,%hi(ENVP_ADDR) */
+                                /* lui a1,%hi(ENVP_ADDR)        */
+
     stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_ADDR));
-                                /* ori a1,a1,%lo(ENVP_ADDR) */
+                                /* ori a1,a1,%lo(ENVP_ADDR)     */
+
     stw_p(p++, 0xe0c0 | NM_HI1(ENVP_ADDR + 8));
+
     stw_p(p++, NM_HI2(ENVP_ADDR + 8));
-                                /* lui a2,%hi(ENVP_ADDR + 8) */
+                                /* lui a2,%hi(ENVP_ADDR + 8)    */
+
     stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_ADDR + 8));
                                 /* ori a2,a2,%lo(ENVP_ADDR + 8) */
+
     stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size));
+
     stw_p(p++, NM_HI2(loaderparams.ram_low_size));
                                 /* lui a3,%hi(loaderparams.ram_low_size) */
+
     stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size));
                                 /* ori a3,a3,%lo(loaderparams.ram_low_size) */
+
+    /*
+     * Load BAR registers as done by YAMON:
+     *
+     *  - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff
+     *  - set up PCI0 MEM0 at 0x10000000, size 0x8000000
+     *  - set up PCI0 MEM1 at 0x18200000, size 0xbe00000
+     *
+     */
+    stw_p(p++, 0xe040); stw_p(p++, 0x0681);
+                                /* lui t1, %hi(0xb4000000)      */
+
+#ifdef TARGET_WORDS_BIGENDIAN
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0be1);
+                                /* lui t0, %hi(0xdf000000)      */
+
+    /* 0x68 corresponds to GT_ISD (from hw/mips/gt64xxx_pci.c)  */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9068);
+                                /* sw t0, 0x68(t1)              */
+
+    stw_p(p++, 0xe040); stw_p(p++, 0x077d);
+                                /* lui t1, %hi(0xbbe00000)      */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0801);
+                                /* lui t0, %hi(0xc0000000)      */
+
+    /* 0x48 corresponds to GT_PCI0IOLD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9048);
+                                /* sw t0, 0x48(t1)              */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0800);
+                                /* lui t0, %hi(0x40000000)      */
+
+    /* 0x50 corresponds to GT_PCI0IOHD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9050);
+                                /* sw t0, 0x50(t1)              */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0001);
+                                /* lui t0, %hi(0x80000000)      */
+
+    /* 0x58 corresponds to GT_PCI0M0LD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9058);
+                                /* sw t0, 0x58(t1)              */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x07e0);
+                                /* lui t0, %hi(0x3f000000)      */
+
+    /* 0x60 corresponds to GT_PCI0M0HD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9060);
+                                /* sw t0, 0x60(t1)              */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0821);
+                                /* lui t0, %hi(0xc1000000)      */
+
+    /* 0x80 corresponds to GT_PCI0M1LD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9080);
+                                /* sw t0, 0x80(t1)              */
+
+    stw_p(p++, 0xe020); stw_p(p++, 0x0bc0);
+                                /* lui t0, %hi(0x5e000000)      */
+
+#else
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x00df);
+                                /* addiu[32] t0, $0, 0xdf       */
+
+    /* 0x68 corresponds to GT_ISD                               */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9068);
+                                /* sw t0, 0x68(t1)              */
+
+    /* Use kseg2 remapped address 0x1be00000                    */
+    stw_p(p++, 0xe040); stw_p(p++, 0x077d);
+                                /* lui t1, %hi(0xbbe00000)      */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x00c0);
+                                /* addiu[32] t0, $0, 0xc0       */
+
+    /* 0x48 corresponds to GT_PCI0IOLD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9048);
+                                /* sw t0, 0x48(t1)              */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x0040);
+                                /* addiu[32] t0, $0, 0x40       */
+
+    /* 0x50 corresponds to GT_PCI0IOHD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9050);
+                                /* sw t0, 0x50(t1)              */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x0080);
+                                /* addiu[32] t0, $0, 0x80       */
+
+    /* 0x58 corresponds to GT_PCI0M0LD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9058);
+                                /* sw t0, 0x58(t1)              */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x003f);
+                                /* addiu[32] t0, $0, 0x3f       */
+
+    /* 0x60 corresponds to GT_PCI0M0HD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9060);
+                                /* sw t0, 0x60(t1)              */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x00c1);
+                                /* addiu[32] t0, $0, 0xc1       */
+
+    /* 0x80 corresponds to GT_PCI0M1LD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9080);
+                                /* sw t0, 0x80(t1)              */
+
+    stw_p(p++, 0x0020); stw_p(p++, 0x005e);
+                                /* addiu[32] t0, $0, 0x5e       */
+
+#endif
+
+    /* 0x88 corresponds to GT_PCI0M1HD                          */
+    stw_p(p++, 0x8422); stw_p(p++, 0x9088);
+                                /* sw t0, 0x88(t1)              */
+
     stw_p(p++, 0xe320 | NM_HI1(kernel_entry));
+
     stw_p(p++, NM_HI2(kernel_entry));
-                                /* lui t9,%hi(kernel_entry) */
+                                /* lui t9,%hi(kernel_entry)     */
+
     stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry));
-                                /* ori t9,t9,%lo(kernel_entry) */
+                                /* ori t9,t9,%lo(kernel_entry)  */
+
     stw_p(p++, 0x4bf9); stw_p(p++, 0x0000);
-                                /* jalrc   t8 */
+                                /* jalrc   t8                   */
 }
 
 /* ROM and pseudo bootloader
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 64/87] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (62 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 63/87] mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU Aleksandar Markovic
                   ` (24 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Fix passing argument for nanoMIPS bare metal related to the
semihosting regime.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 hw/mips/mips_malta.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index f261dd6..40041d5 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -630,8 +630,14 @@ static void write_bootloader_nanomips(uint8_t *base, int64_t run_addr,
                                 /* nop */
 
     /* to_here: */
-    stw_p(p++, 0x0080); stw_p(p++, 0x0002);
+    if (semihosting_get_argc()) {
+        /* Preserve a0 content as arguments have been passed    */
+        stw_p(p++, 0x8000); stw_p(p++, 0xc000);
+                                /* nop                          */
+    } else {
+        stw_p(p++, 0x0080); stw_p(p++, 0x0002);
                                 /* li a0,2                      */
+    }
 
     stw_p(p++, 0xe3a0 | NM_HI1(ENVP_ADDR - 64));
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (63 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 64/87] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-16 12:26   ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields Aleksandar Markovic
                   ` (23 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add definition of the first nanoMIPS processor in QEMU.

Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/translate_init.inc.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index c7ba6ee..b3320b9 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -449,6 +449,45 @@ const mips_def_t mips_defs[] =
         .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
         .mmu_type = MMU_TYPE_R4000,
     },
+    {
+        .name = "I7200",
+        .CP0_PRid = 0x00010000,
+        .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) |
+                        (MMU_TYPE_R4000 << CP0C0_MT),
+        .CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) |
+                       (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) |
+                       (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) |
+                       (1 << CP0C1_EP),
+        .CP0_Config2 = MIPS_CONFIG2,
+        .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) |
+                       (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) |
+                       (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) |
+                       (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) |
+                       (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) |
+                       (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) |
+                       (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL),
+        .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
+                       (2 << CP0C4_IE) | (1U << CP0C4_M),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB),
+        .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
+                                  (1 << CP0C5_UFE),
+        .CP0_LLAddr_rw_bitmask = 0,
+        .CP0_LLAddr_shift = 0,
+        .SYNCI_Step = 32,
+        .CCRes = 2,
+        .CP0_Status_rw_bitmask = 0x3158FF1F,
+        .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
+                         (1U << CP0PG_RIE),
+        .CP0_PageGrain_rw_bitmask = 0,
+        .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
+                    (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
+                    (1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV),
+        .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
+        .SEGBITS = 32,
+        .PABITS = 32,
+        .insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_MT,
+        .mmu_type = MMU_TYPE_R4000,
+    },
 #if defined(TARGET_MIPS64)
     {
         .name = "R4000",
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (64 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS Aleksandar Markovic
                   ` (22 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add nanoMIPS-related values in ELF header fields as specified in
nanoMIPS' "ELF ABI Supplement".

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 include/elf.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index 312f68a..341960c 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -62,6 +62,24 @@ typedef int64_t  Elf64_Sxword;
 #define EF_MIPS_FP64      0x00000200
 #define EF_MIPS_NAN2008   0x00000400
 
+/* nanoMIPS architecture bits, EF_NANOMIPS_ARCH */
+#define EF_NANOMIPS_ARCH_32R6 0x00000000  /* 32-bit nanoMIPS Release 6 ISA   */
+#define EF_NANOMIPS_ARCH_64R6 0x10000000  /* 62-bit nanoMIPS Release 6 ISA   */
+
+/* nanoMIPS ABI bits, EF_NANOMIPS_ABI */
+#define EF_NANOMIPS_ABI_P32   0x00001000  /* 32-bit nanoMIPS ABI             */
+#define EF_NANOMIPS_ABI_P64   0x00002000  /* 64-bit nanoMIPS ABI             */
+
+/* nanoMIPS processor specific flags, e_flags */
+#define EF_NANOMIPS_LINKRELAX 0x00000001  /* Link-time relaxation            */
+#define EF_NANOMIPS_PIC       0x00000002  /* Position independent code       */
+#define EF_NANOMIPS_32BITMODE 0x00000004  /* 32-bit object for 64-bit arch.  */
+#define EF_NANOMIPS_PID       0x00000008  /* Position independent data       */
+#define EF_NANOMIPS_PCREL     0x00000010  /* PC-relative mode                */
+#define EF_NANOMIPS_ABI       0x0000f000  /* nanoMIPS ABI                    */
+#define EF_NANOMIPS_MACH      0x00ff0000  /* Machine variant                 */
+#define EF_NANOMIPS_ARCH      0xf0000000  /* nanoMIPS architecture           */
+
 /* MIPS machine variant */
 #define EF_MIPS_MACH_NONE     0x00000000  /* A standard MIPS implementation  */
 #define EF_MIPS_MACH_3900     0x00810000  /* Toshiba R3900                   */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (65 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 68/87] linux-user: Add target_signal.h header " Aleksandar Markovic
                   ` (21 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add syscall numbers for nanoMIPS. nanoMIPS redefines its ABI
compared to preceding MIPS architectures, and its set of
supported system calls is significantly different.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/syscall_nr.h | 275 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 275 insertions(+)
 create mode 100644 linux-user/nanomips/syscall_nr.h

diff --git a/linux-user/nanomips/syscall_nr.h b/linux-user/nanomips/syscall_nr.h
new file mode 100644
index 0000000..b826e5c
--- /dev/null
+++ b/linux-user/nanomips/syscall_nr.h
@@ -0,0 +1,275 @@
+/*
+ * Linux mipsp32 style syscalls.
+ */
+#define TARGET_NR_io_setup                   0
+#define TARGET_NR_io_destroy                 1
+#define TARGET_NR_io_submit                  2
+#define TARGET_NR_io_cancel                  3
+#define TARGET_NR_io_getevents               4
+#define TARGET_NR_setxattr                   5
+#define TARGET_NR_lsetxattr                  6
+#define TARGET_NR_fsetxattr                  7
+#define TARGET_NR_getxattr                   8
+#define TARGET_NR_lgetxattr                  9
+#define TARGET_NR_fgetxattr                  10
+#define TARGET_NR_listxattr                  11
+#define TARGET_NR_llistxattr                 12
+#define TARGET_NR_flistxattr                 13
+#define TARGET_NR_removexattr                14
+#define TARGET_NR_lremovexattr               15
+#define TARGET_NR_fremovexattr               16
+#define TARGET_NR_getcwd                     17
+#define TARGET_NR_lookup_dcookie             18
+#define TARGET_NR_eventfd2                   19
+#define TARGET_NR_epoll_create1              20
+#define TARGET_NR_epoll_ctl                  21
+#define TARGET_NR_epoll_pwait                22
+#define TARGET_NR_dup                        23
+#define TARGET_NR_dup3                       24
+#define TARGET_NR_fcntl64                    25
+#define TARGET_NR_inotify_init1              26
+#define TARGET_NR_inotify_add_watch          27
+#define TARGET_NR_inotify_rm_watch           28
+#define TARGET_NR_ioctl                      29
+#define TARGET_NR_ioprio_set                 30
+#define TARGET_NR_ioprio_get                 31
+#define TARGET_NR_flock                      32
+#define TARGET_NR_mknodat                    33
+#define TARGET_NR_mkdirat                    34
+#define TARGET_NR_unlinkat                   35
+#define TARGET_NR_symlinkat                  36
+#define TARGET_NR_linkat                     37
+#define TARGET_NR_umount2                    39
+#define TARGET_NR_mount                      40
+#define TARGET_NR_pivot_root                 41
+#define TARGET_NR_nfsservctl                 42
+#define TARGET_NR_statfs64                   43
+#define TARGET_NR_fstatfs64                  44
+#define TARGET_NR_truncate64                 45
+#define TARGET_NR_ftruncate64                46
+#define TARGET_NR_fallocate                  47
+#define TARGET_NR_faccessat                  48
+#define TARGET_NR_chdir                      49
+#define TARGET_NR_fchdir                     50
+#define TARGET_NR_chroot                     51
+#define TARGET_NR_fchmod                     52
+#define TARGET_NR_fchmodat                   53
+#define TARGET_NR_fchownat                   54
+#define TARGET_NR_fchown                     55
+#define TARGET_NR_openat                     56
+#define TARGET_NR_close                      57
+#define TARGET_NR_vhangup                    58
+#define TARGET_NR_pipe2                      59
+#define TARGET_NR_quotactl                   60
+#define TARGET_NR_getdents64                 61
+#define TARGET_NR__llseek                    62
+#define TARGET_NR_read                       63
+#define TARGET_NR_write                      64
+#define TARGET_NR_readv                      65
+#define TARGET_NR_writev                     66
+#define TARGET_NR_pread64                    67
+#define TARGET_NR_pwrite64                   68
+#define TARGET_NR_preadv                     69
+#define TARGET_NR_pwritev                    70
+#define TARGET_NR_sendfile64                 71
+#define TARGET_NR_pselect6                   72
+#define TARGET_NR_ppoll                      73
+#define TARGET_NR_signalfd4                  74
+#define TARGET_NR_vmsplice                   75
+#define TARGET_NR_splice                     76
+#define TARGET_NR_tee                        77
+#define TARGET_NR_readlinkat                 78
+#define TARGET_NR_sync                       81
+#define TARGET_NR_fsync                      82
+#define TARGET_NR_fdatasync                  83
+#define TARGET_NR_sync_file_range2           84
+#define TARGET_NR_timerfd_create             85
+#define TARGET_NR_timerfd_settime            86
+#define TARGET_NR_timerfd_gettime            87
+#define TARGET_NR_utimensat                  88
+#define TARGET_NR_acct                       89
+#define TARGET_NR_capget                     90
+#define TARGET_NR_capset                     91
+#define TARGET_NR_personality                92
+#define TARGET_NR_exit                       93
+#define TARGET_NR_exit_group                 94
+#define TARGET_NR_waitid                     95
+#define TARGET_NR_set_tid_address            96
+#define TARGET_NR_unshare                    97
+#define TARGET_NR_futex                      98
+#define TARGET_NR_set_robust_list            99
+#define TARGET_NR_get_robust_list            100
+#define TARGET_NR_nanosleep                  101
+#define TARGET_NR_getitimer                  102
+#define TARGET_NR_setitimer                  103
+#define TARGET_NR_kexec_load                 104
+#define TARGET_NR_init_module                105
+#define TARGET_NR_delete_module              106
+#define TARGET_NR_timer_create               107
+#define TARGET_NR_timer_gettime              108
+#define TARGET_NR_timer_getoverrun           109
+#define TARGET_NR_timer_settime              110
+#define TARGET_NR_timer_delete               111
+#define TARGET_NR_clock_settime              112
+#define TARGET_NR_clock_gettime              113
+#define TARGET_NR_clock_getres               114
+#define TARGET_NR_clock_nanosleep            115
+#define TARGET_NR_syslog                     116
+#define TARGET_NR_ptrace                     117
+#define TARGET_NR_sched_setparam             118
+#define TARGET_NR_sched_setscheduler         119
+#define TARGET_NR_sched_getscheduler         120
+#define TARGET_NR_sched_getparam             121
+#define TARGET_NR_sched_setaffinity          122
+#define TARGET_NR_sched_getaffinity          123
+#define TARGET_NR_sched_yield                124
+#define TARGET_NR_sched_get_priority_max     125
+#define TARGET_NR_sched_get_priority_min     126
+#define TARGET_NR_sched_rr_get_interval      127
+#define TARGET_NR_restart_syscall            128
+#define TARGET_NR_kill                       129
+#define TARGET_NR_tkill                      130
+#define TARGET_NR_tgkill                     131
+#define TARGET_NR_sigaltstack                132
+#define TARGET_NR_rt_sigsuspend              133
+#define TARGET_NR_rt_sigaction               134
+#define TARGET_NR_rt_sigprocmask             135
+#define TARGET_NR_rt_sigpending              136
+#define TARGET_NR_rt_sigtimedwait            137
+#define TARGET_NR_rt_sigqueueinfo            138
+#define TARGET_NR_rt_sigreturn               139
+#define TARGET_NR_setpriority                140
+#define TARGET_NR_getpriority                141
+#define TARGET_NR_reboot                     142
+#define TARGET_NR_setregid                   143
+#define TARGET_NR_setgid                     144
+#define TARGET_NR_setreuid                   145
+#define TARGET_NR_setuid                     146
+#define TARGET_NR_setresuid                  147
+#define TARGET_NR_getresuid                  148
+#define TARGET_NR_setresgid                  149
+#define TARGET_NR_getresgid                  150
+#define TARGET_NR_setfsuid                   151
+#define TARGET_NR_setfsgid                   152
+#define TARGET_NR_times                      153
+#define TARGET_NR_setpgid                    154
+#define TARGET_NR_getpgid                    155
+#define TARGET_NR_getsid                     156
+#define TARGET_NR_setsid                     157
+#define TARGET_NR_getgroups                  158
+#define TARGET_NR_setgroups                  159
+#define TARGET_NR_uname                      160
+#define TARGET_NR_sethostname                161
+#define TARGET_NR_setdomainname              162
+#define TARGET_NR_getrusage                  165
+#define TARGET_NR_umask                      166
+#define TARGET_NR_prctl                      167
+#define TARGET_NR_getcpu                     168
+#define TARGET_NR_gettimeofday               169
+#define TARGET_NR_settimeofday               170
+#define TARGET_NR_adjtimex                   171
+#define TARGET_NR_getpid                     172
+#define TARGET_NR_getppid                    173
+#define TARGET_NR_getuid                     174
+#define TARGET_NR_geteuid                    175
+#define TARGET_NR_getgid                     176
+#define TARGET_NR_getegid                    177
+#define TARGET_NR_gettid                     178
+#define TARGET_NR_sysinfo                    179
+#define TARGET_NR_mq_open                    180
+#define TARGET_NR_mq_unlink                  181
+#define TARGET_NR_mq_timedsend               182
+#define TARGET_NR_mq_timedreceive            183
+#define TARGET_NR_mq_notify                  184
+#define TARGET_NR_mq_getsetattr              185
+#define TARGET_NR_msgget                     186
+#define TARGET_NR_msgctl                     187
+#define TARGET_NR_msgrcv                     188
+#define TARGET_NR_msgsnd                     189
+#define TARGET_NR_semget                     190
+#define TARGET_NR_semctl                     191
+#define TARGET_NR_semtimedop                 192
+#define TARGET_NR_semop                      193
+#define TARGET_NR_shmget                     194
+#define TARGET_NR_shmctl                     195
+#define TARGET_NR_shmat                      196
+#define TARGET_NR_shmdt                      197
+#define TARGET_NR_socket                     198
+#define TARGET_NR_socketpair                 199
+#define TARGET_NR_bind                       200
+#define TARGET_NR_listen                     201
+#define TARGET_NR_accept                     202
+#define TARGET_NR_connect                    203
+#define TARGET_NR_getsockname                204
+#define TARGET_NR_getpeername                205
+#define TARGET_NR_sendto                     206
+#define TARGET_NR_recvfrom                   207
+#define TARGET_NR_setsockopt                 208
+#define TARGET_NR_getsockopt                 209
+#define TARGET_NR_shutdown                   210
+#define TARGET_NR_sendmsg                    211
+#define TARGET_NR_recvmsg                    212
+#define TARGET_NR_readahead                  213
+#define TARGET_NR_brk                        214
+#define TARGET_NR_munmap                     215
+#define TARGET_NR_mremap                     216
+#define TARGET_NR_add_key                    217
+#define TARGET_NR_request_key                218
+#define TARGET_NR_keyctl                     219
+#define TARGET_NR_clone                      220
+#define TARGET_NR_execve                     221
+#define TARGET_NR_mmap2                      222
+#define TARGET_NR_fadvise64_64               223
+#define TARGET_NR_swapon                     224
+#define TARGET_NR_swapoff                    225
+#define TARGET_NR_mprotect                   226
+#define TARGET_NR_msync                      227
+#define TARGET_NR_mlock                      228
+#define TARGET_NR_munlock                    229
+#define TARGET_NR_mlockall                   230
+#define TARGET_NR_munlockall                 231
+#define TARGET_NR_mincore                    232
+#define TARGET_NR_madvise                    233
+#define TARGET_NR_remap_file_pages           234
+#define TARGET_NR_mbind                      235
+#define TARGET_NR_get_mempolicy              236
+#define TARGET_NR_set_mempolicy              237
+#define TARGET_NR_migrate_pages              238
+#define TARGET_NR_move_pages                 239
+#define TARGET_NR_rt_tgsigqueueinfo          240
+#define TARGET_NR_perf_event_open            241
+#define TARGET_NR_accept4                    242
+#define TARGET_NR_recvmmsg                   243
+#define TARGET_NR_set_thread_area            244
+#define TARGET_NR_wait4                      260
+#define TARGET_NR_prlimit64                  261
+#define TARGET_NR_fanotify_init              262
+#define TARGET_NR_fanotify_mark              263
+#define TARGET_NR_name_to_handle_at          264
+#define TARGET_NR_open_by_handle_at          265
+#define TARGET_NR_clock_adjtime              266
+#define TARGET_NR_syncfs                     267
+#define TARGET_NR_setns                      268
+#define TARGET_NR_sendmmsg                   269
+#define TARGET_NR_process_vm_readv           270
+#define TARGET_NR_process_vm_writev          271
+#define TARGET_NR_kcmp                       272
+#define TARGET_NR_finit_module               273
+#define TARGET_NR_sched_setattr              274
+#define TARGET_NR_sched_getattr              275
+#define TARGET_NR_renameat2                  276
+#define TARGET_NR_seccomp                    277
+#define TARGET_NR_getrandom                  278
+#define TARGET_NR_memfd_create               279
+#define TARGET_NR_bpf                        280
+#define TARGET_NR_execveat                   281
+#define TARGET_NR_userfaultfd                282
+#define TARGET_NR_membarrier                 283
+#define TARGET_NR_mlock2                     284
+#define TARGET_NR_copy_file_range            285
+#define TARGET_NR_preadv2                    286
+#define TARGET_NR_pwritev2                   287
+#define TARGET_NR_pkey_mprotect              288
+#define TARGET_NR_pkey_alloc                 289
+#define TARGET_NR_pkey_free                  290
+#define TARGET_NR_statx                      291
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 68/87] linux-user: Add target_signal.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (66 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 69/87] linux-user: Add termbits.h " Aleksandar Markovic
                   ` (20 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

nanoMIPS signal handling is much closer to the signal handling in
other mainstream platforms than to the signal handling in preceding
MIPS platforms.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_signal.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 linux-user/nanomips/target_signal.h

diff --git a/linux-user/nanomips/target_signal.h b/linux-user/nanomips/target_signal.h
new file mode 100644
index 0000000..604e853
--- /dev/null
+++ b/linux-user/nanomips/target_signal.h
@@ -0,0 +1,22 @@
+#ifndef NANOMIPS_TARGET_SIGNAL_H
+#define NANOMIPS_TARGET_SIGNAL_H
+
+#include "../generic/signal.h"
+#undef TARGET_SIGRTMIN
+#define TARGET_SIGRTMIN       35
+
+/* this struct defines a stack used during syscall handling */
+typedef struct target_sigaltstack {
+    abi_long ss_sp;
+    abi_ulong ss_size;
+    abi_long ss_flags;
+} target_stack_t;
+
+/* sigaltstack controls */
+#define TARGET_SS_ONSTACK     1
+#define TARGET_SS_DISABLE     2
+
+#define TARGET_MINSIGSTKSZ    6144
+#define TARGET_SIGSTKSZ       12288
+
+#endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 69/87] linux-user: Add termbits.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (67 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 68/87] linux-user: Add target_signal.h header " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h " Aleksandar Markovic
                   ` (19 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add termbits.h header for nanoMIPS. Reuse MIPS' termbits.h as
the functionalities are almost identical.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/termbits.h     | 4 ++++
 linux-user/nanomips/termbits.h | 1 +
 2 files changed, 5 insertions(+)
 create mode 100644 linux-user/nanomips/termbits.h

diff --git a/linux-user/mips/termbits.h b/linux-user/mips/termbits.h
index 49a72c5..c7254f4 100644
--- a/linux-user/mips/termbits.h
+++ b/linux-user/mips/termbits.h
@@ -1,6 +1,10 @@
 /* from asm/termbits.h */
 
+#ifdef TARGET_NANOMIPS
+#define TARGET_NCCS 32
+#else
 #define TARGET_NCCS 23
+#endif
 
 struct target_termios {
     unsigned int c_iflag;               /* input mode flags */
diff --git a/linux-user/nanomips/termbits.h b/linux-user/nanomips/termbits.h
new file mode 100644
index 0000000..ea4e962
--- /dev/null
+++ b/linux-user/nanomips/termbits.h
@@ -0,0 +1 @@
+#include "../mips/termbits.h"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (68 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 69/87] linux-user: Add termbits.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h " Aleksandar Markovic
                   ` (18 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Update constants and structures related to linux user syscall support
in nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/syscall_defs.h | 57 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 40bb60e..abf94b8 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -374,7 +374,7 @@ struct target_dirent64 {
 #define TARGET_SIG_IGN	((abi_long)1)	/* ignore signal */
 #define TARGET_SIG_ERR	((abi_long)-1)	/* error return from signal */
 
-#ifdef TARGET_MIPS
+#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)
 #define TARGET_NSIG	   128
 #else
 #define TARGET_NSIG	   64
@@ -445,7 +445,7 @@ struct target_sigaction {
     target_sigset_t sa_mask;
     abi_ulong sa_restorer;
 };
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)
 struct target_sigaction {
 	uint32_t	sa_flags;
 #if defined(TARGET_ABI_MIPSN32)
@@ -459,6 +459,14 @@ struct target_sigaction {
         abi_ulong sa_restorer;
 #endif
 };
+#elif defined(TARGET_NANOMIPS)
+struct target_sigaction {
+    abi_ulong _sa_handler;
+    abi_uint sa_flags;
+    target_sigset_t sa_mask;
+    abi_ulong sa_restorer;
+};
+
 #else
 struct target_old_sigaction {
         abi_ulong _sa_handler;
@@ -537,7 +545,7 @@ typedef struct {
 #define QEMU_SI_RT 5
 
 typedef struct target_siginfo {
-#ifdef TARGET_MIPS
+#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)
 	int si_signo;
 	int si_code;
 	int si_errno;
@@ -665,13 +673,16 @@ struct target_rlimit {
 
 #if defined(TARGET_ALPHA)
 #define TARGET_RLIM_INFINITY	0x7fffffffffffffffull
-#elif defined(TARGET_MIPS) || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32)
+#elif (defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)) \
+      || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32)
 #define TARGET_RLIM_INFINITY	0x7fffffffUL
+#elif defined(TARGET_NANOMIPS)
+#define TARGET_RLIM_INFINITY    0x76ffeec4UL
 #else
 #define TARGET_RLIM_INFINITY	((abi_ulong)-1)
 #endif
 
-#if defined(TARGET_MIPS)
+#if defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)
 #define TARGET_RLIMIT_CPU		0
 #define TARGET_RLIMIT_FSIZE		1
 #define TARGET_RLIMIT_DATA		2
@@ -687,6 +698,22 @@ struct target_rlimit {
 #define TARGET_RLIMIT_MSGQUEUE		12
 #define TARGET_RLIMIT_NICE		13
 #define TARGET_RLIMIT_RTPRIO		14
+#elif defined(TARGET_NANOMIPS)
+#define TARGET_RLIMIT_CPU               0
+#define TARGET_RLIMIT_FSIZE             1
+#define TARGET_RLIMIT_DATA              2
+#define TARGET_RLIMIT_STACK             3
+#define TARGET_RLIMIT_CORE              4
+#define TARGET_RLIMIT_RSS               5
+#define TARGET_RLIMIT_NPROC             6
+#define TARGET_RLIMIT_NOFILE            7
+#define TARGET_RLIMIT_MEMLOCK           8
+#define TARGET_RLIMIT_AS                9
+#define TARGET_RLIMIT_LOCKS             10
+#define TARGET_RLIMIT_SIGPENDING        11
+#define TARGET_RLIMIT_MSGQUEUE          12
+#define TARGET_RLIMIT_NICE              13
+#define TARGET_RLIMIT_RTPRIO            14
 #else
 #define TARGET_RLIMIT_CPU		0
 #define TARGET_RLIMIT_FSIZE		1
@@ -1657,6 +1684,10 @@ struct target_stat64 {
 	int64_t  	st_blocks;
 };
 
+#elif defined(TARGET_ABI_MIPSP32)
+
+/* No struct stat and struct stat64 structures */
+
 #elif defined(TARGET_ALPHA)
 
 struct target_stat {
@@ -2009,6 +2040,22 @@ struct target_statfs {
 	int32_t			f_flags;
 	int32_t			f_spare[5];
 };
+#elif defined(TARGET_ABI_MIPSP32)
+struct target_statfs {
+    abi_long    f_type;
+    abi_long    f_bsize;
+    abi_long    f_blocks;
+    abi_long    f_bfree;
+    abi_long    f_bavail;
+    abi_long    f_files;
+    abi_long    f_ffree;
+
+    /* Linux specials */
+    target_fsid_t f_fsid;
+    abi_long    f_namelen;
+    abi_llong   f_frsize;   /* Fragment size - unsupported */
+    abi_long    f_spare[6];
+};
 #else
 struct target_statfs {
 	abi_long		f_type;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (69 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 72/87] linux-user: Add sockbits.h " Aleksandar Markovic
                   ` (17 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add fcntl-related constants and structures for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_fcntl.h | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 linux-user/nanomips/target_fcntl.h

diff --git a/linux-user/nanomips/target_fcntl.h b/linux-user/nanomips/target_fcntl.h
new file mode 100644
index 0000000..4203825
--- /dev/null
+++ b/linux-user/nanomips/target_fcntl.h
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
+ */
+
+#ifndef NANOMIPS_TARGET_FCNTL_H
+#define NANOMIPS_TARGET_FCNTL_H
+
+#define TARGET_O_APPEND         0x000400
+#define TARGET_O_DSYNC          0x001000
+#define TARGET_O_NONBLOCK       0x000800
+#define TARGET_O_CREAT          0x000040
+#define TARGET_O_TRUNC          0x000200
+#define TARGET_O_EXCL           0x000080
+#define TARGET_O_NOCTTY         0x000100
+#define TARGET_FASYNC           0x002000
+#define TARGET_O_LARGEFILE      0x008000
+#define TARGET___O_SYNC         0x101000
+#define TARGET_O_DIRECT         0x004000
+#define TARGET_O_CLOEXEC        0x080000
+
+#define TARGET_F_GETLK         5
+#define TARGET_F_SETLK         6
+#define TARGET_F_SETLKW        7
+#define TARGET_F_SETOWN        8       /*  for sockets. */
+#define TARGET_F_GETOWN        9       /*  for sockets. */
+
+#define TARGET_ARCH_FLOCK_PAD abi_long pad[4];
+#define TARGET_ARCH_FLOCK64_PAD
+
+#define TARGET_F_GETLK64       12      /*  using 'struct flock64' */
+#define TARGET_F_SETLK64       13
+#define TARGET_F_SETLKW64      14
+
+#include "../generic/fcntl.h"
+#endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 72/87] linux-user: Add sockbits.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (70 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h " Aleksandar Markovic
                   ` (16 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add sockbits.h header for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/sockbits.h | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 linux-user/nanomips/sockbits.h

diff --git a/linux-user/nanomips/sockbits.h b/linux-user/nanomips/sockbits.h
new file mode 100644
index 0000000..e6b6d31
--- /dev/null
+++ b/linux-user/nanomips/sockbits.h
@@ -0,0 +1 @@
+#include "../mips/sockbits.h"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (71 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 72/87] linux-user: Add sockbits.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h " Aleksandar Markovic
                   ` (15 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add target_syscall.h header for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_syscall.h | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 linux-user/nanomips/target_syscall.h

diff --git a/linux-user/nanomips/target_syscall.h b/linux-user/nanomips/target_syscall.h
new file mode 100644
index 0000000..b40e36b
--- /dev/null
+++ b/linux-user/nanomips/target_syscall.h
@@ -0,0 +1,30 @@
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+
+struct target_pt_regs {
+    /* Pad bytes for argument save space on the stack. */
+    abi_ulong pad0[6];
+
+    /* Saved main processor registers. */
+    abi_ulong regs[32];
+
+    /* Saved special registers. */
+    abi_ulong cp0_status;
+    abi_ulong lo;
+    abi_ulong hi;
+    abi_ulong cp0_badvaddr;
+    abi_ulong cp0_cause;
+    abi_ulong cp0_epc;
+};
+
+/* Nasty hack: define a fake errno value for use by sigreturn.  */
+#undef TARGET_QEMU_ESIGRETURN
+#define TARGET_QEMU_ESIGRETURN 255
+
+#define UNAME_MACHINE "nanomips"
+#define UNAME_MINIMUM_RELEASE "2.6.32"
+
+#define TARGET_CLONE_BACKWARDS
+#define TARGET_MINSIGSTKSZ 6144
+#define TARGET_MLOCKALL_MCL_CURRENT 1
+#define TARGET_MLOCKALL_MCL_FUTURE  2
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (72 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h " Aleksandar Markovic
                   ` (14 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Dimitrije Nikolic <dnikolic@wavecomp.com>

Add target_cpu.h header for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_cpu.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 linux-user/nanomips/target_cpu.h

diff --git a/linux-user/nanomips/target_cpu.h b/linux-user/nanomips/target_cpu.h
new file mode 100644
index 0000000..bbb51de
--- /dev/null
+++ b/linux-user/nanomips/target_cpu.h
@@ -0,0 +1,21 @@
+#ifndef NANOMIPS_TARGET_CPU_H
+#define NANOMIPS_TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->active_tc.gpr[29] = newsp;
+    }
+    env->active_tc.gpr[4] = 0;
+}
+
+static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
+{
+    env->active_tc.CP0_UserLocal = newtls;
+}
+
+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state)
+{
+    return state->active_tc.gpr[29];
+}
+#endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (73 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h " Aleksandar Markovic
                   ` (13 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Dimitrije Nikolic <dnikolic@wavecomp.com>

Add target_structs.h header for nanoMIPS, that in fact only redirects
to the corresponding MIPS header.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_structs.h | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 linux-user/nanomips/target_structs.h

diff --git a/linux-user/nanomips/target_structs.h b/linux-user/nanomips/target_structs.h
new file mode 100644
index 0000000..cc6c6ea
--- /dev/null
+++ b/linux-user/nanomips/target_structs.h
@@ -0,0 +1 @@
+#include "../mips/target_structs.h"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h header for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (74 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 77/87] linux-user: Add signal.c " Aleksandar Markovic
                   ` (12 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Dimitrije Nikolic <dnikolic@wavecomp.com>

This header includes common elf header, and adds cpu_get_model()
function.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/nanomips/target_elf.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 linux-user/nanomips/target_elf.h

diff --git a/linux-user/nanomips/target_elf.h b/linux-user/nanomips/target_elf.h
new file mode 100644
index 0000000..ca68dab
--- /dev/null
+++ b/linux-user/nanomips/target_elf.h
@@ -0,0 +1,14 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
+ */
+
+#ifndef NANOMIPS_TARGET_ELF_H
+#define NANOMIPS_TARGET_ELF_H
+static inline const char *cpu_get_model(uint32_t eflags)
+{
+    return "I7200";
+}
+#endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 77/87] linux-user: Add signal.c for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (75 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline Aleksandar Markovic
                   ` (11 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Dimitrije Nikolic <dnikolic@wavecomp.com>

Add signal.c as a redirection to regular mips' signal.c, but at the
same time amend regular mips' signal.c with bits and pieces specific
for nanoMIPS. This was done this way to avoid duplication of large
pieces of code.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/signal.c     | 25 ++++++++++++++++++++-----
 linux-user/nanomips/signal.c |  1 +
 2 files changed, 21 insertions(+), 5 deletions(-)
 create mode 100644 linux-user/nanomips/signal.c

diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index 6aa303e..ab66429 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -21,7 +21,15 @@
 #include "signal-common.h"
 #include "linux-user/trace.h"
 
-# if defined(TARGET_ABI_MIPSO32)
+#if defined(TARGET_ABI_MIPSP32)
+struct target_sigcontext {
+    uint64_t sc_regs[32];
+    uint64_t sc_pc;
+    uint32_t sc_used_math;
+    uint32_t sc_reserved;
+};
+#define TARGET_ALMASK  (~15)
+#elif defined(TARGET_ABI_MIPSO32)
 struct target_sigcontext {
     uint32_t   sc_regmask;     /* Unused */
     uint32_t   sc_status;
@@ -43,6 +51,7 @@ struct target_sigcontext {
     target_ulong   sc_hi3;
     target_ulong   sc_lo3;
 };
+#define TARGET_ALMASK  (~7)
 # else /* N32 || N64 */
 struct target_sigcontext {
     uint64_t sc_regs[32];
@@ -61,6 +70,7 @@ struct target_sigcontext {
     uint32_t sc_dsp;
     uint32_t sc_reserved;
 };
+#define TARGET_ALMASK  (~15)
 # endif /* O32 */
 
 struct sigframe {
@@ -100,6 +110,7 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 
     __put_user(0x24020000 + syscall, tramp + 0);
     __put_user(0x0000000c          , tramp + 1);
+
     return err;
 }
 
@@ -116,6 +127,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs,
         __put_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
     }
 
+#if !defined(TARGET_ABI_MIPSP32)
     __put_user(regs->active_tc.HI[0], &sc->sc_mdhi);
     __put_user(regs->active_tc.LO[0], &sc->sc_mdlo);
 
@@ -137,6 +149,7 @@ static inline void setup_sigcontext(CPUMIPSState *regs,
     for (i = 0; i < 32; ++i) {
         __put_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
     }
+#endif
 }
 
 static inline void
@@ -146,13 +159,14 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
 
     __get_user(regs->CP0_EPC, &sc->sc_pc);
 
-    __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
-    __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
-
     for (i = 1; i < 32; ++i) {
         __get_user(regs->active_tc.gpr[i], &sc->sc_regs[i]);
     }
 
+#if !defined(TARGET_ABI_MIPSP32)
+    __get_user(regs->active_tc.HI[0], &sc->sc_mdhi);
+    __get_user(regs->active_tc.LO[0], &sc->sc_mdlo);
+
     __get_user(regs->active_tc.HI[1], &sc->sc_hi1);
     __get_user(regs->active_tc.HI[2], &sc->sc_hi2);
     __get_user(regs->active_tc.HI[3], &sc->sc_hi3);
@@ -168,6 +182,7 @@ restore_sigcontext(CPUMIPSState *regs, struct target_sigcontext *sc)
     for (i = 0; i < 32; ++i) {
         __get_user(regs->active_fpu.fpr[i].d, &sc->sc_fpregs[i]);
     }
+#endif
 }
 
 /*
@@ -185,7 +200,7 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
      */
     sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka);
 
-    return (sp - frame_size) & ~7;
+    return (sp - frame_size) & TARGET_ALMASK;
 }
 
 static void mips_set_hflags_isa_mode_from_pc(CPUMIPSState *env)
diff --git a/linux-user/nanomips/signal.c b/linux-user/nanomips/signal.c
new file mode 100644
index 0000000..86efc21
--- /dev/null
+++ b/linux-user/nanomips/signal.c
@@ -0,0 +1 @@
+#include "../mips/signal.c"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (76 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 77/87] linux-user: Add signal.c " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 79/87] linux-user: Add cpu_loop.c for nanoMIPS Aleksandar Markovic
                   ` (10 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add signal trampoline support for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/signal.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index ab66429..c6f5504 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -101,6 +101,17 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 {
     int err = 0;
 
+#if defined(TARGET_ABI_MIPSP32)
+    uint16_t *tramp16 = (uint16_t *)tramp;
+    /*
+     *         li      $2, __NR__foo_sigreturn
+     *         syscall 0
+     */
+     __put_user(0x6040 , tramp16 + 0);
+     __put_user(syscall, tramp16 + 1);
+     __put_user(0      , tramp16 + 2);
+     __put_user(0x1008 , tramp16 + 3);
+#else
     /*
      * Set up the return code ...
      *
@@ -110,7 +121,7 @@ static inline int install_sigtramp(unsigned int *tramp,   unsigned int syscall)
 
     __put_user(0x24020000 + syscall, tramp + 0);
     __put_user(0x0000000c          , tramp + 1);
-
+#endif
     return err;
 }
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 79/87] linux-user: Add cpu_loop.c for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (77 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall " Aleksandar Markovic
                   ` (9 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Dimitrije Nikolic <dnikolic@wavecomp.com>

Amend regular MIPS' cpu_loop.c to include nanoMIPS support.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/mips/cpu_loop.c     | 8 +++++++-
 linux-user/nanomips/cpu_loop.c | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100644 linux-user/nanomips/cpu_loop.c

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index c9c20cf..ada5a79 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -546,7 +546,7 @@ void cpu_loop(CPUMIPSState *env)
                                  arg5, arg6, arg7, arg8);
             }
 done_syscall:
-# else
+# else /* N32/N64 and P32 */
             ret = do_syscall(env, env->active_tc.gpr[2],
                              env->active_tc.gpr[4], env->active_tc.gpr[5],
                              env->active_tc.gpr[6], env->active_tc.gpr[7],
@@ -562,6 +562,7 @@ done_syscall:
                    Avoid clobbering register state.  */
                 break;
             }
+#if !defined(TARGET_ABI_MIPSP32)
             if ((abi_ulong)ret >= (abi_ulong)-1133) {
                 env->active_tc.gpr[7] = 1; /* error flag */
                 ret = -ret;
@@ -569,6 +570,9 @@ done_syscall:
                 env->active_tc.gpr[7] = 0; /* error flag */
             }
             env->active_tc.gpr[2] = ret;
+#else
+            env->active_tc.gpr[4] = ret;
+#endif
             break;
         case EXCP_TLBL:
         case EXCP_TLBS:
@@ -714,6 +718,8 @@ done_syscall:
                     } else {
                         code = ((trap_instr >> 6) & ((1 << 10) - 1));
                     }
+                } else if (env->insn_flags & ISA_NANOMIPS32) {
+                    code = ((trap_instr >> 11) & ((1 << 5) - 1));
                 }
 
                 if (do_break(env, &info, code) != 0) {
diff --git a/linux-user/nanomips/cpu_loop.c b/linux-user/nanomips/cpu_loop.c
new file mode 100644
index 0000000..da4949a
--- /dev/null
+++ b/linux-user/nanomips/cpu_loop.c
@@ -0,0 +1 @@
+#include "../mips/cpu_loop.c"
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (78 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 79/87] linux-user: Add cpu_loop.c for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms Aleksandar Markovic
                   ` (8 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Amend sigaction syscall support for nanoMIPS. This must be done
since nanoMIPS' signal handling is different than MIPS' signal
handling.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/syscall.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3d57966..bced9b8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8825,7 +8825,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                 old_act->sa_flags = oact.sa_flags;
                 unlock_user_struct(old_act, arg3, 1);
             }
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_MIPS) && !defined(TARGET_NANOMIPS)
 	    struct target_sigaction act, oact, *pact, *old_act;
 
 	    if (arg2) {
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (79 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall " Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-20  7:48   ` Timothy Baldwin
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files Aleksandar Markovic
                   ` (7 subsequent siblings)
  88 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Implement support for translation of system call statx(). The
implementation includes invoking other (more mature) syscalls
(from the same 'stat' family) on the host side. This way,
problems of availability of statx() on the host side are
avoided.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/syscall.c      | 121 +++++++++++++++++++++++++++++++++++++++++++++-
 linux-user/syscall_defs.h |  38 +++++++++++++++
 2 files changed, 158 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index bced9b8..f1b6d71 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8002,7 +8002,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     abi_long ret;
 #if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
     || defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
-    || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
+    || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
+    || defined(TARGET_NR_statx)
     struct stat st;
 #endif
 #if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
@@ -10025,6 +10026,124 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         }
         break;
 #endif
+#if defined(TARGET_NR_statx)
+    case TARGET_NR_statx:
+        {
+            struct target_statx *target_stx;
+            int dirfd = tswap32(arg1);
+            int flags = tswap32(arg3);
+
+            p = lock_user_string(arg2);
+            if (p == NULL) {
+                goto efault;
+            }
+#if defined(__NR_statx)
+            {
+                /* We assume that struct statx is arhitecture independent */
+                struct target_statx host_stx;
+                int mask = tswap32(arg4);
+
+                ret = get_errno(syscall(__NR_statx, dirfd, p, flags, mask,
+                                        &host_stx));
+                if (!is_error(ret)) {
+                    unlock_user(p, arg2, 0);
+                    if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
+                        goto efault;
+                    }
+                    memset(target_stx, 0, sizeof(*target_stx));
+
+                    __put_user(host_stx.stx_mask, &target_stx->stx_mask);
+                    __put_user(host_stx.stx_blksize, &target_stx->stx_blksize);
+                    __put_user(host_stx.stx_attributes,
+                               &target_stx->stx_attributes);
+                    __put_user(host_stx.stx_nlink, &target_stx->stx_nlink);
+                    __put_user(host_stx.stx_uid, &target_stx->stx_uid);
+                    __put_user(host_stx.stx_gid, &target_stx->stx_gid);
+                    __put_user(host_stx.stx_mode, &target_stx->stx_mode);
+                    __put_user(host_stx.stx_ino, &target_stx->stx_ino);
+                    __put_user(host_stx.stx_size, &target_stx->stx_size);
+                    __put_user(host_stx.stx_blocks, &target_stx->stx_blocks);
+                    __put_user(host_stx.stx_attributes_mask,
+                               &target_stx->stx_attributes_mask);
+                    __put_user(host_stx.stx_atime.tv_sec,
+                               &target_stx->stx_atime.tv_sec);
+                    __put_user(host_stx.stx_atime.tv_nsec,
+                               &target_stx->stx_atime.tv_nsec);
+                    __put_user(host_stx.stx_btime.tv_sec,
+                               &target_stx->stx_atime.tv_sec);
+                    __put_user(host_stx.stx_btime.tv_nsec,
+                               &target_stx->stx_atime.tv_nsec);
+                    __put_user(host_stx.stx_ctime.tv_sec,
+                               &target_stx->stx_atime.tv_sec);
+                    __put_user(host_stx.stx_ctime.tv_nsec,
+                               &target_stx->stx_atime.tv_nsec);
+                    __put_user(host_stx.stx_mtime.tv_sec,
+                               &target_stx->stx_atime.tv_sec);
+                    __put_user(host_stx.stx_mtime.tv_nsec,
+                               &target_stx->stx_atime.tv_nsec);
+                    __put_user(host_stx.stx_rdev_major,
+                               &target_stx->stx_rdev_major);
+                    __put_user(host_stx.stx_rdev_minor,
+                               &target_stx->stx_rdev_minor);
+                    __put_user(host_stx.stx_dev_major,
+                               &target_stx->stx_dev_major);
+                    __put_user(host_stx.stx_dev_minor,
+                               &target_stx->stx_dev_minor);
+                }
+
+                if (ret != TARGET_ENOSYS) {
+                    break;
+                }
+            }
+#endif
+            if ((p == NULL) || (*((char *)p) == 0)) {
+                /* By file descriptor */
+                ret = get_errno(fstat(dirfd, &st));
+                unlock_user(p, arg2, 0);
+            } else if (*((char *)p) == '/') {
+                /* Absolute pathname */
+                ret = get_errno(stat(path(p), &st));
+                unlock_user(p, arg2, 0);
+            } else {
+                if (dirfd == AT_FDCWD) {
+                    /* Pathname relative to the current working directory */
+                    ret = get_errno(stat(path(p), &st));
+                    unlock_user(p, arg2, 0);
+                } else {
+                    /*
+                     * Pathname relative to the directory referred to by the
+                     * file descriptor dirfd
+                     */
+                    ret = get_errno(fstatat(dirfd, path(p), &st, flags));
+                    unlock_user(p, arg2, 0);
+                }
+            }
+
+            if (!is_error(ret)) {
+                if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
+                    goto efault;
+                }
+                memset(target_stx, 0, sizeof(*target_stx));
+                __put_user(major(st.st_dev), &target_stx->stx_dev_major);
+                __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
+                __put_user(st.st_ino, &target_stx->stx_ino);
+                __put_user(st.st_mode, &target_stx->stx_mode);
+                __put_user(st.st_uid, &target_stx->stx_uid);
+                __put_user(st.st_gid, &target_stx->stx_gid);
+                __put_user(st.st_nlink, &target_stx->stx_nlink);
+                __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
+                __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
+                __put_user(st.st_size, &target_stx->stx_size);
+                __put_user(st.st_blksize, &target_stx->stx_blksize);
+                __put_user(st.st_blocks, &target_stx->stx_blocks);
+                __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
+                __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
+                __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
+                unlock_user_struct(target_stx, arg5, 1);
+            }
+        }
+        break;
+#endif
 #ifdef TARGET_NR_olduname
     case TARGET_NR_olduname:
         goto unimplemented;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index abf94b8..34cc6e0 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2530,4 +2530,42 @@ struct target_user_cap_data {
 /* Return size of the log buffer */
 #define TARGET_SYSLOG_ACTION_SIZE_BUFFER   10
 
+struct target_statx_timestamp {
+   int64_t tv_sec;
+   uint32_t tv_nsec;
+   int32_t __reserved;
+};
+
+struct target_statx {
+   /* 0x00 */
+   uint32_t stx_mask;       /* What results were written [uncond] */
+   uint32_t stx_blksize;    /* Preferred general I/O size [uncond] */
+   uint64_t stx_attributes; /* Flags conveying information about the file */
+   /* 0x10 */
+   uint32_t stx_nlink;      /* Number of hard links */
+   uint32_t stx_uid;        /* User ID of owner */
+   uint32_t stx_gid;        /* Group ID of owner */
+   uint16_t stx_mode;       /* File mode */
+   uint16_t __spare0[1];
+   /* 0x20 */
+   uint64_t stx_ino;        /* Inode number */
+   uint64_t stx_size;       /* File size */
+   uint64_t stx_blocks;     /* Number of 512-byte blocks allocated */
+   uint64_t stx_attributes_mask; /* Mask to show what's supported in
+                                    stx_attributes */
+   /* 0x40 */
+   struct target_statx_timestamp  stx_atime;  /* Last access time */
+   struct target_statx_timestamp  stx_btime;  /* File creation time */
+   struct target_statx_timestamp  stx_ctime;  /* Last attribute change time */
+   struct target_statx_timestamp  stx_mtime;  /* Last data modification time */
+   /* 0x80 */
+   uint32_t stx_rdev_major;   /* Device ID of special file [if bdev/cdev] */
+   uint32_t stx_rdev_minor;
+   uint32_t stx_dev_major; /* ID of device containing file [uncond] */
+   uint32_t stx_dev_minor;
+   /* 0x90 */
+   uint64_t __spare2[14];  /* Spare space for future expansion */
+   /* 0x100 */
+};
+
 #endif
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (80 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 83/87] linux-user: Add nanoMIPS linux user mode configuration support Aleksandar Markovic
                   ` (6 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

nanoMIPs core files require value EF_NANOMIPS_ABI_P32 to be passed
to the e_flags part of the core's elf header.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 linux-user/elfload.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8638612..366ef3b 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1291,6 +1291,10 @@ static inline void init_thread(struct target_pt_regs *regs,
 #define ELF_CLASS ELFCLASS64
 #endif
 
+#ifdef TARGET_ABI_MIPSP32
+#define ELF_FLAGS EF_NANOMIPS_ABI_P32
+#endif
+
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
 {
@@ -1400,6 +1404,10 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
 #define ELF_HWCAP 0
 #endif
 
+#ifndef ELF_FLAGS
+#define ELF_FLAGS 0
+#endif
+
 #ifndef STACK_GROWS_DOWN
 #define STACK_GROWS_DOWN 1
 #endif
@@ -3432,7 +3440,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
      * Construct valid coredump ELF header.  We also
      * add one more segment for notes.
      */
-    fill_elf_header(&elf, segs + 1, ELF_MACHINE, 0);
+    fill_elf_header(&elf, segs + 1, ELF_MACHINE, ELF_FLAGS);
     if (dump_write(fd, &elf, sizeof (elf)) != 0)
         goto out;
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 83/87] linux-user: Add nanoMIPS linux user mode configuration support
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (81 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh Aleksandar Markovic
                   ` (5 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add new linux user mode configuration for nanoMIPS.

Signed-off-by: Aleksandar Rikalo <arikalo@wavecomp.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 configure                               | 13 ++++++++++++-
 default-configs/nanomips-linux-user.mak |  1 +
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/nanomips-linux-user.mak

diff --git a/configure b/configure
index 2a7796e..86c8b28 100755
--- a/configure
+++ b/configure
@@ -742,6 +742,9 @@ case "$cpu" in
     supported_cpu="yes"
     cross_cc_mips=$host_cc
   ;;
+  nanomips*)
+    cpu="mips"
+  ;;
   sparc|sun4[cdmuv])
     cpu="sparc"
     supported_cpu="yes"
@@ -6883,7 +6886,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
 target_bigendian="no"
 
 case "$target_name" in
-  armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|nanomipseb|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -6999,6 +7002,11 @@ case "$target_name" in
   moxie)
     target_compiler=$cross_cc_moxie
   ;;
+  nanomips|nanomipseb)
+    TARGET_ARCH=nanomips
+    TARGET_BASE_ARCH=mips
+    echo "TARGET_ABI_MIPSP32=y" >> $config_target_mak
+  ;;
   nios2)
     target_compiler=$cross_cc_nios2
   ;;
@@ -7256,6 +7264,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   moxie*)
     disas_config "MOXIE"
   ;;
+  nanomips*)
+    disas_config "MIPS"
+  ;;
   nios2)
     disas_config "NIOS2"
   ;;
diff --git a/default-configs/nanomips-linux-user.mak b/default-configs/nanomips-linux-user.mak
new file mode 100644
index 0000000..68fc1f7
--- /dev/null
+++ b/default-configs/nanomips-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for nanomips-linux-user
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (82 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 83/87] linux-user: Add nanoMIPS linux user mode configuration support Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub Aleksandar Markovic
                   ` (4 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Rikalo <arikalo@wavecomp.com>

Add support for nanomips[eb] variant in scripts/qemu-binfmt-conf.sh.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 scripts/qemu-binfmt-conf.sh | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index b0dc8a7..adb96ac 100755
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -2,7 +2,7 @@
 # Enable automatic program execution by the kernel.
 
 qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
-mips mipsel mipsn32 mipsn32el mips64 mips64el \
+mips mipsel mipsn32 mipsn32el mips64 mips64el nanomips nanomipseb \
 sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \
 microblaze microblazeel or1k"
 
@@ -76,6 +76,14 @@ mips64el_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\
 mips64el_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
 mips64el_family=mips
 
+nanomips_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9\x00'
+nanomips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
+nanomips_family=nanomips
+
+nanomipseb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9'
+nanomipseb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
+nanomipseb_family=nanomipseb
+
 sh4_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00'
 sh4_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
 sh4_family=sh4
@@ -137,6 +145,12 @@ qemu_get_family() {
     mips*)
         echo "mips"
         ;;
+    nanomips)
+        echo "nanomips"
+        ;;
+    nanomipseb)
+        echo "nanomipseb"
+        ;;
     "Power Macintosh"|ppc64|powerpc|ppc)
         echo "ppc"
         ;;
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (83 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 86/87] gdbstub: Add XML support for GDB for nanoMIPS Aleksandar Markovic
                   ` (3 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: James Hogan <james.hogan@mips.com>

nanoMIPS has no ISA bit in the PC, so remove the handling of the low bit
of the PC in the MIPS gdbstub for nanoMIPS. This prevents the PC being
read as e.g. 0xbfc00001, and prevents writing to the PC clearing
MIPS_HFLAG_M16.

Signed-off-by: James Hogan <james.hogan@mips.com>
Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 target/mips/gdbstub.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/target/mips/gdbstub.c b/target/mips/gdbstub.c
index 18e0e6d..559b69f 100644
--- a/target/mips/gdbstub.c
+++ b/target/mips/gdbstub.c
@@ -60,7 +60,8 @@ int mips_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
         return gdb_get_regl(mem_buf, (int32_t)env->CP0_Cause);
     case 37:
         return gdb_get_regl(mem_buf, env->active_tc.PC |
-                                     !!(env->hflags & MIPS_HFLAG_M16));
+                                     (!(env->insn_flags & ISA_NANOMIPS32) &&
+                                      env->hflags & MIPS_HFLAG_M16));
     case 72:
         return gdb_get_regl(mem_buf, 0); /* fp */
     case 89:
@@ -131,10 +132,12 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
         break;
     case 37:
         env->active_tc.PC = tmp & ~(target_ulong)1;
-        if (tmp & 1) {
-            env->hflags |= MIPS_HFLAG_M16;
-        } else {
-            env->hflags &= ~(MIPS_HFLAG_M16);
+        if (!(env->insn_flags & ISA_NANOMIPS32)) {
+            if (tmp & 1) {
+                env->hflags |= MIPS_HFLAG_M16;
+            } else {
+                env->hflags &= ~(MIPS_HFLAG_M16);
+            }
         }
         break;
     case 72: /* fp, ignored */
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 86/87] gdbstub: Add XML support for GDB for nanoMIPS
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (84 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items Aleksandar Markovic
                   ` (2 subsequent siblings)
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Stefan Markovic <smarkovic@wavecomp.com>

Add XML support files for GDB for nanoMIPS.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 MAINTAINERS                |  3 ++-
 gdb-xml/nanomips-cp0.xml   | 13 +++++++++++++
 gdb-xml/nanomips-cpu.xml   | 44 ++++++++++++++++++++++++++++++++++++++++++++
 gdb-xml/nanomips-dsp.xml   | 20 ++++++++++++++++++++
 gdb-xml/nanomips-fpu.xml   | 45 +++++++++++++++++++++++++++++++++++++++++++++
 gdb-xml/nanomips-linux.xml | 20 ++++++++++++++++++++
 6 files changed, 144 insertions(+), 1 deletion(-)
 create mode 100644 gdb-xml/nanomips-cp0.xml
 create mode 100644 gdb-xml/nanomips-cpu.xml
 create mode 100644 gdb-xml/nanomips-dsp.xml
 create mode 100644 gdb-xml/nanomips-fpu.xml
 create mode 100644 gdb-xml/nanomips-linux.xml

diff --git a/MAINTAINERS b/MAINTAINERS
index 7130807..a4907d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -190,6 +190,8 @@ M: Aurelien Jarno <aurelien@aurel32.net>
 M: Aleksandar Markovic <amarkovic@wavecomp.com>
 S: Maintained
 F: target/mips/
+F: disas/mips.c
+F: gdb-xml/*ips*.xml
 F: hw/mips/
 F: hw/misc/mips_*
 F: hw/intc/mips_gic.c
@@ -199,7 +201,6 @@ F: include/hw/misc/mips_*
 F: include/hw/intc/mips_gic.h
 F: include/hw/timer/mips_gictimer.h
 F: tests/tcg/mips/
-F: disas/mips.c
 
 Moxie
 M: Anthony Green <green@moxielogic.com>
diff --git a/gdb-xml/nanomips-cp0.xml b/gdb-xml/nanomips-cp0.xml
new file mode 100644
index 0000000..8095dc6
--- /dev/null
+++ b/gdb-xml/nanomips-cp0.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.nanomips.cp0">
+  <reg name="status" bitsize="32"/>
+  <reg name="badvaddr" bitsize="32"/>
+  <reg name="cause" bitsize="32"/>
+</feature>
diff --git a/gdb-xml/nanomips-cpu.xml b/gdb-xml/nanomips-cpu.xml
new file mode 100644
index 0000000..6bba224
--- /dev/null
+++ b/gdb-xml/nanomips-cpu.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.nanomips.cpu">
+  <reg name="r0" bitsize="32" regnum="0"/>
+  <reg name="r1" bitsize="32"/>
+  <reg name="r2" bitsize="32"/>
+  <reg name="r3" bitsize="32"/>
+  <reg name="r4" bitsize="32"/>
+  <reg name="r5" bitsize="32"/>
+  <reg name="r6" bitsize="32"/>
+  <reg name="r7" bitsize="32"/>
+  <reg name="r8" bitsize="32"/>
+  <reg name="r9" bitsize="32"/>
+  <reg name="r10" bitsize="32"/>
+  <reg name="r11" bitsize="32"/>
+  <reg name="r12" bitsize="32"/>
+  <reg name="r13" bitsize="32"/>
+  <reg name="r14" bitsize="32"/>
+  <reg name="r15" bitsize="32"/>
+  <reg name="r16" bitsize="32"/>
+  <reg name="r17" bitsize="32"/>
+  <reg name="r18" bitsize="32"/>
+  <reg name="r19" bitsize="32"/>
+  <reg name="r20" bitsize="32"/>
+  <reg name="r21" bitsize="32"/>
+  <reg name="r22" bitsize="32"/>
+  <reg name="r23" bitsize="32"/>
+  <reg name="r24" bitsize="32"/>
+  <reg name="r25" bitsize="32"/>
+  <reg name="r26" bitsize="32"/>
+  <reg name="r27" bitsize="32"/>
+  <reg name="r28" bitsize="32"/>
+  <reg name="r29" bitsize="32"/>
+  <reg name="r30" bitsize="32"/>
+  <reg name="r31" bitsize="32"/>
+
+  <reg name="pc" bitsize="32"/>
+</feature>
diff --git a/gdb-xml/nanomips-dsp.xml b/gdb-xml/nanomips-dsp.xml
new file mode 100644
index 0000000..950910f
--- /dev/null
+++ b/gdb-xml/nanomips-dsp.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2012-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.nanomips.dsp">
+  <reg name="hi0" bitsize="32"/>
+  <reg name="lo0" bitsize="32"/>
+  <reg name="hi1" bitsize="32"/>
+  <reg name="lo1" bitsize="32"/>
+  <reg name="hi2" bitsize="32"/>
+  <reg name="lo2" bitsize="32"/>
+  <reg name="hi3" bitsize="32"/>
+  <reg name="lo3" bitsize="32"/>
+
+  <reg name="dspctl" bitsize="32"/>
+</feature>
diff --git a/gdb-xml/nanomips-fpu.xml b/gdb-xml/nanomips-fpu.xml
new file mode 100644
index 0000000..fd225a5
--- /dev/null
+++ b/gdb-xml/nanomips-fpu.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.nanomips.fpu">
+  <reg name="f0" bitsize="64" type="ieee_double"/>
+  <reg name="f1" bitsize="64" type="ieee_double"/>
+  <reg name="f2" bitsize="64" type="ieee_double"/>
+  <reg name="f3" bitsize="64" type="ieee_double"/>
+  <reg name="f4" bitsize="64" type="ieee_double"/>
+  <reg name="f5" bitsize="64" type="ieee_double"/>
+  <reg name="f6" bitsize="64" type="ieee_double"/>
+  <reg name="f7" bitsize="64" type="ieee_double"/>
+  <reg name="f8" bitsize="64" type="ieee_double"/>
+  <reg name="f9" bitsize="64" type="ieee_double"/>
+  <reg name="f10" bitsize="64" type="ieee_double"/>
+  <reg name="f11" bitsize="64" type="ieee_double"/>
+  <reg name="f12" bitsize="64" type="ieee_double"/>
+  <reg name="f13" bitsize="64" type="ieee_double"/>
+  <reg name="f14" bitsize="64" type="ieee_double"/>
+  <reg name="f15" bitsize="64" type="ieee_double"/>
+  <reg name="f16" bitsize="64" type="ieee_double"/>
+  <reg name="f17" bitsize="64" type="ieee_double"/>
+  <reg name="f18" bitsize="64" type="ieee_double"/>
+  <reg name="f19" bitsize="64" type="ieee_double"/>
+  <reg name="f20" bitsize="64" type="ieee_double"/>
+  <reg name="f21" bitsize="64" type="ieee_double"/>
+  <reg name="f22" bitsize="64" type="ieee_double"/>
+  <reg name="f23" bitsize="64" type="ieee_double"/>
+  <reg name="f24" bitsize="64" type="ieee_double"/>
+  <reg name="f25" bitsize="64" type="ieee_double"/>
+  <reg name="f26" bitsize="64" type="ieee_double"/>
+  <reg name="f27" bitsize="64" type="ieee_double"/>
+  <reg name="f28" bitsize="64" type="ieee_double"/>
+  <reg name="f29" bitsize="64" type="ieee_double"/>
+  <reg name="f30" bitsize="64" type="ieee_double"/>
+  <reg name="f31" bitsize="64" type="ieee_double"/>
+
+  <reg name="fcsr" bitsize="32" group="float"/>
+  <reg name="fir" bitsize="32" group="float"/>
+</feature>
diff --git a/gdb-xml/nanomips-linux.xml b/gdb-xml/nanomips-linux.xml
new file mode 100644
index 0000000..8a04634
--- /dev/null
+++ b/gdb-xml/nanomips-linux.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2015 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <architecture>nanomips</architecture>
+  <osabi>GNU/Linux</osabi>
+  <xi:include href="nanomips-cpu.xml"/>
+  <xi:include href="nanomips-cp0.xml"/>
+  <xi:include href="nanomips-fpu.xml"/>
+  <xi:include href="nanomips-dsp.xml"/>
+
+  <feature name="org.gnu.gdb.nanomips.linux">
+    <reg name="restart" bitsize="32" group="system"/>
+  </feature>
+</target>
-- 
2.7.4

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

* [Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (85 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 86/87] gdbstub: Add XML support for GDB for nanoMIPS Aleksandar Markovic
@ 2018-08-13 17:53 ` Aleksandar Markovic
  2018-08-14 15:52 ` [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
  2018-08-16  8:16 ` no-reply
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 17:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, amarkovic, smarkovic, pjovanovic,
	pburton

From: Aleksandar Markovic <amarkovic@wavecomp.com>

Add nanoMIPS-related items in qemu-doc.texi

Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
---
 qemu-doc.texi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index 8ea6bfa..ab2471d 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2705,6 +2705,8 @@ The binary format is detected automatically.
 
 @command{qemu-mipsn32el} executes 32-bit little endian MIPS binaries (MIPS N32 ABI).
 
+@command{qemu-nanomips} executes 32-bit little endian nanoMIPS binaries (MIPS P32 ABI).
+
 @cindex user mode (NiosII)
 @command{qemu-nios2} TODO.
 
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT Aleksandar Markovic
@ 2018-08-13 18:13   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 18:13 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:52 PM
> 
> Subject: [PATCH v8 09/87] target/mips: Add support for availability control via bit MT
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Add a field in hflags for MT bit, and functions check_mt() and
> check_cp0_mt().
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/cpu.h       |  3 ++-
>  target/mips/internal.h  |  6 +++++-
>  target/mips/translate.c | 29 +++++++++++++++++++++++++++++
>  3 files changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> ...
> +/*
> + * This code generates a "coprocessor unusable" if CP) is not
> + * available, and, if that is not the case, generates a "reserved
> + * instruction" exception if the Config5 MT bit is NOT set.
> + * This is used for some of instructions in MT ASE.
> + */

" "coprocessor unusable" if CP) " should be " "coprocessor unusable" exception if CP0 ". Otherwise:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control Aleksandar Markovic
@ 2018-08-13 18:23   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-13 18:23 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:52 PM
> To: qemu-devel@nongnu.org
>
> Subject: [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Use bits from configuration registers for availability control
> of MT ASE instructions, rather than only ISA_MT bit in insn_flags.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index b73f434..af9714b 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -8393,7 +8393,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
>          opn = "mthc0";
>          break;
>      case OPC_MFTR:
> -        check_insn(ctx, ASE_MT);
> +        check_cp0_enabled(ctx);
>          if (rd == 0) {
>              /* Treat as NOP. */
>              return;
> @@ -8403,7 +8403,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
>          opn = "mftr";
>          break;
>      case OPC_MTTR:
> -        check_insn(ctx, ASE_MT);
> +        check_cp0_enabled(ctx);
>          gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
>                   ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
>          opn = "mttr";
> @@ -18619,7 +18619,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
>          gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
>          break;
>      case OPC_FORK:
> -        check_insn(ctx, ASE_MT);
> +        check_mt(ctx);
>          {
>              TCGv t0 = tcg_temp_new();
>              TCGv t1 = tcg_temp_new();
> @@ -18632,7 +18632,7 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
>          }
>          break;
>      case OPC_YIELD:
> -        check_insn(ctx, ASE_MT);
> +        check_mt(ctx);
>          {
>              TCGv t0 = tcg_temp_new();
> 
> @@ -19929,22 +19929,22 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
>                  op2 = MASK_MFMC0(ctx->opcode);
>                  switch (op2) {
>                  case OPC_DMT:
> -                    check_insn(ctx, ASE_MT);
> +                    check_cp0_mt(ctx);
>                      gen_helper_dmt(t0);
>                      gen_store_gpr(t0, rt);
>                      break;
>                  case OPC_EMT:
> -                    check_insn(ctx, ASE_MT);
> +                    check_cp0_mt(ctx);
>                      gen_helper_emt(t0);
>                      gen_store_gpr(t0, rt);
>                      break;
>                  case OPC_DVPE:
> -                    check_insn(ctx, ASE_MT);
> +                    check_cp0_mt(ctx);
>                      gen_helper_dvpe(t0, cpu_env);
>                      gen_store_gpr(t0, rt);
>                      break;
>                  case OPC_EVPE:
> -                    check_insn(ctx, ASE_MT);
> +                    check_cp0_mt(ctx);
>                      gen_helper_evpe(t0, cpu_env);
>                      gen_store_gpr(t0, rt);
>                      break;

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2 Aleksandar Markovic
@ 2018-08-14 11:13   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-14 11:13 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:52 PM
> 
> Subject: [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Remove "range style" case statements to make code analysis easier.
> This patch handles cases when the values in the range in question
> were not properly defined.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <amarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 71 insertions(+), 7 deletions(-)

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair Aleksandar Markovic
@ 2018-08-14 12:20   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-14 12:20 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP > pair
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Implement support for nanoMIPS LLWP/SCWP instruction pair.
> 
> Signed-off-by: Dimitrije Nikolic <dnikolic@wavecomp.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  linux-user/mips/cpu_loop.c | 25 ++++++++++++----
>  target/mips/cpu.h          |  2 ++
>  target/mips/translate.c    | 74 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 96 insertions(+), 5 deletions(-)
> 

I was told that all applicable tests now pass, so:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

Many thanks to Richard Henderson for guidance and patience.


> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
> index 084ad6a..1d3dc9e 100644
> --- a/linux-user/mips/cpu_loop.c
> +++ b/linux-user/mips/cpu_loop.c
> @@ -397,10 +397,13 @@ static int do_store_exclusive(CPUMIPSState *env)
>      target_ulong addr;
>      target_ulong page_addr;
>      target_ulong val;
> +    uint32_t val_wp = 0;
> +    uint32_t llnewval_wp = 0;
>      int flags;
>      int segv = 0;
>      int reg;
>      int d;
> +    int wp;
> 
>      addr = env->lladdr;
>      page_addr = addr & TARGET_PAGE_MASK;
> @@ -412,19 +415,31 @@ static int do_store_exclusive(CPUMIPSState *env)
>      } else {
>          reg = env->llreg & 0x1f;
>          d = (env->llreg & 0x20) != 0;
> -        if (d) {
> -            segv = get_user_s64(val, addr);
> +        wp = (env->llreg & 0x40) != 0;
> +        if (!wp) {
> +            if (d) {
> +                segv = get_user_s64(val, addr);
> +            } else {
> +                segv = get_user_s32(val, addr);
> +            }
>          } else {
>              segv = get_user_s32(val, addr);
> +            segv |= get_user_s32(val_wp, addr);
> +            llnewval_wp = env->llnewval_wp;
>          }
>          if (!segv) {
> -            if (val != env->llval) {
> +            if (val != env->llval && val_wp == llnewval_wp) {
>                  env->active_tc.gpr[reg] = 0;
>              } else {
> -                if (d) {
> -                    segv = put_user_u64(env->llnewval, addr);
> +                if (!wp) {
> +                    if (d) {
> +                        segv = put_user_u64(env->llnewval, addr);
> +                    } else {
> +                        segv = put_user_u32(env->llnewval, addr);
> +                    }
>                  } else {
>                      segv = put_user_u32(env->llnewval, addr);
> +                    segv |= put_user_u32(env->llnewval_wp, addr + 4);
>                  }
>                  if (!segv) {
>                      env->active_tc.gpr[reg] = 1;
> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> index 8a8782b..bf9c634 100644
> --- a/target/mips/cpu.h
> +++ b/target/mips/cpu.h
> @@ -506,6 +506,8 @@ struct CPUMIPSState {
>      uint64_t lladdr;
>      target_ulong llval;
>      target_ulong llnewval;
> +    uint64_t llval_wp;
> +    uint32_t llnewval_wp;
>      target_ulong llreg;
>      uint64_t CP0_LLAddr_rw_bitmask;
>      int CP0_LLAddr_shift;
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 9f27aab..70785f2 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -2401,6 +2401,31 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
>      tcg_temp_free(t0);
>  }
> 
> +static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
> +                    uint32_t reg1, uint32_t reg2)
> +{
> +    TCGv taddr = tcg_temp_new();
> +    TCGv_i64 tval = tcg_temp_new_i64();
> +    TCGv tmp1 = tcg_temp_new();
> +    TCGv tmp2 = tcg_temp_new();
> +
> +    gen_base_offset_addr(ctx, taddr, base, offset);
> +    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
> +#ifdef TARGET_WORDS_BIGENDIAN
> +    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
> +#else
> +    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
> +#endif
> +    gen_store_gpr(tmp1, reg1);
> +    tcg_temp_free(tmp1);
> +    gen_store_gpr(tmp2, reg2);
> +    tcg_temp_free(tmp2);
> +    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
> +    tcg_temp_free_i64(tval);
> +    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
> +    tcg_temp_free(taddr);
> +}
> +
>  /* Store */
>  static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
>                      int base, int offset)
> @@ -2497,6 +2522,51 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, > int rt,
>      tcg_temp_free(t0);
>  }
> 
> +static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
> +                    uint32_t reg1, uint32_t reg2)
> +{
> +    TCGv taddr = tcg_temp_local_new();
> +    TCGv lladdr = tcg_temp_local_new();
> +    TCGv_i64 tval = tcg_temp_new_i64();
> +    TCGv_i64 llval = tcg_temp_new_i64();
> +    TCGv_i64 val = tcg_temp_new_i64();
> +    TCGv tmp1 = tcg_temp_new();
> +    TCGv tmp2 = tcg_temp_new();
> +    TCGLabel *lab_fail = gen_new_label();
> +    TCGLabel *lab_done = gen_new_label();
> +
> +    gen_base_offset_addr(ctx, taddr, base, offset);
> +
> +    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
> +    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
> +
> +    gen_load_gpr(tmp1, reg1);
> +    gen_load_gpr(tmp2, reg2);
> +
> +#ifdef TARGET_WORDS_BIGENDIAN
> +    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
> +#else
> +    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
> +#endif
> +
> +    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
> +    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
> +                               ctx->mem_idx, MO_64);
> +    if (reg1 != 0) {
> +        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
> +    }
> +    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
> +
> +    gen_set_label(lab_fail);
> +
> +    if (reg1 != 0) {
> +        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
> +    }
> +    gen_set_label(lab_done);
> +    tcg_gen_movi_tl(lladdr, -1);
> +    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
> +}
> +
>  /* Load and store */
>  static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
>                            TCGv t0)
> @@ -18027,6 +18097,8 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, > DisasContext *ctx)
>                          gen_ld(ctx, OPC_LL, rt, rs, s);
>                          break;
>                      case NM_LLWP:
> +                        check_xnp(ctx);
> +                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
>                          break;
>                      }
>                      break;
> @@ -18036,6 +18108,8 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, > DisasContext *ctx)
>                          gen_st_cond(ctx, OPC_SC, rt, rs, s);
>                          break;
>                      case NM_SCWP:
> +                        check_xnp(ctx);
> +                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
>                          break;
>                      }
>                      break;
> --
> 2.7.4

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

* Re: [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP Aleksandar Markovic
@ 2018-08-14 12:23   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-14 12:23 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:52 PM
> 
> Subject: [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Add a field in hflags for XNP bit, and a function check_xnp().
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/cpu.h       |  3 ++-
>  target/mips/internal.h  |  5 ++++-
>  target/mips/translate.c | 12 ++++++++++++
>  3 files changed, 18 insertions(+), 2 deletions(-)

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (86 preceding siblings ...)
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items Aleksandar Markovic
@ 2018-08-14 15:52 ` Aleksandar Markovic
  2018-08-16  8:16 ` no-reply
  88 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-14 15:52 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com
> Sent: Monday, August 13, 2018 7:52 PM
> 
> Subject: [PATCH v8 00/87] Add nanoMIPS support to QEMU
> 
> From: Aleksandar Markovic <amarkovic@wavecomp.com>
> 
> v7->v8:
> 
>   - the series is slightly reorganized so that:
>      - patches 1-19 are fixes and improvements that are not
>      dependent on the existence of nanoMIPS (even though most
>      of them are logically connected to (and necessary for)
>      nanoMIPS support) - they fix and improve pre-nanoMIPS code
>       - patches 20-65 introduce core nanoMIPS functionality, but
>       do not contain any dependence on or reference to nanoMIPS
>       Linux ABI
>       - patches 66-87 mostly deal with Linux user mode-related
>       nanoMIPS functionality, therefore dependent on nanoMIPS
>       Linux ABI
>   - the series will probably be split into three (corresponding
>      to the organization mentioned above) in near future

Hello, all,

I am going to do splitting as described above soon. This will hopefully allow all of us to work easier with this series, and to make progress on parts that don't depend on Linux ABI independently on the destiny of Linux ABI-dependent parts.

Please let me know if you have any reservations.

Regards,
Aleksandar

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

* Re: [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU
  2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
                   ` (87 preceding siblings ...)
  2018-08-14 15:52 ` [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
@ 2018-08-16  8:16 ` no-reply
  2018-08-16 11:43   ` Aleksandar Markovic
  88 siblings, 1 reply; 120+ messages in thread
From: no-reply @ 2018-08-16  8:16 UTC (permalink / raw)
  To: aleksandar.markovic
  Cc: famz, qemu-devel, peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude, amarkovic,
	pjovanovic, aurelien

Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1534182832-554-1-git-send-email-aleksandar.markovic@rt-rk.com
Subject: [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 t [tag update]            patchew/20180814124254.5229-1-peter.maydell@linaro.org -> patchew/20180814124254.5229-1-peter.maydell@linaro.org
Switched to a new branch 'test'
fac42f8865 qemu-doc: Add nanoMIPS-related items
d43d5394ec gdbstub: Add XML support for GDB for nanoMIPS
be84315d2b gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub
6e0ed49b51 linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh
77ade6242a linux-user: Add nanoMIPS linux user mode configuration support
fa3a48ee21 linux-user: Add support for nanoMIPS core files
5c4e621529 linux-user: Add support for statx() syscall for all platforms
e0b2c6b944 linux-user: Amend support for sigaction() syscall for nanoMIPS
5b77b3db32 linux-user: Add cpu_loop.c for nanoMIPS
c930d7df54 linux-user: Add support for nanoMIPS signal trampoline
84b6db80f6 linux-user: Add signal.c for nanoMIPS
7b6c630289 linux-user: Add target_elf.h header for nanoMIPS
ea4815bf2e linux-user: Add target_structs.h header for nanoMIPS
01ba7d1d83 linux-user: Add target_cpu.h header for nanoMIPS
646d28f897 linux-user: Add target_syscall.h header for nanoMIPS
1c313bc906 linux-user: Add sockbits.h header for nanoMIPS
d8fa5d7422 linux-user: Add target_fcntl.h header for nanoMIPS
4e6a108c25 linux-user: Update syscall_defs.h header for nanoMIPS
d9feca652a linux-user: Add termbits.h header for nanoMIPS
c4d510be5a linux-user: Add target_signal.h header for nanoMIPS
4b1f9d5fba linux-user: Add syscall numbers for nanoMIPS
9fca61d37b elf: Add nanoMIPS specific variations in ELF header fields
056bdea55d target/mips: Add definition of nanoMIPS I7200 CPU
a1d3456a16 mips_malta: Fix semihosting argument passing for nanoMIPS bare metal
8b1712a854 mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader
ab8023fade mips_malta: Add basic nanoMIPS boot code for Malta board
c8029e0d74 elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS
d6f8520f27 elf: Don't check FCR31_NAN2008 bit for nanoMIPS
028dd85c14 elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too
aec7c34312 elf: Add EM_NANOMIPS value as a valid one for e_machine field
069fbd7e7c target/mips: Fix ERET/ERETNC behavior related to ADEL exception
e89fe52648 target/mips: Adjust set_pc() for nanoMIPS
7ac8ee6a05 target/mips: Adjust set_hflags_for_handler() for nanoMIPS
ae3a1c7255 target/mips: Adjust exception_resume_pc() for nanoMIPS
96a8b80e8f target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS
5f05596e99 target/mips: Add handling of branch delay slots for nanoMIPS
6561a9b7a3 disas: Add support for microMIPS and nanoMIPS
70c1c34c36 target/mips: Add emulation of DSP ASE for nanoMIPS - part 6
b8865ddc64 target/mips: Add emulation of DSP ASE for nanoMIPS - part 5
a8bbbc77a7 target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
7a3eea0733 target/mips: Add emulation of DSP ASE for nanoMIPS - part 3
f20d6e767c target/mips: Add emulation of DSP ASE for nanoMIPS - part 2
2cbfdb6373 target/mips: Add emulation of DSP ASE for nanoMIPS - part 1
948216d775 target/mips: Implement MT ASE support for nanoMIPS
ca66c06309 target/mips: Add emulation of nanoMIPS 32-bit branch instructions
3f523002af target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair
783994d6b8 target/mips: Add emulation of nanoMIPS 32-bit load and store instructions
043f78c068 target/mips: Implement emulation of nanoMIPS EXTW instruction
8d0ef85707 target/mips: Implement emulation of nanoMIPS ROTX instruction
82e7d6022d target/mips: Add emulation of misc nanoMIPS instructions (p_lsx)
342833bc21 target/mips: Add emulation of misc nanoMIPS instructions (pool32axf)
ab79a06b77 target/mips: Add emulation of misc nanoMIPS instructions (pool32a0)
4157eb9c42 target/mips: Add emulation of nanoMIPS FP instructions
76a17b7be9 target/mips: Add emulation of nanoMIPS 48-bit instructions
f2f0c31e87 target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV
1793b81c87 target/mips: Add emulation of some common nanoMIPS 32-bit instructions
9541d0f758 target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions
77cfeb5e5b target/mips: Add emulation of nanoMIPS 16-bit logic instructions
543e827f55 target/mips: Add emulation of nanoMIPS 16-bit load and store instructions
d835b9de55 target/mips: Add emulation of nanoMIPS 16-bit misc instructions
801def3f9b target/mips: Add emulation of nanoMIPS 16-bit shift instructions
b63a7e6980 target/mips: Add emulation of nanoMIPS 16-bit branch instructions
a399d564c0 target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions
e689608f33 target/mips: Add nanoMIPS decoding and extraction utilities
ab249748fe target/mips: Add placeholder and invocation of decode_nanomips_opc()
60c689101d target/mips: Add nanoMIPS DSP ASE opcodes
069d6e6cc0 target/mips: Add nanoMIPS base instruction set opcodes
85c6419fcb target/mips: Add preprocessor constants for nanoMIPS
463e9f77e4 qemu-doc: Amend MIPS-related items
c7d6e91a16 linux-user: Add preprocessor availability control to some syscalls
fa22ac3c81 linux-user: Update MIPS syscall numbers up to kernel 4.18 headers
753b7ddc9f elf: Add ELF flags for MIPS machine variants
2731da1ea4 elf: Remove duplicate preprocessor constant definition
99ed97e25f target/mips: Add gen_op_addr_addi()
14f4e549a1 target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0
d41913a620 target/mips: Don't update BadVAddr register in Debug Mode
2583d95d46 target/mips: Implement CP0 Config1.WR bit functionality
e8bf0b5bb8 target/mips: Fix MT ASE instructions' availability control
2e40ec0a66 target/mips: Add support for availability control via bit MT
6cc683c8c2 target/mips: Add support for availability control via bit XNP
c6cf9dbbd6 target/mips: Add CP0 BadInstrX register
3da785ee55 target/mips: Update some CP0 registers bit definitions
d49428b302 target/mips: Fix two instances of shadow variables
b8b0dbf712 target/mips: Mark switch fallthroughs with interpretable comments
c3342491bc target/mips: Avoid case statements formulated by ranges - part 2
4969fbbd87 target/mips: Avoid case statements formulated by ranges - part 1
7d92c3cbb4 MAINTAINERS: Update target/mips maintainer's email addresses

=== OUTPUT BEGIN ===
Checking PATCH 1/87: MAINTAINERS: Update target/mips maintainer's email addresses...
Checking PATCH 2/87: target/mips: Avoid case statements formulated by ranges - part 1...
Checking PATCH 3/87: target/mips: Avoid case statements formulated by ranges - part 2...
Checking PATCH 4/87: target/mips: Mark switch fallthroughs with interpretable comments...
Checking PATCH 5/87: target/mips: Fix two instances of shadow variables...
Checking PATCH 6/87: target/mips: Update some CP0 registers bit definitions...
Checking PATCH 7/87: target/mips: Add CP0 BadInstrX register...
Checking PATCH 8/87: target/mips: Add support for availability control via bit XNP...
Checking PATCH 9/87: target/mips: Add support for availability control via bit MT...
Checking PATCH 10/87: target/mips: Fix MT ASE instructions' availability control...
Checking PATCH 11/87: target/mips: Implement CP0 Config1.WR bit functionality...
Checking PATCH 12/87: target/mips: Don't update BadVAddr register in Debug Mode...
Checking PATCH 13/87: target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0...
Checking PATCH 14/87: target/mips: Add gen_op_addr_addi()...
Checking PATCH 15/87: elf: Remove duplicate preprocessor constant definition...
Checking PATCH 16/87: elf: Add ELF flags for MIPS machine variants...
Checking PATCH 17/87: linux-user: Update MIPS syscall numbers up to kernel 4.18 headers...
Checking PATCH 18/87: linux-user: Add preprocessor availability control to some syscalls...
Checking PATCH 19/87: qemu-doc: Amend MIPS-related items...
Checking PATCH 20/87: target/mips: Add preprocessor constants for nanoMIPS...
Checking PATCH 21/87: target/mips: Add nanoMIPS base instruction set opcodes...
Checking PATCH 22/87: target/mips: Add nanoMIPS DSP ASE opcodes...
Checking PATCH 23/87: target/mips: Add placeholder and invocation of decode_nanomips_opc()...
Checking PATCH 24/87: target/mips: Add nanoMIPS decoding and extraction utilities...
Checking PATCH 25/87: target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions...
Checking PATCH 26/87: target/mips: Add emulation of nanoMIPS 16-bit branch instructions...
Checking PATCH 27/87: target/mips: Add emulation of nanoMIPS 16-bit shift instructions...
Checking PATCH 28/87: target/mips: Add emulation of nanoMIPS 16-bit misc instructions...
Checking PATCH 29/87: target/mips: Add emulation of nanoMIPS 16-bit load and store instructions...
Checking PATCH 30/87: target/mips: Add emulation of nanoMIPS 16-bit logic instructions...
Checking PATCH 31/87: target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions...
Checking PATCH 32/87: target/mips: Add emulation of some common nanoMIPS 32-bit instructions...
Checking PATCH 33/87: target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV...
Checking PATCH 34/87: target/mips: Add emulation of nanoMIPS 48-bit instructions...
Checking PATCH 35/87: target/mips: Add emulation of nanoMIPS FP instructions...
Checking PATCH 36/87: target/mips: Add emulation of misc nanoMIPS instructions (pool32a0)...
Checking PATCH 37/87: target/mips: Add emulation of misc nanoMIPS instructions (pool32axf)...
Checking PATCH 38/87: target/mips: Add emulation of misc nanoMIPS instructions (p_lsx)...
Checking PATCH 39/87: target/mips: Implement emulation of nanoMIPS ROTX instruction...
Checking PATCH 40/87: target/mips: Implement emulation of nanoMIPS EXTW instruction...
Checking PATCH 41/87: target/mips: Add emulation of nanoMIPS 32-bit load and store instructions...
Checking PATCH 42/87: target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair...
Checking PATCH 43/87: target/mips: Add emulation of nanoMIPS 32-bit branch instructions...
Checking PATCH 44/87: target/mips: Implement MT ASE support for nanoMIPS...
Checking PATCH 45/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 1...
Checking PATCH 46/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 2...
Checking PATCH 47/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 3...
Checking PATCH 48/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 4...
Checking PATCH 49/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 5...
Checking PATCH 50/87: target/mips: Add emulation of DSP ASE for nanoMIPS - part 6...
Checking PATCH 51/87: disas: Add support for microMIPS and nanoMIPS...
ERROR: externs should be avoided in .c files
#330: FILE: disas/mips.c:6074:
+int nanomips_dis(char *buf, unsigned address, unsigned short one,

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#414: 
new file mode 100644

ERROR: space required before that '*' (ctx:OxV)
#860: FILE: disas/nanomips.cpp:442:
+                if ((cond == 0) || (this->*cond)(op_code)) {
                                           ^

ERROR: space required before that '*' (ctx:OxV)
#888: FILE: disas/nanomips.cpp:470:
+                            dis = (this->*dis_fn)(op_code);
                                          ^

ERROR: space prohibited between function name and open parenthesis '('
#17393: FILE: include/disas/bfd.h:390:
+int print_insn_micromips        (bfd_vma, disassemble_info*);

total: 4 errors, 1 warnings, 17374 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 52/87: target/mips: Add handling of branch delay slots for nanoMIPS...
Checking PATCH 53/87: target/mips: Add updating BadInstr, BadInstrP, BadInstrX for nanoMIPS...
Checking PATCH 54/87: target/mips: Adjust exception_resume_pc() for nanoMIPS...
Checking PATCH 55/87: target/mips: Adjust set_hflags_for_handler() for nanoMIPS...
Checking PATCH 56/87: target/mips: Adjust set_pc() for nanoMIPS...
Checking PATCH 57/87: target/mips: Fix ERET/ERETNC behavior related to ADEL exception...
Checking PATCH 58/87: elf: Add EM_NANOMIPS value as a valid one for e_machine field...
Checking PATCH 59/87: elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too...
Checking PATCH 60/87: elf: Don't check FCR31_NAN2008 bit for nanoMIPS...
Checking PATCH 61/87: elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS...
Checking PATCH 62/87: mips_malta: Add basic nanoMIPS boot code for Malta board...
Checking PATCH 63/87: mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader...
Checking PATCH 64/87: mips_malta: Fix semihosting argument passing for nanoMIPS bare metal...
Checking PATCH 65/87: target/mips: Add definition of nanoMIPS I7200 CPU...
Checking PATCH 66/87: elf: Add nanoMIPS specific variations in ELF header fields...
Checking PATCH 67/87: linux-user: Add syscall numbers for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

total: 0 errors, 1 warnings, 275 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 68/87: linux-user: Add target_signal.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#16: 
new file mode 100644

total: 0 errors, 1 warnings, 22 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 69/87: linux-user: Add termbits.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#30: 
new file mode 100644

total: 0 errors, 1 warnings, 11 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 70/87: linux-user: Update syscall_defs.h header for nanoMIPS...
Checking PATCH 71/87: linux-user: Add target_fcntl.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

total: 0 errors, 1 warnings, 38 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 72/87: linux-user: Add sockbits.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

total: 0 errors, 1 warnings, 1 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 73/87: linux-user: Add target_syscall.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

total: 0 errors, 1 warnings, 30 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 74/87: linux-user: Add target_cpu.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#14: 
new file mode 100644

total: 0 errors, 1 warnings, 21 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 75/87: linux-user: Add target_structs.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#15: 
new file mode 100644

total: 0 errors, 1 warnings, 1 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 76/87: linux-user: Add target_elf.h header for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#15: 
new file mode 100644

total: 0 errors, 1 warnings, 14 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 77/87: linux-user: Add signal.c for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#113: 
new file mode 100644

total: 0 errors, 1 warnings, 84 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 78/87: linux-user: Add support for nanoMIPS signal trampoline...
Checking PATCH 79/87: linux-user: Add cpu_loop.c for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#54: 
new file mode 100644

total: 0 errors, 1 warnings, 33 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 80/87: linux-user: Amend support for sigaction() syscall for nanoMIPS...
Checking PATCH 81/87: linux-user: Add support for statx() syscall for all platforms...
WARNING: architecture specific defines should be avoided
#45: FILE: linux-user/syscall.c:10040:
+#if defined(__NR_statx)

total: 0 errors, 1 warnings, 175 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 82/87: linux-user: Add support for nanoMIPS core files...
Checking PATCH 83/87: linux-user: Add nanoMIPS linux user mode configuration support...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#60: 
new file mode 100644

total: 0 errors, 1 warnings, 38 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 84/87: linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh...
WARNING: line over 80 characters
#30: FILE: scripts/qemu-binfmt-conf.sh:79:
+nanomips_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9\x00'

ERROR: line over 90 characters
#31: FILE: scripts/qemu-binfmt-conf.sh:80:
+nanomips_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'

WARNING: line over 80 characters
#34: FILE: scripts/qemu-binfmt-conf.sh:83:
+nanomipseb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf9'

ERROR: line over 90 characters
#35: FILE: scripts/qemu-binfmt-conf.sh:84:
+nanomipseb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'

total: 2 errors, 2 warnings, 34 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 85/87: gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub...
Checking PATCH 86/87: gdbstub: Add XML support for GDB for nanoMIPS...
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#34: 
new file mode 100644

total: 0 errors, 1 warnings, 157 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 87/87: qemu-doc: Add nanoMIPS-related items...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU
  2018-08-16  8:16 ` no-reply
@ 2018-08-16 11:43   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 11:43 UTC (permalink / raw)
  To: aleksandar.markovic, qemu-devel
  Cc: famz, peter.maydell, Paul Burton, Stefan Markovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude,
	Petar Jovanovic, aurelien

> From: no-reply@patchew.org <no-reply@patchew.org>
> Sent: Thursday, August 16, 2018 10:16 AM
>
> Subject: Re: [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU
> 
> Hi,
> 
> This series seems to have some coding style problems. See output below for
more information:
> 
> ...
>

We are aware of all these warnings. As Stefan explained earlier, they are all "false positives" for given circumstances, and we don't plan to fix any of the patches.

Yours,
Aleksandar

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

* Re: [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board Aleksandar Markovic
@ 2018-08-16 11:59   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 11:59 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board
> 
> From: Matthew Fortune <matthew.fortune@mips.com>
> 
> Add basic nanoMIPS boot code for Malta.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  hw/mips/mips_malta.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 60 insertions(+), 3 deletions(-)

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() for nanoMIPS
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() " Aleksandar Markovic
@ 2018-08-16 12:05   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:05 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() for nanoMIPS
> 
> From: James Hogan <james.hogan@mips.com>
> 
> We shouldn't clear M16 mode when entering an interrupt on nanoMIPS,
> otherwise we'll start interpreting the code as normal MIPS code.
> 
> Signed-off-by: James Hogan <james.hogan@mips.com>
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
> target/mips/helper.c | 3 +++
>  1 file changed, 3 insertions(+)

This code segment should be re-thought and redesigned in future cleanups. For now:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU Aleksandar Markovic
@ 2018-08-16 12:26   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:26 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> To: qemu-devel@nongnu.org
> 
> Subject: [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU
> 
> From: Stefan Markovic <smarkovic@wavecomp.com>
> 
> Add definition of the first nanoMIPS processor in QEMU.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate_init.inc.c | 39 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
> index c7ba6ee..b3320b9 100644
> --- a/target/mips/translate_init.inc.c
> +++ b/target/mips/translate_init.inc.c
> @@ -449,6 +449,45 @@ const mips_def_t mips_defs[] =
>          .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS,
>          .mmu_type = MMU_TYPE_R4000,
>      },
> +    {
> +        .name = "I7200",
> +        .CP0_PRid = 0x00010000,
> +        .CP0_Config0 = MIPS_CONFIG0 | (1 << CP0C0_MM) | (0x2 << CP0C0_AR) |
> +                        (MMU_TYPE_R4000 << CP0C0_MT),
> +        .CP0_Config1 = (1U << CP0C1_M) | (15 << CP0C1_MMU) | (2 << CP0C1_IS) |
> +                       (4 << CP0C1_IL) | (3 << CP0C1_IA) | (2 << CP0C1_DS) |
> +                       (4 << CP0C1_DL) | (3 << CP0C1_DA) | (1 << CP0C1_PC) |
> +                       (1 << CP0C1_EP),
> +        .CP0_Config2 = MIPS_CONFIG2,
> +        .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) |
> +                       (1 << CP0C3_BI) | (1 << CP0C3_SC) | (3 << CP0C3_MMAR) |
> +                       (1 << CP0C3_ISA_ON_EXC) | (1 << CP0C3_ISA) |
> +                       (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) |
> +                       (1 << CP0C3_DSP2P) | (1 << CP0C3_DSPP) |
> +                       (1 << CP0C3_CTXTC) | (1 << CP0C3_VInt) |
> +                       (1 << CP0C3_CDMM) | (1 << CP0C3_MT) | (1 << CP0C3_TL),
> +        .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
> +                       (2 << CP0C4_IE) | (1U << CP0C4_M),
> +        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB),
> +        .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
> +                                  (1 << CP0C5_UFE),
> +        .CP0_LLAddr_rw_bitmask = 0,
> +        .CP0_LLAddr_shift = 0,
> +        .SYNCI_Step = 32,
> +        .CCRes = 2,
> +        .CP0_Status_rw_bitmask = 0x3158FF1F,
> +        .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
> +                         (1U << CP0PG_RIE),
> +        .CP0_PageGrain_rw_bitmask = 0,
> +        .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
> +                    (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
> +                    (1 << FCR0_S) | (0x02 << FCR0_PRID) | (0x0 << FCR0_REV),
> +        .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008),
> +        .SEGBITS = 32,
> +        .PABITS = 32,
> +        .insn_flags = CPU_NANOMIPS32 | ASE_DSP | ASE_DSPR2 | ASE_MT,
> +        .mmu_type = MMU_TYPE_R4000,
> +    },
>  #if defined(TARGET_MIPS64)
>      {
>          .name = "R4000",
> --
> 2.7.4
> 
> 

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS Aleksandar Markovic
@ 2018-08-16 12:28   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:28 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Modify load_elf32()/load_elf64() to treat EM_NANOMIPS as equal to
> EM_MIPS.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  include/hw/elf_ops.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
> index b6e19e3..81cecaf 100644
> --- a/include/hw/elf_ops.h
> +++ b/include/hw/elf_ops.h
> @@ -327,6 +327,14 @@ static int glue(load_elf, SZ)(const char *name, int fd,
>                  }
>              }
>              break;
> +        case EM_MIPS:
> +        case EM_NANOMIPS:
> +            if ((ehdr.e_machine != EM_MIPS) &&
> +                (ehdr.e_machine != EM_NANOMIPS)) {
> +                ret = ELF_LOAD_WRONG_ARCH;
> +                goto fail;
> +            }
> +            break;
>          default:
>              if (elf_machine != ehdr.e_machine) {
>                  ret = ELF_LOAD_WRONG_ARCH;
> --
> 2.7.4
> 


Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4 Aleksandar Markovic
@ 2018-08-16 12:31   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:31 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4
> 
> From: Stefan Markovic <smarkovic@wavecomp.com>
> 
> Add emulation of DSP ASE instructions for nanoMIPS - part 4.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 363 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 363 insertions(+)

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field Aleksandar Markovic
@ 2018-08-16 12:55   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:55 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field
> 
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Value 249 is registered as valid for usage for nanoMIPS executables.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  include/elf.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/elf.h b/include/elf.h
> index 28a5a63..312f68a 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -143,6 +143,8 @@ typedef int64_t  Elf64_Sxword;
> 
>  #define EM_RISCV        243     /* RISC-V */
> 
> +#define EM_NANOMIPS     249     /* Wave Computing nanoMIPS */
> +
>  /*
>   * This is an interim value that we will use until the committee comes
>   * up with a final number.
> --
> 2.7.4 
> 

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() for nanoMIPS
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() " Aleksandar Markovic
@ 2018-08-16 12:56   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 12:56 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() for nanoMIPS
> 
> From: James Hogan <james.hogan@mips.com>
> 
> We shouldn't set the ISA bit in CP0_EPC for nanoMIPS.
> 
> Signed-off-by: James Hogan <james.hogan@mips.com>
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/helper.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target/mips/helper.c b/target/mips/helper.c
> index b25e000..b429671 100644
> --- a/target/mips/helper.c
> +++ b/target/mips/helper.c
> @@ -656,7 +656,8 @@ target_ulong exception_resume_pc (CPUMIPSState *env)
>      target_ulong bad_pc;
>      target_ulong isa_mode;
> 
> -    isa_mode = !!(env->hflags & MIPS_HFLAG_M16);
> +    isa_mode = env->hflags & MIPS_HFLAG_M16 &&
> +                !(env->insn_flags & ISA_NANOMIPS32);
>      bad_pc = env->active_tc.PC | isa_mode;
>      if (env->hflags & MIPS_HFLAG_BMASK) {
>          /* If the exception was raised from a delay slot, come back to
> --
> 2.7.4
> 


Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS Aleksandar Markovic
@ 2018-08-16 13:01   ` Aleksandar Markovic
  0 siblings, 0 replies; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-16 13:01 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, laurent, riku.voipio, philippe.mathieu.daude,
	aurelien, richard.henderson, Stefan Markovic, Petar Jovanovic,
	Paul Burton

> From: Aleksandar Markovic <aleksandar.markovic@rt-rk.com>
> Sent: Monday, August 13, 2018 7:53 PM
> 
> Subject: [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS
> 
> From: Matthew Fortune <matthew.fortune@mips.com>
> 
> ISA mode bit (LSB of address) is no longer required but is also
> masked to allow for tools transition. The flag has_isa_mode has the
> key role in the implementation.
> 
> Signed-off-by: Yongbok Kim <yongbok.kim@mips.com>
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>  target/mips/translate.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 3282fca..e4427e4 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -1471,6 +1471,7 @@ typedef struct DisasContext {
>      bool mrp;
>      bool nan2008;
>      bool abs2008;
> +    bool has_isa_mode;
>  } DisasContext;
> 
>  #define DISAS_STOP       DISAS_TARGET_0
> @@ -4674,7 +4675,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
> 
>      if (blink > 0) {
>          int post_delay = insn_bytes + delayslot_size;
> -        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
> +        int lowbit = ctx->has_isa_mode && !!(ctx->hflags & MIPS_HFLAG_M16);
> 
>          tcg_gen_movi_tl(cpu_gpr[blink],
>                          ctx->base.pc_next + post_delay + lowbit);
> @@ -11171,7 +11172,7 @@ static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
>      int bcond_compute = 0;
>      TCGv t0 = tcg_temp_new();
>      TCGv t1 = tcg_temp_new();
> -    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
> +    int m16_lowbit = ctx->has_isa_mode && ((ctx->hflags & MIPS_HFLAG_M16) != 0);
> 
>      if (ctx->hflags & MIPS_HFLAG_BMASK) {
>  #ifdef MIPS_DEBUG_DISAS
> @@ -24970,6 +24971,7 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, > CPUState *cs)
>      ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
>      ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
>      ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
> +    ctx->has_isa_mode = ((env->CP0_Config3 >> CP0C3_MMAR) & 0x7) < 3;
>      restore_cpu_state(env, ctx);
>  #ifdef CONFIG_USER_ONLY
>          ctx->mem_idx = MIPS_HFLAG_UM;
> --
> 2.7.4
> 

This patch should be renamed to reflect its real content. Also, the code segments in question should be re-examined in follow-up clean ups. That said, it isn't still show-stopper:

Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>

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

* Re: [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
  2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms Aleksandar Markovic
@ 2018-08-20  7:48   ` Timothy Baldwin
  2018-08-20  9:45     ` Aleksandar Markovic
  0 siblings, 1 reply; 120+ messages in thread
From: Timothy Baldwin @ 2018-08-20  7:48 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude, amarkovic,
	pjovanovic, aurelien

On 13/08/18 18:53, Aleksandar Markovic wrote:
> From: Aleksandar Rikalo <arikalo@wavecomp.com>
> 
> Implement support for translation of system call statx(). The
> implementation includes invoking other (more mature) syscalls
> (from the same 'stat' family) on the host side. This way,
> problems of availability of statx() on the host side are
> avoided.
> 
> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> ---
>   linux-user/syscall.c      | 121 +++++++++++++++++++++++++++++++++++++++++++++-
>   linux-user/syscall_defs.h |  38 +++++++++++++++
>   2 files changed, 158 insertions(+), 1 deletion(-)
> 


> +            if ((p == NULL) || (*((char *)p) == 0)) {
> +                /* By file descriptor */
> +                ret = get_errno(fstat(dirfd, &st));
> +                unlock_user(p, arg2, 0);
> +            } else if (*((char *)p) == '/') {
> +                /* Absolute pathname */
> +                ret = get_errno(stat(path(p), &st));
> +                unlock_user(p, arg2, 0);
> +            } else {
> +                if (dirfd == AT_FDCWD) {
> +                    /* Pathname relative to the current working directory */
> +                    ret = get_errno(stat(path(p), &st));
> +                    unlock_user(p, arg2, 0);
> +                } else {
> +                    /*
> +                     * Pathname relative to the directory referred to by the
> +                     * file descriptor dirfd
> +                     */
> +                    ret = get_errno(fstatat(dirfd, path(p), &st, flags));
> +                    unlock_user(p, arg2, 0);
> +                }
> +            }

This doesn't correctly handle the flags argument, it is ignored unless a 
relative path and directory file descriptor is provided. As such an 
implementation of lstat that uses statx will be broken.

Since fstatat exists since 2.6.16 this can be reduced to a call to fstatat.

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

* Re: [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
  2018-08-20  7:48   ` Timothy Baldwin
@ 2018-08-20  9:45     ` Aleksandar Markovic
  2018-08-29 15:38       ` Timothy Baldwin
  0 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2018-08-20  9:45 UTC (permalink / raw)
  To: Timothy Baldwin, Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, Paul Burton, Stefan Markovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude,
	Petar Jovanovic, aurelien

> From: Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
> Sent: Monday, August 20, 2018 9:48 AM
> 
> Subject: Re: [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
> 
> On 13/08/18 18:53, Aleksandar Markovic wrote:
> > From: Aleksandar Rikalo <arikalo@wavecomp.com>
> >
> > Implement support for translation of system call statx(). The
> > implementation includes invoking other (more mature) syscalls
> > (from the same 'stat' family) on the host side. This way,
> > problems of availability of statx() on the host side are
> > avoided.
> >
> > Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
> > Signed-off-by: Stefan Markovic <smarkovic@wavecomp.com>
> > ---
> >   linux-user/syscall.c      | 121 +++++++++++++++++++++++++++++++++++++++++++++-
> >   linux-user/syscall_defs.h |  38 +++++++++++++++
> >   2 files changed, 158 insertions(+), 1 deletion(-)
> >
> 
> 
> > +            if ((p == NULL) || (*((char *)p) == 0)) {
> > +                /* By file descriptor */
> > +                ret = get_errno(fstat(dirfd, &st));
> > +                unlock_user(p, arg2, 0);
> > +            } else if (*((char *)p) == '/') {
> > +                /* Absolute pathname */
> > +                ret = get_errno(stat(path(p), &st));
> > +                unlock_user(p, arg2, 0);
> > +            } else {
> > +                if (dirfd == AT_FDCWD) {
> > +                    /* Pathname relative to the current working directory */
> > +                    ret = get_errno(stat(path(p), &st));
> > +                    unlock_user(p, arg2, 0);
> > +                } else {
> > +                    /*
> > +                     * Pathname relative to the directory referred to by the
> > +                     * file descriptor dirfd
> > +                     */
> > +                    ret = get_errno(fstatat(dirfd, path(p), &st, flags));
> > +                    unlock_user(p, arg2, 0);
> > +                }
> > +            }
> 
> This doesn't correctly handle the flags argument, it is ignored unless a
> relative path and directory file descriptor is provided.

Hi, Timothy.

Agreed. The patch generally needs certain improvements wrt handling original statx() arguments. I would certianly add handling the mask argument.

> As such an implementation of lstat that uses statx will be broken.
> 
> Since fstatat exists since 2.6.16 this can be reduced to a call to fstatat.

I am not sure what you meant here. I think QEMU lstat() implementation does not use statx(). This implementation of statx() uses hosts's statx(), and, as a fallback, host's fstat(), stat(), and fstatat().

I would like to add that I think this patch should be submitted separately, out of this series.

Yours,
Aleksandar

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

* Re: [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms
  2018-08-20  9:45     ` Aleksandar Markovic
@ 2018-08-29 15:38       ` Timothy Baldwin
  0 siblings, 0 replies; 120+ messages in thread
From: Timothy Baldwin @ 2018-08-29 15:38 UTC (permalink / raw)
  To: Aleksandar Markovic, Timothy Baldwin, Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, Paul Burton, Stefan Markovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude,
	Petar Jovanovic, aurelien

On Mon, 20 Aug 2018, at 10:45 AM, Aleksandar Markovic wrote:

> > As such an implementation of lstat that uses statx will be broken.
> > 
> > Since fstatat exists since 2.6.16 this can be reduced to a call to fstatat.
> 
> I am not sure what you meant here. I think QEMU lstat() implementation 
> does not use statx(). This implementation of statx() uses hosts's 
> statx(), and, as a fallback, host's fstat(), stat(), and fstatat().

I was referring to an  implementation of lstat in a C library that is running on QEMU linux user.

> 
> I would like to add that I think this patch should be submitted 
> separately, out of this series.
> 
> Yours,
> Aleksandar
> 

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

* [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
@ 2019-07-07 20:26   ` Stefan Weil
  2019-07-08  4:40     ` Markus Armbruster
                       ` (2 more replies)
  0 siblings, 3 replies; 120+ messages in thread
From: Stefan Weil @ 2019-07-07 20:26 UTC (permalink / raw)
  To: Aleksandar Markovic, qemu-devel
  Cc: peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, laurent, philippe.mathieu.daude, amarkovic,
	pjovanovic, aurelien

Am 13.08.18 um 19:52 schrieb Aleksandar Markovic:

> From: Aleksandar Markovic <amarkovic@wavecomp.com>
>
> Mark switch fallthroughs with comments, in cases fallthroughs
> are intentional.


This is a general problem all over the QEMU code. I usually compile with 
nearly all warnings enabled and get now lots of errors with the latest 
code and after updating to gcc-8.3.0 (Debian buster). It should be 
reproducible by enabling -Werror=implicit-fallthrough.

The current situation is like this:

- Some code has fallthrough comments which are accepted by the compiler.

- Other code has fallthrough comments which are not accepted (resulting 
in a compiler error).

- Some code is correct, but has no indication that the fallthrough is 
intentional.

- There is also fallthrough code which is obviously not correct (even in 
target/mips/translate.c).


I suggest to enable -Werror=implicit-fallthrough by default and add a 
new macro to mark all fallthrough locations which are correct, but not 
accepted by the compiler.

This can be done with a definition for GCC compatible compilers in 
include/qemu/compiler.h:

#define QEMU_FALLTHROUGH __attribute__ ((fallthrough))

Then fallthrough code would look like this:

     case 1:
         do_something();
         QEMU_FALLTHROUGH;

     case 2:


VIXL_FALLTHROUGH also needs a similar definition to work with gcc-8.3.0.

Please comment. Would you prefer another macro name or a macro with 
parentheses like this:

#define QEMU_FALLTHROUGH() __attribute__ ((fallthrough))


As soon as there is consensus on the macro name and form, I can send a 
patch which adds it (but would not mind if someone else adds it).

Then I suggest that the maintainers build with the fallthrough warning 
enabled and fix all warnings, either by using the new macro or by adding 
the missing break.

Finally we can enforce the warning by default.


Another macro which is currently missing is a scanf variant of GCC_FMT_ATTR.

I suggest to add and use a GCC_SCANF_ATTR macro:

#define GCC_SCANF_ATTR(n, m) __attribute__((format(gnu_scanf, n, m)))

A more regular solution would require renaming GCC_FMT_ATTR to 
GCC_FMT_PRINTF and use GCC_FMT_SCANF for the new macro.


Regards
Stefan Weil




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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-07 20:26   ` [Qemu-devel] Handling of fall through code (was: " Stefan Weil
@ 2019-07-08  4:40     ` Markus Armbruster
  2019-07-08  4:52       ` [Qemu-devel] Handling of fall through code Stefan Weil
  2019-07-08  8:14     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
  2019-07-08  8:42     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Peter Maydell
  2 siblings, 1 reply; 120+ messages in thread
From: Markus Armbruster @ 2019-07-08  4:40 UTC (permalink / raw)
  To: Stefan Weil
  Cc: peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, amarkovic, pjovanovic, aurelien

Stefan Weil <sw@weilnetz.de> writes:

> Am 13.08.18 um 19:52 schrieb Aleksandar Markovic:
>
>> From: Aleksandar Markovic <amarkovic@wavecomp.com>
>>
>> Mark switch fallthroughs with comments, in cases fallthroughs
>> are intentional.
>
>
> This is a general problem all over the QEMU code. I usually compile
> with nearly all warnings enabled and get now lots of errors with the
> latest code and after updating to gcc-8.3.0 (Debian buster). It should
> be reproducible by enabling -Werror=implicit-fallthrough.
>
> The current situation is like this:
>
> - Some code has fallthrough comments which are accepted by the compiler.
>
> - Other code has fallthrough comments which are not accepted
> (resulting in a compiler error).
>
> - Some code is correct, but has no indication that the fallthrough is
> intentional.

I'd treat that as a bug.

> - There is also fallthrough code which is obviously not correct (even
> in target/mips/translate.c).

Bug.

> I suggest to enable -Werror=implicit-fallthrough by default and add a
> new macro to mark all fallthrough locations which are correct, but not
> accepted by the compiler.
>
> This can be done with a definition for GCC compatible compilers in
> include/qemu/compiler.h:
>
> #define QEMU_FALLTHROUGH __attribute__ ((fallthrough))
>
> Then fallthrough code would look like this:
>
>     case 1:
>         do_something();
>         QEMU_FALLTHROUGH;
>
>     case 2:
>
>
> VIXL_FALLTHROUGH also needs a similar definition to work with gcc-8.3.0.
>
> Please comment. Would you prefer another macro name or a macro with
> parentheses like this:
>
> #define QEMU_FALLTHROUGH() __attribute__ ((fallthrough))

In my opinion, the macro is no clearer than proper comments.

I'd prefer -Wimplicit-fallthrough=1 or 2.  The former makes gcc accept
any comment.  The latter makes it accept '.*falls?[ \t-]*thr(ough|u).*',
which should still match the majority of our comments.  Less churn than
the macro.

> As soon as there is consensus on the macro name and form, I can send a
> patch which adds it (but would not mind if someone else adds it).
>
> Then I suggest that the maintainers build with the fallthrough warning
> enabled and fix all warnings, either by using the new macro or by
> adding the missing break.
>
> Finally we can enforce the warning by default.
>
>
> Another macro which is currently missing is a scanf variant of GCC_FMT_ATTR.
>
> I suggest to add and use a GCC_SCANF_ATTR macro:
>
> #define GCC_SCANF_ATTR(n, m) __attribute__((format(gnu_scanf, n, m)))

Do we define our own scanf()-like functions?  If yes, decorating them
with the attribute is a good idea.

However, the gnu_ in gnu_scanf tells the compiler we're linking with the
GNU C Library, which seems unwise.  Hmm, we already use gnu_printf.
Commit 9c9e7d51bf0:

    Newer gcc versions support format gnu_printf which is
    better suited for use in QEMU than format printf
    (QEMU always uses standard format strings (even with mingw32)).

Should we limit the use of gnu_printf to #ifdef _WIN32?

> A more regular solution would require renaming GCC_FMT_ATTR to
> GCC_FMT_PRINTF and use GCC_FMT_SCANF for the new macro.

Quite some churn, but regularity matters.


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

* Re: [Qemu-devel] Handling of fall through code
  2019-07-08  4:40     ` Markus Armbruster
@ 2019-07-08  4:52       ` Stefan Weil
  2019-07-09  5:40         ` Markus Armbruster
  0 siblings, 1 reply; 120+ messages in thread
From: Stefan Weil @ 2019-07-08  4:52 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, amarkovic, pjovanovic, aurelien

Am 08.07.19 um 06:40 schrieb Markus Armbruster:

> Stefan Weil <sw@weilnetz.de> writes:
>
>> - Some code is correct, but has no indication that the fallthrough is
>> intentional.
> I'd treat that as a bug.


Sure.


>
>> - There is also fallthrough code which is obviously not correct (even
>> in target/mips/translate.c).
> Bug.


Yes, of course.


>
>> I suggest to enable -Werror=implicit-fallthrough by default and add a
>> new macro to mark all fallthrough locations which are correct, but not
>> accepted by the compiler.
>>
>> This can be done with a definition for GCC compatible compilers in
>> include/qemu/compiler.h:
>>
>> #define QEMU_FALLTHROUGH __attribute__ ((fallthrough))
>>
>> Then fallthrough code would look like this:
>>
>>      case 1:
>>          do_something();
>>          QEMU_FALLTHROUGH;
>>
>>      case 2:
>>
>>
>> VIXL_FALLTHROUGH also needs a similar definition to work with gcc-8.3.0.
>>
>> Please comment. Would you prefer another macro name or a macro with
>> parentheses like this:
>>
>> #define QEMU_FALLTHROUGH() __attribute__ ((fallthrough))
> In my opinion, the macro is no clearer than proper comments.
>
> I'd prefer -Wimplicit-fallthrough=1 or 2.  The former makes gcc accept
> any comment.  The latter makes it accept '.*falls?[ \t-]*thr(ough|u).*',
> which should still match the majority of our comments.  Less churn than
> the macro.
[...]
> Another macro which is currently missing is a scanf variant of GCC_FMT_ATTR.
>
> I suggest to add and use a GCC_SCANF_ATTR macro:
>
> #define GCC_SCANF_ATTR(n, m) __attribute__((format(gnu_scanf, n, m)))
> Do we define our own scanf()-like functions?  If yes, decorating them
> with the attribute is a good idea.


xen_device_backend_scanf, xs_node_vscanf, xs_node_scanf, 
xen_device_frontend_scanf

Maybe more. The compiler can tell you missing attributes.


>
> However, the gnu_ in gnu_scanf tells the compiler we're linking with the
> GNU C Library, which seems unwise.  Hmm, we already use gnu_printf.
> Commit 9c9e7d51bf0:
>
>      Newer gcc versions support format gnu_printf which is
>      better suited for use in QEMU than format printf
>      (QEMU always uses standard format strings (even with mingw32)).
>
> Should we limit the use of gnu_printf to #ifdef _WIN32?


No, because we don't want lots of conditional code with different format 
strings for POSIX and Windows (I made that commit 9 years ago).


>> A more regular solution would require renaming GCC_FMT_ATTR to
>> GCC_FMT_PRINTF and use GCC_FMT_SCANF for the new macro.
> Quite some churn, but regularity matters.


I could do that when adding the new macro, but would like to hear more 
opinions on that.

Thank you,

Stefan



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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-07 20:26   ` [Qemu-devel] Handling of fall through code (was: " Stefan Weil
  2019-07-08  4:40     ` Markus Armbruster
@ 2019-07-08  8:14     ` Aleksandar Markovic
  2019-07-08 12:04       ` Stefan Weil
  2019-07-08  8:42     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Peter Maydell
  2 siblings, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2019-07-08  8:14 UTC (permalink / raw)
  To: Stefan Weil
  Cc: pburton, peter.maydell, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, amarkovic, pjovanovic, aurelien

On Jul 7, 2019 10:26 PM, "Stefan Weil" <sw@weilnetz.de> wrote:
>
> Am 13.08.18 um 19:52 schrieb Aleksandar Markovic:
>
>> From: Aleksandar Markovic <amarkovic@wavecomp.com>
>>
>> Mark switch fallthroughs with comments, in cases fallthroughs
>> are intentional.
>
>
>
> This is a general problem all over the QEMU code. I usually compile with
nearly all warnings enabled and get now lots of errors with the latest code
and after updating to gcc-8.3.0 (Debian buster). It should be reproducible
by enabling -Werror=implicit-fallthrough.
>

Hi, Stefan.

Thanks for bringing this to the attention of the community.

I am sure there is a number of nasty bugs of this nature in our code - yet
to be found.

> The current situation is like this:
>
> - Some code has fallthrough comments which are accepted by the compiler.
>
> - Other code has fallthrough comments which are not accepted (resulting
in a compiler error).
>
> - Some code is correct, but has no indication that the fallthrough is
intentional.
>
> - There is also fallthrough code which is obviously not correct (even in
target/mips/translate.c).

Can you please be more specific about those cases from
target/mips/translate.c?

Yours,
Aleksandar

>
>
> I suggest to enable -Werror=implicit-fallthrough by default and add a new
macro to mark all fallthrough locations which are correct, but not accepted
by the compiler.
>
> This can be done with a definition for GCC compatible compilers in
include/qemu/compiler.h:
>
> #define QEMU_FALLTHROUGH __attribute__ ((fallthrough))
>
> Then fallthrough code would look like this:
>
>     case 1:
>         do_something();
>         QEMU_FALLTHROUGH;
>
>     case 2:
>
>
> VIXL_FALLTHROUGH also needs a similar definition to work with gcc-8.3.0.
>
> Please comment. Would you prefer another macro name or a macro with
parentheses like this:
>
> #define QEMU_FALLTHROUGH() __attribute__ ((fallthrough))
>
>
> As soon as there is consensus on the macro name and form, I can send a
patch which adds it (but would not mind if someone else adds it).
>
> Then I suggest that the maintainers build with the fallthrough warning
enabled and fix all warnings, either by using the new macro or by adding
the missing break.
>
> Finally we can enforce the warning by default.
>
>
> Another macro which is currently missing is a scanf variant of
GCC_FMT_ATTR.
>
> I suggest to add and use a GCC_SCANF_ATTR macro:
>
> #define GCC_SCANF_ATTR(n, m) __attribute__((format(gnu_scanf, n, m)))
>
> A more regular solution would require renaming GCC_FMT_ATTR to
GCC_FMT_PRINTF and use GCC_FMT_SCANF for the new macro.
>
>
> Regards
> Stefan Weil
>
>
>

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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-07 20:26   ` [Qemu-devel] Handling of fall through code (was: " Stefan Weil
  2019-07-08  4:40     ` Markus Armbruster
  2019-07-08  8:14     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
@ 2019-07-08  8:42     ` Peter Maydell
  2019-07-09  5:42       ` Markus Armbruster
  2 siblings, 1 reply; 120+ messages in thread
From: Peter Maydell @ 2019-07-08  8:42 UTC (permalink / raw)
  To: Stefan Weil
  Cc: Paul Burton, Stefan Markovic, Riku Voipio, Richard Henderson,
	QEMU Developers, Laurent Vivier, Aleksandar Markovic,
	Philippe Mathieu-Daudé,
	Aleksandar Markovic, Petar Jovanovic, Aurelien Jarno

On Sun, 7 Jul 2019 at 21:26, Stefan Weil <sw@weilnetz.de> wrote:
> This is a general problem all over the QEMU code. I usually compile with
> nearly all warnings enabled and get now lots of errors with the latest
> code and after updating to gcc-8.3.0 (Debian buster). It should be
> reproducible by enabling -Werror=implicit-fallthrough.

Coverity warns about implicit fallthroughs, and we are
currently warning-free in that department, so I think
our remaining problems are largely down to perhaps
using idioms which the compiler doesn't spot.
Being able to enable gcc implicit-fallthrough errors would
definitely be better than spotting them only after the
fact with Coverity.

> I suggest to enable -Werror=implicit-fallthrough by default and add a
> new macro to mark all fallthrough locations which are correct, but not
> accepted by the compiler.

I'm not sure why we need a macro. Our standard way to
mark fallthrough is /* fall through */, which has hundreds
of uses in the codebase. -Wimplicit-fallthrough=2 will match this,
so it seems simpler to just use that rather than to rework
how we mark fallthroughs.

Since vixl is 3rd-party code it might be easier to just
add -Wno-implicit-fallthrough to the cflags that
disas/libvixl/Makefile.objs sets up for building those files.
(We should check also for newer libvixl and/or suggest
something upstream that works with gcc.)

thanks
-- PMM


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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-08  8:14     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
@ 2019-07-08 12:04       ` Stefan Weil
  2019-07-08 12:08         ` Daniel P. Berrangé
  2019-07-08 19:39         ` Aleksandar Markovic
  0 siblings, 2 replies; 120+ messages in thread
From: Stefan Weil @ 2019-07-08 12:04 UTC (permalink / raw)
  To: Aleksandar Markovic, Daniel P. Berrange
  Cc: pburton, peter.maydell, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, amarkovic, pjovanovic, aurelien

Am 08.07.2019 um 10:14 schrieb Aleksandar Markovic:
>
> On Jul 7, 2019 10:26 PM, "Stefan Weil" <sw@weilnetz.de
> <mailto:sw@weilnetz.de>> wrote:
> > - There is also fallthrough code which is obviously not correct
> (even in target/mips/translate.c).
>
> Can you please be more specific about those cases from
> target/mips/translate.c?
>

Hi Aleksandar,

this is the list of warnings for target/mips/translate.c:

/home/debian/src/github/qemu/qemu/target/mips/translate.c:10047:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:10056:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:20138:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:20144:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:6739:9:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:9820:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]
/home/debian/src/github/qemu/qemu/target/mips/translate.c:9829:13:
warning: this statement may fall through [-Wimplicit-fallthrough=]

I have built using

    ../configure --disable-werror '--extra-cflags=-Wextra
-Wimplicit-fallthrough=2'

The build process produced warnings for 79 fallthrough locations. See
build protocol:

    https://qemu.weilnetz.de/results/build-20190708.txt (116 MiB !)

Sometimes the fallthrough comment is misplaced in the following case
statement or followed by code, so the compiler (correctly) won't accept
it. Maybe there exist also fallthrough comments although there is no
fallthrough code.

The protocol also shows 18 warnings [-Wcast-function-type] which might
indicate bugs:

/home/debian/src/github/qemu/qemu/chardev/char-fe.c:372:32: warning:
cast between incompatible function types from ‘GIOFunc’ {aka ‘int
(*)(struct _GIOChannel *, enum <anonymous>,  void *)’} to ‘gboolean
(*)(void *)’ {aka ‘int (*)(void *)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/chardev/char-io.c:92:20: warning: cast
between incompatible function types from ‘QIOChannelFunc’ {aka ‘int
(*)(struct QIOChannel *, enum <anonymous>,  void *)’} to ‘gboolean
(*)(void *)’ {aka ‘int (*)(void *)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/chardev/char-socket.c:606:42: warning:
cast between incompatible function types from ‘gboolean (*)(QIOChannel
*, GIOCondition,  void *)’ {aka ‘int (*)(struct QIOChannel *, enum
<anonymous>,  void *)’} to ‘gboolean (*)(void *)’ {aka ‘int (*)(void
*)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/contrib/libvhost-user/libvhost-user-glib.c:59:6:
warning: cast between incompatible function types from ‘GSourceFunc’
{aka ‘int (*)(void *)’} to ‘void (*)(VuDev *, int,  void *)’ {aka ‘void
(*)(struct VuDev *, int,  void *)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/contrib/libvhost-user/libvhost-user-glib.c:85:33:
warning: cast between incompatible function types from ‘vu_watch_cb’
{aka ‘void (*)(struct VuDev *, int,  void *)’} to ‘gboolean (*)(void *)’
{aka ‘int (*)(void *)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel-buffer.c:182:27: warning:
cast between incompatible function types from ‘GSourceFunc’ {aka ‘int
(*)(void *)’} to ‘gboolean (*)(QIOChannel *, GIOCondition,  void *)’
{aka ‘int (*)(struct QIOChannel *, enum <anonymous>,  void *)’}
[-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel.c:315:35: warning: cast
between incompatible function types from ‘QIOChannelFunc’ {aka ‘int
(*)(struct QIOChannel *, enum <anonymous>,  void *)’} to ‘gboolean
(*)(void *)’ {aka ‘int (*)(void *)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel.c:507:27: warning: cast
between incompatible function types from ‘gboolean (*)(QIOChannel *,
GIOCondition,  void *)’ {aka ‘int (*)(struct QIOChannel *, enum
<anonymous>,  void *)’} to ‘gboolean (*)(void *)’ {aka ‘int (*)(void
*)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel-watch.c:216:27: warning:
cast between incompatible function types from ‘GSourceFunc’ {aka ‘int
(*)(void *)’} to ‘gboolean (*)(QIOChannel *, GIOCondition,  void *)’
{aka ‘int (*)(struct QIOChannel *, enum <anonymous>,  void *)’}
[-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel-watch.c:81:27: warning:
cast between incompatible function types from ‘GSourceFunc’ {aka ‘int
(*)(void *)’} to ‘gboolean (*)(QIOChannel *, GIOCondition,  void *)’
{aka ‘int (*)(struct QIOChannel *, enum <anonymous>,  void *)’}
[-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/channel-websock.c:1258:27: warning:
cast between incompatible function types from ‘GSourceFunc’ {aka ‘int
(*)(void *)’} to ‘gboolean (*)(QIOChannel *, GIOCondition,  void *)’
{aka ‘int (*)(struct QIOChannel *, enum <anonymous>,  void *)’}
[-Wcast-function-type]
/home/debian/src/github/qemu/qemu/io/net-listener.c:236:31: warning:
cast between incompatible function types from ‘gboolean (*)(QIOChannel
*, GIOCondition,  void *)’ {aka ‘int (*)(struct QIOChannel *, enum
<anonymous>,  void *)’} to ‘gboolean (*)(void *)’ {aka ‘int (*)(void
*)’} [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:2850:16:
warning: cast between incompatible function types from ‘void (*)(struct
TCGv_ptr_d *, struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_i32_d *)’ to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *)’ [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:2850:16:
warning: cast between incompatible function types from ‘void (*)(struct
TCGv_ptr_d *, struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_i64_d *)’ to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *)’ [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:2851:16:
warning: cast between incompatible function types from ‘void (*)(struct
TCGv_ptr_d *, struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_i32_d *)’ to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *)’ [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:2851:16:
warning: cast between incompatible function types from ‘void (*)(struct
TCGv_ptr_d *, struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_i64_d *)’ to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *)’ [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:4469:27:
warning: cast between incompatible function types from ‘SSEFunc_0_epp’
{aka ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_ptr_d *)’} to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *, struct TCGv_i32_d *)’ [-Wcast-function-type]
/home/debian/src/github/qemu/qemu/target/i386/translate.c:4469:27:
warning: cast between incompatible function types from ‘SSEFunc_0_epp’
{aka ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *, struct
TCGv_ptr_d *)’} to ‘void (*)(struct TCGv_ptr_d *, struct TCGv_ptr_d *,
struct TCGv_ptr_d *, struct TCGv_i64_d *)’ [-Wcast-function-type]

Daniel, here is one possible fix (I am not sure how important that is):

diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
index 96f186f442..074cece468 100644
--- a/crypto/hash-nettle.c
+++ b/crypto/hash-nettle.c
@@ -28,10 +28,10 @@
 
 typedef void (*qcrypto_nettle_init)(void *ctx);
 typedef void (*qcrypto_nettle_write)(void *ctx,
-                                     unsigned int len,
+                                     size_t len,
                                      const uint8_t *buf);
 typedef void (*qcrypto_nettle_result)(void *ctx,
-                                      unsigned int len,
+                                      size_t len,
                                       uint8_t *buf);

Regards
Stefan


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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-08 12:04       ` Stefan Weil
@ 2019-07-08 12:08         ` Daniel P. Berrangé
  2019-07-08 19:39         ` Aleksandar Markovic
  1 sibling, 0 replies; 120+ messages in thread
From: Daniel P. Berrangé @ 2019-07-08 12:08 UTC (permalink / raw)
  To: Stefan Weil
  Cc: pburton, peter.maydell, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, aurelien, amarkovic, pjovanovic,
	Aleksandar Markovic

On Mon, Jul 08, 2019 at 02:04:27PM +0200, Stefan Weil wrote:
> Am 08.07.2019 um 10:14 schrieb Aleksandar Markovic:
> >
> > On Jul 7, 2019 10:26 PM, "Stefan Weil" <sw@weilnetz.de
> > <mailto:sw@weilnetz.de>> wrote:
> > > - There is also fallthrough code which is obviously not correct
> > (even in target/mips/translate.c).
> >
> > Can you please be more specific about those cases from
> > target/mips/translate.c?
> >
> 
> Daniel, here is one possible fix (I am not sure how important that is):
> 
> diff --git a/crypto/hash-nettle.c b/crypto/hash-nettle.c
> index 96f186f442..074cece468 100644
> --- a/crypto/hash-nettle.c
> +++ b/crypto/hash-nettle.c
> @@ -28,10 +28,10 @@
>  
>  typedef void (*qcrypto_nettle_init)(void *ctx);
>  typedef void (*qcrypto_nettle_write)(void *ctx,
> -                                     unsigned int len,
> +                                     size_t len,
>                                       const uint8_t *buf);
>  typedef void (*qcrypto_nettle_result)(void *ctx,
> -                                      unsigned int len,
> +                                      size_t len,
>                                        uint8_t *buf);

This is a case of nettle changing its API contract in version 3.

We dealt with it in cipher-nettle.c already by creating a cipher_length_t
type. need to copy this solution into the hash code, unless perhaps we
can drop older nettle per out platform support matrix.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-08 12:04       ` Stefan Weil
  2019-07-08 12:08         ` Daniel P. Berrangé
@ 2019-07-08 19:39         ` Aleksandar Markovic
  2019-07-09  8:25           ` Peter Maydell
  1 sibling, 1 reply; 120+ messages in thread
From: Aleksandar Markovic @ 2019-07-08 19:39 UTC (permalink / raw)
  To: Stefan Weil, Aleksandar Markovic, Daniel P. Berrange
  Cc: Paul Burton, peter.maydell, riku.voipio, richard.henderson,
	qemu-devel, laurent, Aleksandar Markovic, philippe.mathieu.daude,
	Petar Jovanovic, aurelien

> ...this is the list of warnings for target/mips/translate.c:

> /home/debian/src/github/qemu/qemu/target/mips/translate.c:10047:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:10056:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:20138:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:20144:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:6739:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:9820:13: warning: this statement may fall through [-Wimplicit-fallthrough=]
> /home/debian/src/github/qemu/qemu/target/mips/translate.c:9829:13: warning: this statement may fall through [-Wimplicit-fallthrough=]

They are all real issues. Two of them are cases of missing '/* fall through */' (I plan to send fixes for them in 4.2 timeframe) and five of them are cases of missing 'break' (I plan to send corresponding fixes for 4.1 in few days).

Last time I checked gcc 'implicit-fallthrough' option was around five months ago, and meanwhile some new code with missing annotation sneaked in. However, there is some news - it appears to me that gcc 8 improved that feature significantly compared to gcc 7: some cases now detected by gcc 8 are simply went undetected by gcc 7. It appears that at least some of such cases are ignored by Coverity too.

Great info! Thanks again!!

Aleksandar




> Stefan


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

* Re: [Qemu-devel] Handling of fall through code
  2019-07-08  4:52       ` [Qemu-devel] Handling of fall through code Stefan Weil
@ 2019-07-09  5:40         ` Markus Armbruster
  0 siblings, 0 replies; 120+ messages in thread
From: Markus Armbruster @ 2019-07-09  5:40 UTC (permalink / raw)
  To: Stefan Weil
  Cc: peter.maydell, pburton, smarkovic, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, amarkovic, pjovanovic, aurelien

Stefan Weil <sw@weilnetz.de> writes:

> Am 08.07.19 um 06:40 schrieb Markus Armbruster:
>
[...]
>> However, the gnu_ in gnu_scanf tells the compiler we're linking with the
>> GNU C Library, which seems unwise.  Hmm, we already use gnu_printf.
>> Commit 9c9e7d51bf0:
>>
>>      Newer gcc versions support format gnu_printf which is
>>      better suited for use in QEMU than format printf
>>      (QEMU always uses standard format strings (even with mingw32)).
>>
>> Should we limit the use of gnu_printf to #ifdef _WIN32?
>
>
> No, because we don't want lots of conditional code with different
> format strings for POSIX and Windows (I made that commit 9 years ago).

I'm afraid I failed to express myself clearly.

I'm not proposing to conditionally use MS conversion specifications
instead of ISO C ones.  That's mess we can do without indeed.

The documentation of gnu_printf vs. plain printf format attribute in
"The GNU Compiler Collection" made me expect gnu_printf accepts
extensions over ISO C provided by glibc, while plain printf rejects
them.  Since we don't require glibc, catching use of extensions would be
useful, even if we still had to use gnu_printf with MinGW.  However, it
appears not to be the case (I tried on Fedora 30).

[...]


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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-08  8:42     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Peter Maydell
@ 2019-07-09  5:42       ` Markus Armbruster
  0 siblings, 0 replies; 120+ messages in thread
From: Markus Armbruster @ 2019-07-09  5:42 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Paul Burton, Stefan Markovic, Stefan Weil, Riku Voipio,
	Richard Henderson, QEMU Developers, Laurent Vivier,
	Aleksandar Markovic, Philippe Mathieu-Daudé,
	Aleksandar Markovic, Petar Jovanovic, Aurelien Jarno

Peter Maydell <peter.maydell@linaro.org> writes:

> On Sun, 7 Jul 2019 at 21:26, Stefan Weil <sw@weilnetz.de> wrote:
>> This is a general problem all over the QEMU code. I usually compile with
>> nearly all warnings enabled and get now lots of errors with the latest
>> code and after updating to gcc-8.3.0 (Debian buster). It should be
>> reproducible by enabling -Werror=implicit-fallthrough.
>
> Coverity warns about implicit fallthroughs, and we are
> currently warning-free in that department, so I think
> our remaining problems are largely down to perhaps
> using idioms which the compiler doesn't spot.
> Being able to enable gcc implicit-fallthrough errors would
> definitely be better than spotting them only after the
> fact with Coverity.
>
>> I suggest to enable -Werror=implicit-fallthrough by default and add a
>> new macro to mark all fallthrough locations which are correct, but not
>> accepted by the compiler.
>
> I'm not sure why we need a macro. Our standard way to
> mark fallthrough is /* fall through */, which has hundreds
> of uses in the codebase. -Wimplicit-fallthrough=2 will match this,
> so it seems simpler to just use that rather than to rework
> how we mark fallthroughs.
>
> Since vixl is 3rd-party code it might be easier to just
> add -Wno-implicit-fallthrough to the cflags that
> disas/libvixl/Makefile.objs sets up for building those files.
> (We should check also for newer libvixl and/or suggest
> something upstream that works with gcc.)

Concur.


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

* Re: [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments
  2019-07-08 19:39         ` Aleksandar Markovic
@ 2019-07-09  8:25           ` Peter Maydell
  2019-07-21 16:39             ` [Qemu-devel] Handling of fall through code Stefan Weil
  0 siblings, 1 reply; 120+ messages in thread
From: Peter Maydell @ 2019-07-09  8:25 UTC (permalink / raw)
  To: Aleksandar Markovic
  Cc: Paul Burton, Daniel P. Berrange, Stefan Weil, riku.voipio,
	richard.henderson, qemu-devel, laurent, Aleksandar Markovic,
	philippe.mathieu.daude, aurelien, Petar Jovanovic,
	Aleksandar Markovic

On Mon, 8 Jul 2019 at 20:39, Aleksandar Markovic <amarkovic@wavecomp.com> wrote:
> They are all real issues. Two of them are cases of missing
> '/* fall through */' (I plan to send fixes for them in 4.2 timeframe)
> and five of them are cases of missing 'break' (I plan to send
> corresponding fixes for 4.1 in few days).

Adding missing /* fall through */ comments would be fine as
a patch for 4.1 rc1 if you liked, though you can of course
wait til 4.2 if that's better for you.

thanks
-- PMM


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

* Re: [Qemu-devel] Handling of fall through code
  2019-07-09  8:25           ` Peter Maydell
@ 2019-07-21 16:39             ` Stefan Weil
  2019-07-22  9:09               ` Peter Maydell
  0 siblings, 1 reply; 120+ messages in thread
From: Stefan Weil @ 2019-07-21 16:39 UTC (permalink / raw)
  To: Peter Maydell, Aleksandar Markovic
  Cc: Paul Burton, Daniel P. Berrange, riku.voipio, richard.henderson,
	qemu-devel, laurent, Aleksandar Markovic, philippe.mathieu.daude,
	aurelien, Petar Jovanovic, Aleksandar Markovic

Am 09.07.2019 um 10:25 schrieb Peter Maydell:
> On Mon, 8 Jul 2019 at 20:39, Aleksandar Markovic <amarkovic@wavecomp.com> wrote:
>> They are all real issues. Two of them are cases of missing
>> '/* fall through */' (I plan to send fixes for them in 4.2 timeframe)
>> and five of them are cases of missing 'break' (I plan to send
>> corresponding fixes for 4.1 in few days).
> Adding missing /* fall through */ comments would be fine as
> a patch for 4.1 rc1 if you liked, though you can of course
> wait til 4.2 if that's better for you.
>
> thanks
> -- PMM


Peter, is this fall through for ARM correct?

https://github.com/qemu/qemu/blob/master/target/arm/helper.c#L7958

It looks rather suspicious and is one of the remaining related compiler
warnings.

Regards
Stefan



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

* Re: [Qemu-devel] Handling of fall through code
  2019-07-21 16:39             ` [Qemu-devel] Handling of fall through code Stefan Weil
@ 2019-07-22  9:09               ` Peter Maydell
  0 siblings, 0 replies; 120+ messages in thread
From: Peter Maydell @ 2019-07-22  9:09 UTC (permalink / raw)
  To: Stefan Weil
  Cc: Paul Burton, Daniel P. Berrange, riku.voipio, richard.henderson,
	qemu-devel, laurent, Aleksandar Markovic, philippe.mathieu.daude,
	aurelien, Aleksandar Markovic, Petar Jovanovic,
	Aleksandar Markovic

On Sun, 21 Jul 2019 at 17:39, Stefan Weil <sw@weilnetz.de> wrote:
> Peter, is this fall through for ARM correct?
>
> https://github.com/qemu/qemu/blob/master/target/arm/helper.c#L7958
>
> It looks rather suspicious and is one of the remaining related compiler
> warnings.

It's wrong, and Philippe posted a patch for it a day or two ago:

https://patchew.org/QEMU/20190719111451.12406-1-philmd@redhat.com/

thanks
-- PMM


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

end of thread, other threads:[~2019-07-22  9:09 UTC | newest]

Thread overview: 120+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-13 17:52 [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 01/87] MAINTAINERS: Update target/mips maintainer's email addresses Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 02/87] target/mips: Avoid case statements formulated by ranges - part 1 Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 03/87] target/mips: Avoid case statements formulated by ranges - part 2 Aleksandar Markovic
2018-08-14 11:13   ` Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
2019-07-07 20:26   ` [Qemu-devel] Handling of fall through code (was: " Stefan Weil
2019-07-08  4:40     ` Markus Armbruster
2019-07-08  4:52       ` [Qemu-devel] Handling of fall through code Stefan Weil
2019-07-09  5:40         ` Markus Armbruster
2019-07-08  8:14     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Aleksandar Markovic
2019-07-08 12:04       ` Stefan Weil
2019-07-08 12:08         ` Daniel P. Berrangé
2019-07-08 19:39         ` Aleksandar Markovic
2019-07-09  8:25           ` Peter Maydell
2019-07-21 16:39             ` [Qemu-devel] Handling of fall through code Stefan Weil
2019-07-22  9:09               ` Peter Maydell
2019-07-08  8:42     ` [Qemu-devel] Handling of fall through code (was: [PATCH v8 04/87] target/mips: Mark switch fallthroughs with interpretable comments Peter Maydell
2019-07-09  5:42       ` Markus Armbruster
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 05/87] target/mips: Fix two instances of shadow variables Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 06/87] target/mips: Update some CP0 registers bit definitions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 07/87] target/mips: Add CP0 BadInstrX register Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 08/87] target/mips: Add support for availability control via bit XNP Aleksandar Markovic
2018-08-14 12:23   ` Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 09/87] target/mips: Add support for availability control via bit MT Aleksandar Markovic
2018-08-13 18:13   ` Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 10/87] target/mips: Fix MT ASE instructions' availability control Aleksandar Markovic
2018-08-13 18:23   ` Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 11/87] target/mips: Implement CP0 Config1.WR bit functionality Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 12/87] target/mips: Don't update BadVAddr register in Debug Mode Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 13/87] target/mips: Check ELPA flag only in some cases of MFHC0 and MTHC0 Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 14/87] target/mips: Add gen_op_addr_addi() Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 15/87] elf: Remove duplicate preprocessor constant definition Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 16/87] elf: Add ELF flags for MIPS machine variants Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 17/87] linux-user: Update MIPS syscall numbers up to kernel 4.18 headers Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 18/87] linux-user: Add preprocessor availability control to some syscalls Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 19/87] qemu-doc: Amend MIPS-related items Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 20/87] target/mips: Add preprocessor constants for nanoMIPS Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 21/87] target/mips: Add nanoMIPS base instruction set opcodes Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 22/87] target/mips: Add nanoMIPS DSP ASE opcodes Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 23/87] target/mips: Add placeholder and invocation of decode_nanomips_opc() Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 24/87] target/mips: Add nanoMIPS decoding and extraction utilities Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 25/87] target/mips: Add emulation of nanoMIPS 16-bit arithmetic instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 26/87] target/mips: Add emulation of nanoMIPS 16-bit branch instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 27/87] target/mips: Add emulation of nanoMIPS 16-bit shift instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 28/87] target/mips: Add emulation of nanoMIPS 16-bit misc instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 29/87] target/mips: Add emulation of nanoMIPS 16-bit load and store instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 30/87] target/mips: Add emulation of nanoMIPS 16-bit logic instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 31/87] target/mips: Add emulation of nanoMIPS 16-bit save and restore instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 32/87] target/mips: Add emulation of some common nanoMIPS 32-bit instructions Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 33/87] target/mips: Add emulation of nanoMIPS instructions MOVE.P and MOVE.PREV Aleksandar Markovic
2018-08-13 17:52 ` [Qemu-devel] [PATCH v8 34/87] target/mips: Add emulation of nanoMIPS 48-bit instructions Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 35/87] target/mips: Add emulation of nanoMIPS FP instructions Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 36/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32a0) Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 37/87] target/mips: Add emulation of misc nanoMIPS instructions (pool32axf) Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 38/87] target/mips: Add emulation of misc nanoMIPS instructions (p_lsx) Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 39/87] target/mips: Implement emulation of nanoMIPS ROTX instruction Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 40/87] target/mips: Implement emulation of nanoMIPS EXTW instruction Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 41/87] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 42/87] target/mips: Implement emulation of nanoMIPS LLWP/SCWP pair Aleksandar Markovic
2018-08-14 12:20   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 43/87] target/mips: Add emulation of nanoMIPS 32-bit branch instructions Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 44/87] target/mips: Implement MT ASE support for nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 45/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 1 Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 46/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 2 Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 47/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 3 Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 48/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 4 Aleksandar Markovic
2018-08-16 12:31   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 49/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 5 Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 50/87] target/mips: Add emulation of DSP ASE for nanoMIPS - part 6 Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 51/87] disas: Add support for microMIPS and nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 52/87] target/mips: Add handling of branch delay slots for nanoMIPS Aleksandar Markovic
2018-08-16 13:01   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 53/87] target/mips: Add updating BadInstr, BadInstrP, BadInstrX " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 54/87] target/mips: Adjust exception_resume_pc() " Aleksandar Markovic
2018-08-16 12:56   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 55/87] target/mips: Adjust set_hflags_for_handler() " Aleksandar Markovic
2018-08-16 12:05   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 56/87] target/mips: Adjust set_pc() " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 57/87] target/mips: Fix ERET/ERETNC behavior related to ADEL exception Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 58/87] elf: Add EM_NANOMIPS value as a valid one for e_machine field Aleksandar Markovic
2018-08-16 12:55   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 59/87] elf: Relax MIPS' elf_check_arch() to accept EM_NANOMIPS too Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 60/87] elf: Don't check FCR31_NAN2008 bit for nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 61/87] elf: On elf loading, treat both EM_MIPS and EM_NANOMIPS as legal for MIPS Aleksandar Markovic
2018-08-16 12:28   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 62/87] mips_malta: Add basic nanoMIPS boot code for Malta board Aleksandar Markovic
2018-08-16 11:59   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 63/87] mips_malta: Add setting up GT64120 BARs to the nanoMIPS bootloader Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 64/87] mips_malta: Fix semihosting argument passing for nanoMIPS bare metal Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 65/87] target/mips: Add definition of nanoMIPS I7200 CPU Aleksandar Markovic
2018-08-16 12:26   ` Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 66/87] elf: Add nanoMIPS specific variations in ELF header fields Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 67/87] linux-user: Add syscall numbers for nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 68/87] linux-user: Add target_signal.h header " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 69/87] linux-user: Add termbits.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 70/87] linux-user: Update syscall_defs.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 71/87] linux-user: Add target_fcntl.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 72/87] linux-user: Add sockbits.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 73/87] linux-user: Add target_syscall.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 74/87] linux-user: Add target_cpu.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 75/87] linux-user: Add target_structs.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 76/87] linux-user: Add target_elf.h " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 77/87] linux-user: Add signal.c " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 78/87] linux-user: Add support for nanoMIPS signal trampoline Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 79/87] linux-user: Add cpu_loop.c for nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 80/87] linux-user: Amend support for sigaction() syscall " Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 81/87] linux-user: Add support for statx() syscall for all platforms Aleksandar Markovic
2018-08-20  7:48   ` Timothy Baldwin
2018-08-20  9:45     ` Aleksandar Markovic
2018-08-29 15:38       ` Timothy Baldwin
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 82/87] linux-user: Add support for nanoMIPS core files Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 83/87] linux-user: Add nanoMIPS linux user mode configuration support Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 84/87] linux-user: Add nanoMIPS support in scripts/qemu-binfmt-conf.sh Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 85/87] gdbstub: Disable handling of nanoMIPS ISA bit in the MIPS gdbstub Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 86/87] gdbstub: Add XML support for GDB for nanoMIPS Aleksandar Markovic
2018-08-13 17:53 ` [Qemu-devel] [PATCH v8 87/87] qemu-doc: Add nanoMIPS-related items Aleksandar Markovic
2018-08-14 15:52 ` [Qemu-devel] [PATCH v8 00/87] Add nanoMIPS support to QEMU Aleksandar Markovic
2018-08-16  8:16 ` no-reply
2018-08-16 11:43   ` Aleksandar Markovic

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.