aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--backends/hostmem-file.c10
-rw-r--r--block.c9
-rw-r--r--block/iscsi.c2
-rw-r--r--block/qcow2.c4
-rw-r--r--block/qed.c4
-rw-r--r--block/rbd.c4
-rw-r--r--block/sheepdog.c2
-rw-r--r--block/vpc.c8
-rw-r--r--blockdev.c27
-rw-r--r--chardev/char-pty.c2
-rw-r--r--chardev/char.c2
-rwxr-xr-xconfigure187
-rw-r--r--cpus.c8
-rw-r--r--crypto/Makefile.objs8
-rw-r--r--crypto/init.c23
-rw-r--r--crypto/tlscredsx509.c21
-rw-r--r--crypto/tlssession.c8
-rw-r--r--crypto/xts.c200
-rw-r--r--default-configs/alpha-softmmu.mak1
-rw-r--r--default-configs/i386-softmmu.mak3
-rw-r--r--default-configs/ppc64-softmmu.mak3
-rw-r--r--default-configs/sparc64-softmmu.mak1
-rw-r--r--device-hotplug.c5
-rw-r--r--disas/Makefile.objs1
-rw-r--r--disas/nanomips.cpp22242
-rw-r--r--disas/nanomips.h1099
-rw-r--r--fsdev/qemu-fsdev-dummy.c2
-rw-r--r--fsdev/qemu-fsdev.c12
-rw-r--r--fsdev/qemu-fsdev.h2
-rw-r--r--hw/9pfs/9p-handle.c6
-rw-r--r--hw/9pfs/9p-local.c4
-rw-r--r--hw/9pfs/xen-9p-backend.c7
-rw-r--r--hw/Makefile.objs2
-rw-r--r--hw/alpha/typhoon.c13
-rw-r--r--hw/arm/boot.c18
-rw-r--r--hw/core/Makefile.objs3
-rw-r--r--hw/core/machine.c2
-rw-r--r--hw/core/null-machine.c2
-rw-r--r--hw/display/cg3.c2
-rw-r--r--hw/display/tcx.c2
-rw-r--r--hw/hppa/dino.c7
-rw-r--r--hw/i386/pc.c11
-rw-r--r--hw/intc/armv7m_nvic.c12
-rw-r--r--hw/intc/ioapic.c8
-rw-r--r--hw/intc/xics.c15
-rw-r--r--hw/intc/xics_kvm.c7
-rw-r--r--hw/isa/Makefile.objs3
-rw-r--r--hw/mem/Makefile.objs4
-rw-r--r--hw/mem/memory-device.c103
-rw-r--r--hw/mem/nvdimm.c9
-rw-r--r--hw/mem/pc-dimm.c84
-rw-r--r--hw/mem/trace-events5
-rw-r--r--hw/mips/gt64xxx_pci.c18
-rw-r--r--hw/mips/mips_malta.c13
-rw-r--r--hw/misc/ivshmem.c4
-rw-r--r--hw/net/cadence_gem.c9
-rw-r--r--hw/net/etraxfs_eth.c44
-rw-r--r--hw/net/lan9118.c9
-rw-r--r--hw/net/lance.c8
-rw-r--r--hw/net/milkymist-minimac2.c9
-rw-r--r--hw/net/mipsnet.c9
-rw-r--r--hw/net/opencores_eth.c8
-rw-r--r--hw/net/smc91c111.c8
-rw-r--r--hw/net/stellaris_enet.c15
-rw-r--r--hw/net/virtio-net.c8
-rw-r--r--hw/net/xgmac.c9
-rw-r--r--hw/pci-host/bonito.c9
-rw-r--r--hw/ppc/pnv_core.c4
-rw-r--r--hw/ppc/spapr.c29
-rw-r--r--hw/ppc/spapr_pci.c7
-rw-r--r--hw/riscv/sifive_clint.c8
-rw-r--r--hw/riscv/sifive_plic.c4
-rw-r--r--hw/riscv/sifive_u.c4
-rw-r--r--hw/riscv/spike.c6
-rw-r--r--hw/riscv/virt.c6
-rw-r--r--hw/sd/ssi-sd.c2
-rw-r--r--hw/sh4/sh_pci.c20
-rw-r--r--hw/smbios/smbios.c90
-rw-r--r--hw/sparc64/niagara.c4
-rw-r--r--hw/ssi/xilinx_spi.c9
-rw-r--r--hw/timer/aspeed_timer.c3
-rw-r--r--hw/timer/sun4v-rtc.c23
-rw-r--r--hw/timer/trace-events6
-rw-r--r--hw/usb/bus.c5
-rw-r--r--hw/vfio/pci-quirks.c4
-rw-r--r--hw/vfio/pci.c25
-rw-r--r--hw/vfio/platform.c6
-rw-r--r--hw/virtio/virtio-pci.c4
-rw-r--r--hw/xen/xen_pt.c2
-rw-r--r--include/disas/bfd.h1
-rw-r--r--include/exec/poison.h1
-rw-r--r--include/hw/mem/memory-device.h74
-rw-r--r--include/hw/mem/pc-dimm.h10
-rw-r--r--include/hw/vfio/vfio-common.h3
-rw-r--r--include/qapi/error.h14
-rw-r--r--include/qapi/qmp/qerror.h6
-rw-r--r--include/qemu/osdep.h12
-rw-r--r--include/sysemu/blockdev.h3
-rw-r--r--include/sysemu/numa.h1
-rw-r--r--include/sysemu/tpm.h2
-rw-r--r--include/ui/console.h2
-rw-r--r--linux-user/aarch64/signal.c4
-rw-r--r--linux-user/elfload.c58
-rw-r--r--linux-user/ioctls.h46
-rw-r--r--linux-user/mips/target_elf.h3
-rw-r--r--linux-user/syscall.c190
-rw-r--r--linux-user/syscall_defs.h28
-rw-r--r--linux-user/syscall_types.h68
-rw-r--r--migration/migration.c12
-rw-r--r--migration/savevm.c8
-rw-r--r--net/l2tpv3.c25
-rw-r--r--net/slirp.c21
-rw-r--r--net/socket.c4
-rw-r--r--numa.c21
-rw-r--r--po/Makefile2
-rw-r--r--qapi/misc.json2
-rw-r--r--qapi/net.json5
-rw-r--r--qemu-deprecated.texi12
-rw-r--r--qemu-io.c8
-rw-r--r--qemu-nbd.c14
-rw-r--r--qemu-options.hx7
-rw-r--r--qemu-seccomp.c18
-rw-r--r--qom/object_interfaces.c4
-rwxr-xr-xscripts/check-qerror.sh22
-rw-r--r--scripts/coccinelle/use-error_fatal.cocci20
-rw-r--r--scripts/qemu.py6
-rw-r--r--slirp/bootp.c45
-rw-r--r--slirp/bootp.h1
-rw-r--r--slirp/libslirp.h1
-rw-r--r--slirp/slirp.c2
-rw-r--r--slirp/slirp.h1
-rw-r--r--stubs/tpm.c3
-rw-r--r--target/arm/cpu.c238
-rw-r--r--target/arm/cpu.h221
-rw-r--r--target/arm/cpu64.c148
-rw-r--r--target/arm/helper.c389
-rw-r--r--target/arm/internals.h45
-rw-r--r--target/arm/kvm.c60
-rw-r--r--target/arm/kvm32.c13
-rw-r--r--target/arm/kvm64.c15
-rw-r--r--target/arm/kvm_arm.h24
-rw-r--r--target/arm/machine.c25
-rw-r--r--target/arm/op_helper.c2
-rw-r--r--target/arm/translate-a64.c715
-rw-r--r--target/arm/translate.c1445
-rw-r--r--target/arm/translate.h21
-rw-r--r--target/i386/cpu.c17
-rw-r--r--target/mips/cpu.c13
-rw-r--r--target/mips/mips-defs.h3
-rw-r--r--target/mips/translate.c1003
-rw-r--r--target/mips/translate_init.inc.c59
-rw-r--r--target/ppc/translate_init.inc.c4
-rw-r--r--target/riscv/Makefile.objs2
-rw-r--r--target/riscv/cpu.c6
-rw-r--r--target/riscv/cpu.h22
-rw-r--r--target/riscv/cpu_bits.h683
-rw-r--r--target/riscv/cpu_helper.c (renamed from target/riscv/helper.c)35
-rw-r--r--target/riscv/op_helper.c34
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/benchmark-crypto-cipher.c149
-rw-r--r--tests/cpu-plug-test.c18
-rw-r--r--tests/crypto-tls-x509-helpers.h3
-rwxr-xr-xtests/docker/dockerfiles/debian-bootstrap.pre4
-rwxr-xr-xtests/docker/test-mingw3
-rw-r--r--tests/migration-test.c16
-rw-r--r--tests/qemu-iotests/049.out12
-rw-r--r--tests/tcg/mips/mipsr5900/Makefile30
-rw-r--r--tests/tcg/mips/mipsr5900/div1.c73
-rw-r--r--tests/tcg/mips/mipsr5900/divu1.c48
-rw-r--r--tests/tcg/mips/mipsr5900/mflohi1.c35
-rw-r--r--tests/tcg/mips/mipsr5900/mtlohi1.c40
-rw-r--r--tests/tcg/mips/mipsr5900/mult.c76
-rw-r--r--tests/tcg/mips/mipsr5900/multu.c68
-rw-r--r--tests/test-crypto-block.c2
-rw-r--r--tests/test-crypto-tlscredsx509.c8
-rw-r--r--tests/test-crypto-xts.c226
-rwxr-xr-xtests/vm/basevm.py30
-rwxr-xr-xtests/vm/centos1
-rwxr-xr-xtests/vm/freebsd1
-rwxr-xr-xtests/vm/netbsd1
-rwxr-xr-xtests/vm/openbsd1
-rwxr-xr-xtests/vm/ubuntu.i3861
-rw-r--r--tpm.c22
-rw-r--r--ui/curses.c6
-rw-r--r--ui/keymaps.c40
-rw-r--r--ui/keymaps.h2
-rw-r--r--ui/sdl.c6
-rw-r--r--ui/spice-core.c13
-rw-r--r--ui/vnc.c19
-rw-r--r--util/error.c13
-rw-r--r--util/qemu-error.c5
-rw-r--r--vl.c152
193 files changed, 28915 insertions, 2925 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 40672c4eba..d794bd7a66 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -202,6 +202,8 @@ F: include/hw/intc/mips_gic.h
F: include/hw/timer/mips_gictimer.h
F: tests/tcg/mips/
F: disas/mips.c
+F: disas/nanomips.h
+F: disas/nanomips.cpp
Moxie
M: Anthony Green <green@moxielogic.com>
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e64074954f..639c8d4307 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -145,20 +145,26 @@ static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
if (host_memory_backend_mr_inited(backend)) {
+ char *path = object_get_canonical_path_component(o);
+
error_setg(errp, "cannot change property 'pmem' of %s '%s'",
object_get_typename(o),
- object_get_canonical_path_component(o));
+ path);
+ g_free(path);
return;
}
#ifndef CONFIG_LIBPMEM
if (value) {
Error *local_err = NULL;
+ char *path = object_get_canonical_path_component(o);
+
error_setg(&local_err,
"Lack of libpmem support while setting the 'pmem=on'"
" of %s '%s'. We can't ensure data persistence.",
object_get_typename(o),
- object_get_canonical_path_component(o));
+ path);
+ g_free(path);
error_propagate(errp, local_err);
return;
}
diff --git a/block.c b/block.c
index 7710b399a3..08d64cdc61 100644
--- a/block.c
+++ b/block.c
@@ -4697,9 +4697,9 @@ bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp)
assert((int) op >= 0 && op < BLOCK_OP_TYPE_MAX);
if (!QLIST_EMPTY(&bs->op_blockers[op])) {
blocker = QLIST_FIRST(&bs->op_blockers[op]);
- error_propagate(errp, error_copy(blocker->reason));
- error_prepend(errp, "Node '%s' is busy: ",
- bdrv_get_device_or_node_name(bs));
+ error_propagate_prepend(errp, error_copy(blocker->reason),
+ "Node '%s' is busy: ",
+ bdrv_get_device_or_node_name(bs));
return true;
}
return false;
@@ -4803,9 +4803,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (options) {
qemu_opts_do_parse(opts, options, NULL, &local_err);
if (local_err) {
- error_report_err(local_err);
- local_err = NULL;
- error_setg(errp, "Invalid options for file format '%s'", fmt);
goto out;
}
}
diff --git a/block/iscsi.c b/block/iscsi.c
index bb69faf34a..73998c2860 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1844,7 +1844,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
iscsi_set_timeout(iscsi, timeout);
#else
if (timeout) {
- error_report("iSCSI: ignoring timeout value for libiscsi <1.15.0");
+ warn_report("iSCSI: ignoring timeout value for libiscsi <1.15.0");
}
#endif
diff --git a/block/qcow2.c b/block/qcow2.c
index 7277feda13..4f8d2fa7bd 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2208,8 +2208,8 @@ static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
qemu_co_mutex_unlock(&s->lock);
qobject_unref(options);
if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "Could not reopen qcow2 layer: ");
+ error_propagate_prepend(errp, local_err,
+ "Could not reopen qcow2 layer: ");
bs->drv = NULL;
return;
} else if (ret < 0) {
diff --git a/block/qed.c b/block/qed.c
index 689ea9d4d5..9377c0b7ad 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1606,8 +1606,8 @@ static void coroutine_fn bdrv_qed_co_invalidate_cache(BlockDriverState *bs,
ret = bdrv_qed_do_open(bs, NULL, bs->open_flags, &local_err);
qemu_co_mutex_unlock(&s->table_lock);
if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "Could not reopen qed layer: ");
+ error_propagate_prepend(errp, local_err,
+ "Could not reopen qed layer: ");
return;
} else if (ret < 0) {
error_setg_errno(errp, -ret, "Could not reopen qed layer");
diff --git a/block/rbd.c b/block/rbd.c
index 014c68d629..e5bf5a146f 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -750,8 +750,8 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
/* Take care whenever deciding to actually deprecate; once this ability
* is removed, we will not be able to open any images with legacy-styled
* backing image strings. */
- error_report("RBD options encoded in the filename as keyvalue pairs "
- "is deprecated");
+ warn_report("RBD options encoded in the filename as keyvalue pairs "
+ "is deprecated");
}
/* Remove the processed options from the QDict (the visitor processes
diff --git a/block/sheepdog.c b/block/sheepdog.c
index b229a664d9..0125df9d49 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -572,7 +572,7 @@ static int connect_to_sdog(BDRVSheepdogState *s, Error **errp)
if (s->addr->type == SOCKET_ADDRESS_TYPE_INET && fd >= 0) {
int ret = socket_set_nodelay(fd);
if (ret < 0) {
- error_report("%s", strerror(errno));
+ warn_report("can't set TCP_NODELAY: %s", strerror(errno));
}
}
diff --git a/block/vpc.c b/block/vpc.c
index bf294abfa7..984187cadd 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -284,9 +284,11 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
checksum = be32_to_cpu(footer->checksum);
footer->checksum = 0;
- if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)
- fprintf(stderr, "block-vpc: The header checksum of '%s' is "
- "incorrect.\n", bs->filename);
+ if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum) {
+ error_setg(errp, "Incorrect header checksum");
+ ret = -EINVAL;
+ goto fail;
+ }
/* Write 'checksum' back to footer, or else will leave it with zero. */
footer->checksum = cpu_to_be32(checksum);
diff --git a/blockdev.c b/blockdev.c
index a8755bd908..574adbcb7f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -759,7 +759,8 @@ QemuOptsList qemu_legacy_drive_opts = {
},
};
-DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
+DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
+ Error **errp)
{
const char *value;
BlockBackend *blk;
@@ -808,7 +809,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
qemu_opt_rename(all_opts, opt_renames[i].from, opt_renames[i].to,
&local_err);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
return NULL;
}
}
@@ -819,7 +820,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
bool writethrough;
if (bdrv_parse_cache_mode(value, &flags, &writethrough) != 0) {
- error_report("invalid cache option");
+ error_setg(errp, "invalid cache option");
return NULL;
}
@@ -847,7 +848,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
&error_abort);
qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
goto fail;
}
@@ -860,7 +861,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
media = MEDIA_CDROM;
read_only = true;
} else {
- error_report("'%s' invalid media", value);
+ error_setg(errp, "'%s' invalid media", value);
goto fail;
}
}
@@ -885,7 +886,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
type++) {
}
if (type == IF_COUNT) {
- error_report("unsupported bus type '%s'", value);
+ error_setg(errp, "unsupported bus type '%s'", value);
goto fail;
}
} else {
@@ -902,7 +903,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
if (index != -1) {
if (bus_id != 0 || unit_id != -1) {
- error_report("index cannot be used with bus and unit");
+ error_setg(errp, "index cannot be used with bus and unit");
goto fail;
}
bus_id = drive_index_to_bus_id(type, index);
@@ -921,13 +922,13 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
}
if (max_devs && unit_id >= max_devs) {
- error_report("unit %d too big (max is %d)", unit_id, max_devs - 1);
+ error_setg(errp, "unit %d too big (max is %d)", unit_id, max_devs - 1);
goto fail;
}
if (drive_get(type, bus_id, unit_id) != NULL) {
- error_report("drive with bus=%d, unit=%d (index=%d) exists",
- bus_id, unit_id, index);
+ error_setg(errp, "drive with bus=%d, unit=%d (index=%d) exists",
+ bus_id, unit_id, index);
goto fail;
}
@@ -970,7 +971,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
if (werror != NULL) {
if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO &&
type != IF_NONE) {
- error_report("werror is not supported by this bus type");
+ error_setg(errp, "werror is not supported by this bus type");
goto fail;
}
qdict_put_str(bs_opts, "werror", werror);
@@ -980,7 +981,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
if (rerror != NULL) {
if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI &&
type != IF_NONE) {
- error_report("rerror is not supported by this bus type");
+ error_setg(errp, "rerror is not supported by this bus type");
goto fail;
}
qdict_put_str(bs_opts, "rerror", rerror);
@@ -991,7 +992,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
bs_opts = NULL;
if (!blk) {
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
}
goto fail;
} else {
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index e8d9a53476..f681d637c1 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -259,7 +259,7 @@ static void char_pty_open(Chardev *chr,
qemu_set_nonblock(master_fd);
chr->filename = g_strdup_printf("pty:%s", pty_name);
- error_report("char device redirected to %s (label %s)",
+ error_printf("char device redirected to %s (label %s)\n",
pty_name, chr->label);
s = PTY_CHARDEV(chr);
diff --git a/chardev/char.c b/chardev/char.c
index e115166995..7f07a1bfbd 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -634,7 +634,7 @@ Chardev *qemu_chr_new_from_opts(QemuOpts *opts, Error **errp)
chardev_name_foreach(help_string_append, str);
- error_report("Available chardev backend types: %s", str->str);
+ error_printf("Available chardev backend types: %s\n", str->str);
g_string_free(str, true);
return NULL;
}
diff --git a/configure b/configure
index 1d267b49cc..1c473ce95b 100755
--- a/configure
+++ b/configure
@@ -428,7 +428,7 @@ usb_redir=""
opengl=""
opengl_dmabuf="no"
cpuid_h="no"
-avx2_opt="no"
+avx2_opt=""
zlib="yes"
capstone=""
lzo=""
@@ -457,12 +457,9 @@ gtk=""
gtk_gl="no"
tls_priority="NORMAL"
gnutls=""
-gnutls_rnd=""
nettle=""
-nettle_kdf="no"
gcrypt=""
gcrypt_hmac="no"
-gcrypt_kdf="no"
vte=""
virglrenderer=""
tpm="yes"
@@ -1332,6 +1329,10 @@ for opt do
;;
--disable-glusterfs) glusterfs="no"
;;
+ --disable-avx2) avx2_opt="no"
+ ;;
+ --enable-avx2) avx2_opt="yes"
+ ;;
--enable-glusterfs) glusterfs="yes"
;;
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1706,6 +1707,7 @@ disabled with --disable-FEATURE, default is enabled if available:
libxml2 for Parallels image format
tcmalloc tcmalloc support
jemalloc jemalloc support
+ avx2 AVX2 optimization support
replication replication support
vhost-vsock virtio sockets device support
opengl opengl support
@@ -2666,79 +2668,28 @@ fi
##########################################
# GNUTLS probe
-gnutls_works() {
- # Unfortunately some distros have bad pkg-config information for gnutls
- # such that it claims to exist but you get a compiler error if you try
- # to use the options returned by --libs. Specifically, Ubuntu for --static
- # builds doesn't work:
- # https://bugs.launchpad.net/ubuntu/+source/gnutls26/+bug/1478035
- #
- # So sanity check the cflags/libs before assuming gnutls can be used.
- if ! $pkg_config --exists "gnutls"; then
- return 1
- fi
-
- write_c_skeleton
- compile_prog "$($pkg_config --cflags gnutls)" "$($pkg_config --libs gnutls)"
-}
-
-gnutls_gcrypt=no
-gnutls_nettle=no
if test "$gnutls" != "no"; then
- if gnutls_works; then
+ if $pkg_config --exists "gnutls >= 3.1.18"; then
gnutls_cflags=$($pkg_config --cflags gnutls)
gnutls_libs=$($pkg_config --libs gnutls)
libs_softmmu="$gnutls_libs $libs_softmmu"
libs_tools="$gnutls_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
gnutls="yes"
-
- # gnutls_rnd requires >= 2.11.0
- if $pkg_config --exists "gnutls >= 2.11.0"; then
- gnutls_rnd="yes"
- else
- gnutls_rnd="no"
- fi
-
- if $pkg_config --exists 'gnutls >= 3.0'; then
- gnutls_gcrypt=no
- gnutls_nettle=yes
- elif $pkg_config --exists 'gnutls >= 2.12'; then
- case $($pkg_config --libs --static gnutls) in
- *gcrypt*)
- gnutls_gcrypt=yes
- gnutls_nettle=no
- ;;
- *nettle*)
- gnutls_gcrypt=no
- gnutls_nettle=yes
- ;;
- *)
- gnutls_gcrypt=yes
- gnutls_nettle=no
- ;;
- esac
- else
- gnutls_gcrypt=yes
- gnutls_nettle=no
- fi
elif test "$gnutls" = "yes"; then
- feature_not_found "gnutls" "Install gnutls devel"
+ feature_not_found "gnutls" "Install gnutls devel >= 3.1.18"
else
gnutls="no"
- gnutls_rnd="no"
fi
-else
- gnutls_rnd="no"
fi
# If user didn't give a --disable/enable-gcrypt flag,
# then mark as disabled if user requested nettle
-# explicitly, or if gnutls links to nettle
+# explicitly
if test -z "$gcrypt"
then
- if test "$nettle" = "yes" || test "$gnutls_nettle" = "yes"
+ if test "$nettle" = "yes"
then
gcrypt="no"
fi
@@ -2746,16 +2697,16 @@ fi
# If user didn't give a --disable/enable-nettle flag,
# then mark as disabled if user requested gcrypt
-# explicitly, or if gnutls links to gcrypt
+# explicitly
if test -z "$nettle"
then
- if test "$gcrypt" = "yes" || test "$gnutls_gcrypt" = "yes"
+ if test "$gcrypt" = "yes"
then
nettle="no"
fi
fi
-has_libgcrypt_config() {
+has_libgcrypt() {
if ! has "libgcrypt-config"
then
return 1
@@ -2770,11 +2721,42 @@ has_libgcrypt_config() {
fi
fi
+ maj=`libgcrypt-config --version | awk -F . '{print $1}'`
+ min=`libgcrypt-config --version | awk -F . '{print $2}'`
+
+ if test $maj != 1 || test $min -lt 5
+ then
+ return 1
+ fi
+
return 0
}
+
+if test "$nettle" != "no"; then
+ if $pkg_config --exists "nettle >= 2.7.1"; then
+ nettle_cflags=$($pkg_config --cflags nettle)
+ nettle_libs=$($pkg_config --libs nettle)
+ nettle_version=$($pkg_config --modversion nettle)
+ libs_softmmu="$nettle_libs $libs_softmmu"
+ libs_tools="$nettle_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
+ nettle="yes"
+
+ if test -z "$gcrypt"; then
+ gcrypt="no"
+ fi
+ else
+ if test "$nettle" = "yes"; then
+ feature_not_found "nettle" "Install nettle devel >= 2.7.1"
+ else
+ nettle="no"
+ fi
+ fi
+fi
+
if test "$gcrypt" != "no"; then
- if has_libgcrypt_config; then
+ if has_libgcrypt; then
gcrypt_cflags=$(libgcrypt-config --cflags)
gcrypt_libs=$(libgcrypt-config --libs)
# Debian has remove -lgpg-error from libgcrypt-config
@@ -2788,22 +2770,6 @@ if test "$gcrypt" != "no"; then
libs_tools="$gcrypt_libs $libs_tools"
QEMU_CFLAGS="$QEMU_CFLAGS $gcrypt_cflags"
gcrypt="yes"
- if test -z "$nettle"; then
- nettle="no"
- fi
-
- cat > $TMPC << EOF
-#include <gcrypt.h>
-int main(void) {
- gcry_kdf_derive(NULL, 0, GCRY_KDF_PBKDF2,
- GCRY_MD_SHA256,
- NULL, 0, 0, 0, NULL);
- return 0;
-}
-EOF
- if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then
- gcrypt_kdf=yes
- fi
cat > $TMPC << EOF
#include <gcrypt.h>
@@ -2819,7 +2785,7 @@ EOF
fi
else
if test "$gcrypt" = "yes"; then
- feature_not_found "gcrypt" "Install gcrypt devel"
+ feature_not_found "gcrypt" "Install gcrypt devel >= 1.5.0"
else
gcrypt="no"
fi
@@ -2827,36 +2793,6 @@ EOF
fi
-if test "$nettle" != "no"; then
- if $pkg_config --exists "nettle"; then
- nettle_cflags=$($pkg_config --cflags nettle)
- nettle_libs=$($pkg_config --libs nettle)
- nettle_version=$($pkg_config --modversion nettle)
- libs_softmmu="$nettle_libs $libs_softmmu"
- libs_tools="$nettle_libs $libs_tools"
- QEMU_CFLAGS="$QEMU_CFLAGS $nettle_cflags"
- nettle="yes"
-
- cat > $TMPC << EOF
-#include <stddef.h>
-#include <nettle/pbkdf2.h>
-int main(void) {
- pbkdf2_hmac_sha256(8, NULL, 1000, 8, NULL, 8, NULL);
- return 0;
-}
-EOF
- if compile_prog "$nettle_cflags" "$nettle_libs" ; then
- nettle_kdf=yes
- fi
- else
- if test "$nettle" = "yes"; then
- feature_not_found "nettle" "Install nettle devel"
- else
- nettle="no"
- fi
- fi
-fi
-
if test "$gcrypt" = "yes" && test "$nettle" = "yes"
then
error_exit "Only one of gcrypt & nettle can be enabled"
@@ -4202,7 +4138,14 @@ if compile_prog "" "" ; then
memfd=yes
fi
-
+# check for usbfs
+have_usbfs=no
+if test "$linux_user" = "yes"; then
+ if check_include linux/usbdevice_fs.h; then
+ have_usbfs=yes
+ fi
+ have_usbfs=yes
+fi
# check for fallocate
fallocate=no
@@ -5094,7 +5037,7 @@ fi
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.
-if test $cpuid_h = yes; then
+if test "$cpuid_h" = "yes" -a "$avx2_opt" != "no"; then
cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx2")
@@ -5108,6 +5051,8 @@ int main(int argc, char *argv[]) { return bar(argv[0]); }
EOF
if compile_object "" ; then
avx2_opt="yes"
+ else
+ avx2_opt="no"
fi
fi
@@ -5976,11 +5921,8 @@ echo "GTK GL support $gtk_gl"
echo "VTE support $vte $(echo_version $vte $vteversion)"
echo "TLS priority $tls_priority"
echo "GNUTLS support $gnutls"
-echo "GNUTLS rnd $gnutls_rnd"
echo "libgcrypt $gcrypt"
-echo "libgcrypt kdf $gcrypt_kdf"
echo "nettle $nettle $(echo_version $nettle $nettle_version)"
-echo "nettle kdf $nettle_kdf"
echo "libtasn1 $tasn1"
echo "curses support $curses"
echo "virgl support $virglrenderer $(echo_version $virglrenderer $virgl_version)"
@@ -6325,6 +6267,9 @@ fi
if test "$memfd" = "yes" ; then
echo "CONFIG_MEMFD=y" >> $config_host_mak
fi
+if test "$have_usbfs" = "yes" ; then
+ echo "CONFIG_USBFS=y" >> $config_host_mak
+fi
if test "$fallocate" = "yes" ; then
echo "CONFIG_FALLOCATE=y" >> $config_host_mak
fi
@@ -6416,24 +6361,15 @@ echo "CONFIG_TLS_PRIORITY=\"$tls_priority\"" >> $config_host_mak
if test "$gnutls" = "yes" ; then
echo "CONFIG_GNUTLS=y" >> $config_host_mak
fi
-if test "$gnutls_rnd" = "yes" ; then
- echo "CONFIG_GNUTLS_RND=y" >> $config_host_mak
-fi
if test "$gcrypt" = "yes" ; then
echo "CONFIG_GCRYPT=y" >> $config_host_mak
if test "$gcrypt_hmac" = "yes" ; then
echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak
fi
- if test "$gcrypt_kdf" = "yes" ; then
- echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak
- fi
fi
if test "$nettle" = "yes" ; then
echo "CONFIG_NETTLE=y" >> $config_host_mak
echo "CONFIG_NETTLE_VERSION_MAJOR=${nettle_version%%.*}" >> $config_host_mak
- if test "$nettle_kdf" = "yes" ; then
- echo "CONFIG_NETTLE_KDF=y" >> $config_host_mak
- fi
fi
if test "$tasn1" = "yes" ; then
echo "CONFIG_TASN1=y" >> $config_host_mak
@@ -7328,6 +7264,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
;;
mips*)
disas_config "MIPS"
+ if test -n "${cxx}"; then
+ disas_config "NANOMIPS"
+ fi
;;
moxie*)
disas_config "MOXIE"
diff --git a/cpus.c b/cpus.c
index bb2a511483..3978f63d8f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -211,12 +211,12 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp)
error_setg(errp, "No MTTCG when icount is enabled");
} else {
#ifndef TARGET_SUPPORTS_MTTCG
- error_report("Guest not yet converted to MTTCG - "
- "you may get unexpected results");
+ warn_report("Guest not yet converted to MTTCG - "
+ "you may get unexpected results");
#endif
if (!check_tcg_memory_orders_compatible()) {
- error_report("Guest expects a stronger memory ordering "
- "than the host provides");
+ warn_report("Guest expects a stronger memory ordering "
+ "than the host provides");
error_printf("This may cause strange/hard to debug errors\n");
}
mttcg_enabled = true;
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 756bab111b..256c9aca1f 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -20,11 +20,11 @@ crypto-obj-y += tlscredsx509.o
crypto-obj-y += tlssession.o
crypto-obj-y += secret.o
crypto-obj-$(CONFIG_GCRYPT) += random-gcrypt.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS_RND)) += random-gnutls.o
-crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS_RND),n,y)) += random-platform.o
+crypto-obj-$(if $(CONFIG_GCRYPT),n,$(CONFIG_GNUTLS)) += random-gnutls.o
+crypto-obj-$(if $(CONFIG_GCRYPT),n,$(if $(CONFIG_GNUTLS),n,y)) += random-platform.o
crypto-obj-y += pbkdf.o
-crypto-obj-$(CONFIG_NETTLE_KDF) += pbkdf-nettle.o
-crypto-obj-$(if $(CONFIG_NETTLE_KDF),n,$(CONFIG_GCRYPT_KDF)) += pbkdf-gcrypt.o
+crypto-obj-$(CONFIG_NETTLE) += pbkdf-nettle.o
+crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += pbkdf-gcrypt.o
crypto-obj-y += ivgen.o
crypto-obj-y += ivgen-essiv.o
crypto-obj-y += ivgen-plain.o
diff --git a/crypto/init.c b/crypto/init.c
index f131c42306..c30156405a 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -37,33 +37,14 @@
/* #define DEBUG_GNUTLS */
/*
- * If GNUTLS is built against GCrypt then
- *
- * - When GNUTLS >= 2.12, we must not initialize gcrypt threading
- * because GNUTLS will do that itself
- * - When GNUTLS < 2.12 we must always initialize gcrypt threading
- * - When GNUTLS is disabled we must always initialize gcrypt threading
- *
- * But....
- *
- * When gcrypt >= 1.6.0 we must not initialize gcrypt threading
- * because gcrypt will do that itself.
- *
- * So we need to init gcrypt threading if
+ * We need to init gcrypt threading if
*
* - gcrypt < 1.6.0
- * AND
- * - gnutls < 2.12
- * OR
- * - gnutls is disabled
*
*/
#if (defined(CONFIG_GCRYPT) && \
- (!defined(CONFIG_GNUTLS) || \
- (LIBGNUTLS_VERSION_NUMBER < 0x020c00)) && \
- (!defined(GCRYPT_VERSION_NUMBER) || \
- (GCRYPT_VERSION_NUMBER < 0x010600)))
+ (GCRYPT_VERSION_NUMBER < 0x010600))
#define QCRYPTO_INIT_GCRYPT_THREADS
#else
#undef QCRYPTO_INIT_GCRYPT_THREADS
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index 98ee0424e5..d6ab4a9862 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -72,14 +72,6 @@ qcrypto_tls_creds_check_cert_times(gnutls_x509_crt_t cert,
}
-#if LIBGNUTLS_VERSION_NUMBER >= 2
-/*
- * The gnutls_x509_crt_get_basic_constraints function isn't
- * available in GNUTLS 1.0.x branches. This isn't critical
- * though, since gnutls_certificate_verify_peers2 will do
- * pretty much the same check at runtime, so we can just
- * disable this code
- */
static int
qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,
gnutls_x509_crt_t cert,
@@ -130,7 +122,6 @@ qcrypto_tls_creds_check_cert_basic_constraints(QCryptoTLSCredsX509 *creds,
return 0;
}
-#endif
static int
@@ -299,14 +290,12 @@ qcrypto_tls_creds_check_cert(QCryptoTLSCredsX509 *creds,
return -1;
}
-#if LIBGNUTLS_VERSION_NUMBER >= 2
if (qcrypto_tls_creds_check_cert_basic_constraints(creds,
cert, certFile,
isServer, isCA,
errp) < 0) {
return -1;
}
-#endif
if (qcrypto_tls_creds_check_cert_key_usage(creds,
cert, certFile,
@@ -615,7 +604,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
}
if (cert != NULL && key != NULL) {
-#if LIBGNUTLS_VERSION_NUMBER >= 0x030111
char *password = NULL;
if (creds->passwordid) {
password = qcrypto_secret_lookup_as_utf8(creds->passwordid,
@@ -630,15 +618,6 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds,
password,
0);
g_free(password);
-#else /* LIBGNUTLS_VERSION_NUMBER < 0x030111 */
- if (creds->passwordid) {
- error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11");
- goto cleanup;
- }
- ret = gnutls_certificate_set_x509_key_file(creds->data,
- cert, key,
- GNUTLS_X509_FMT_PEM);
-#endif
if (ret < 0) {
error_setg(errp, "Cannot load certificate '%s' & key '%s': %s",
cert, key, gnutls_strerror(ret));
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index 66a6fbe19c..2f28fa7f71 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -90,13 +90,7 @@ qcrypto_tls_session_pull(void *opaque, void *buf, size_t len)
}
#define TLS_PRIORITY_ADDITIONAL_ANON "+ANON-DH"
-
-#if GNUTLS_VERSION_MAJOR >= 3
-#define TLS_ECDHE_PSK "+ECDHE-PSK:"
-#else
-#define TLS_ECDHE_PSK ""
-#endif
-#define TLS_PRIORITY_ADDITIONAL_PSK TLS_ECDHE_PSK "+DHE-PSK:+PSK"
+#define TLS_PRIORITY_ADDITIONAL_PSK "+ECDHE-PSK:+DHE-PSK:+PSK"
QCryptoTLSSession *
qcrypto_tls_session_new(QCryptoTLSCreds *creds,
diff --git a/crypto/xts.c b/crypto/xts.c
index 95212341f6..4277ad40de 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -24,52 +24,75 @@
*/
#include "qemu/osdep.h"
+#include "qemu/bswap.h"
#include "crypto/xts.h"
-static void xts_mult_x(uint8_t *I)
+typedef union {
+ uint8_t b[XTS_BLOCK_SIZE];
+ uint64_t u[2];
+} xts_uint128;
+
+static inline void xts_uint128_xor(xts_uint128 *D,
+ const xts_uint128 *S1,
+ const xts_uint128 *S2)
{
- int x;
- uint8_t t, tt;
+ D->u[0] = S1->u[0] ^ S2->u[0];
+ D->u[1] = S1->u[1] ^ S2->u[1];
+}
- for (x = t = 0; x < 16; x++) {
- tt = I[x] >> 7;
- I[x] = ((I[x] << 1) | t) & 0xFF;
- t = tt;
- }
- if (tt) {
- I[0] ^= 0x87;
+static inline void xts_uint128_cpu_to_les(xts_uint128 *v)
+{
+ cpu_to_le64s(&v->u[0]);
+ cpu_to_le64s(&v->u[1]);
+}
+
+static inline void xts_uint128_le_to_cpus(xts_uint128 *v)
+{
+ le64_to_cpus(&v->u[0]);
+ le64_to_cpus(&v->u[1]);
+}
+
+static void xts_mult_x(xts_uint128 *I)
+{
+ uint64_t tt;
+
+ xts_uint128_le_to_cpus(I);
+
+ tt = I->u[0] >> 63;
+ I->u[0] <<= 1;
+
+ if (I->u[1] >> 63) {
+ I->u[0] ^= 0x87;
}
+ I->u[1] <<= 1;
+ I->u[1] |= tt;
+
+ xts_uint128_cpu_to_les(I);
}
/**
- * xts_tweak_uncrypt:
+ * xts_tweak_encdec:
* @param ctxt: the cipher context
* @param func: the cipher function
- * @src: buffer providing the cipher text of XTS_BLOCK_SIZE bytes
- * @dst: buffer to output the plain text of XTS_BLOCK_SIZE bytes
+ * @src: buffer providing the input text of XTS_BLOCK_SIZE bytes
+ * @dst: buffer to output the output text of XTS_BLOCK_SIZE bytes
* @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes
*
- * Decrypt data with a tweak
+ * Encrypt/decrypt data with a tweak
*/
-static void xts_tweak_decrypt(const void *ctx,
- xts_cipher_func *func,
- const uint8_t *src,
- uint8_t *dst,
- uint8_t *iv)
+static inline void xts_tweak_encdec(const void *ctx,
+ xts_cipher_func *func,
+ const xts_uint128 *src,
+ xts_uint128 *dst,
+ xts_uint128 *iv)
{
- unsigned long x;
-
/* tweak encrypt block i */
- for (x = 0; x < XTS_BLOCK_SIZE; x++) {
- dst[x] = src[x] ^ iv[x];
- }
+ xts_uint128_xor(dst, src, iv);
- func(ctx, XTS_BLOCK_SIZE, dst, dst);
+ func(ctx, XTS_BLOCK_SIZE, dst->b, dst->b);
- for (x = 0; x < XTS_BLOCK_SIZE; x++) {
- dst[x] = dst[x] ^ iv[x];
- }
+ xts_uint128_xor(dst, dst, iv);
/* LFSR the tweak */
xts_mult_x(iv);
@@ -85,7 +108,7 @@ void xts_decrypt(const void *datactx,
uint8_t *dst,
const uint8_t *src)
{
- uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE];
+ xts_uint128 PP, CC, T;
unsigned long i, m, mo, lim;
/* get number of blocks */
@@ -102,72 +125,53 @@ void xts_decrypt(const void *datactx,
}
/* encrypt the iv */
- encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv);
-
- for (i = 0; i < lim; i++) {
- xts_tweak_decrypt(datactx, decfunc, src, dst, T);
-
- src += XTS_BLOCK_SIZE;
- dst += XTS_BLOCK_SIZE;
+ encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv);
+
+ if (QEMU_PTR_IS_ALIGNED(src, sizeof(uint64_t)) &&
+ QEMU_PTR_IS_ALIGNED(dst, sizeof(uint64_t))) {
+ xts_uint128 *S = (xts_uint128 *)src;
+ xts_uint128 *D = (xts_uint128 *)dst;
+ for (i = 0; i < lim; i++, S++, D++) {
+ xts_tweak_encdec(datactx, decfunc, S, D, &T);
+ }
+ } else {
+ xts_uint128 D;
+
+ for (i = 0; i < lim; i++) {
+ memcpy(&D, src, XTS_BLOCK_SIZE);
+ xts_tweak_encdec(datactx, decfunc, &D, &D, &T);
+ memcpy(dst, &D, XTS_BLOCK_SIZE);
+ src += XTS_BLOCK_SIZE;
+ dst += XTS_BLOCK_SIZE;
+ }
}
/* if length is not a multiple of XTS_BLOCK_SIZE then */
if (mo > 0) {
- memcpy(CC, T, XTS_BLOCK_SIZE);
- xts_mult_x(CC);
+ xts_uint128 S, D;
+ memcpy(&CC, &T, XTS_BLOCK_SIZE);
+ xts_mult_x(&CC);
/* PP = tweak decrypt block m-1 */
- xts_tweak_decrypt(datactx, decfunc, src, PP, CC);
+ memcpy(&S, src, XTS_BLOCK_SIZE);
+ xts_tweak_encdec(datactx, decfunc, &S, &PP, &CC);
/* Pm = first length % XTS_BLOCK_SIZE bytes of PP */
for (i = 0; i < mo; i++) {
- CC[i] = src[XTS_BLOCK_SIZE + i];
- dst[XTS_BLOCK_SIZE + i] = PP[i];
+ CC.b[i] = src[XTS_BLOCK_SIZE + i];
+ dst[XTS_BLOCK_SIZE + i] = PP.b[i];
}
for (; i < XTS_BLOCK_SIZE; i++) {
- CC[i] = PP[i];
+ CC.b[i] = PP.b[i];
}
/* Pm-1 = Tweak uncrypt CC */
- xts_tweak_decrypt(datactx, decfunc, CC, dst, T);
+ xts_tweak_encdec(datactx, decfunc, &CC, &D, &T);
+ memcpy(dst, &D, XTS_BLOCK_SIZE);
}
/* Decrypt the iv back */
- decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T);
-}
-
-
-/**
- * xts_tweak_crypt:
- * @param ctxt: the cipher context
- * @param func: the cipher function
- * @src: buffer providing the plain text of XTS_BLOCK_SIZE bytes
- * @dst: buffer to output the cipher text of XTS_BLOCK_SIZE bytes
- * @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes
- *
- * Encrypt data with a tweak
- */
-static void xts_tweak_encrypt(const void *ctx,
- xts_cipher_func *func,
- const uint8_t *src,
- uint8_t *dst,
- uint8_t *iv)
-{
- unsigned long x;
-
- /* tweak encrypt block i */
- for (x = 0; x < XTS_BLOCK_SIZE; x++) {
- dst[x] = src[x] ^ iv[x];
- }
-
- func(ctx, XTS_BLOCK_SIZE, dst, dst);
-
- for (x = 0; x < XTS_BLOCK_SIZE; x++) {
- dst[x] = dst[x] ^ iv[x];
- }
-
- /* LFSR the tweak */
- xts_mult_x(iv);
+ decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T.b);
}
@@ -180,7 +184,7 @@ void xts_encrypt(const void *datactx,
uint8_t *dst,
const uint8_t *src)
{
- uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE];
+ xts_uint128 PP, CC, T;
unsigned long i, m, mo, lim;
/* get number of blocks */
@@ -197,34 +201,50 @@ void xts_encrypt(const void *datactx,
}
/* encrypt the iv */
- encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv);
+ encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv);
+
+ if (QEMU_PTR_IS_ALIGNED(src, sizeof(uint64_t)) &&
+ QEMU_PTR_IS_ALIGNED(dst, sizeof(uint64_t))) {
+ xts_uint128 *S = (xts_uint128 *)src;
+ xts_uint128 *D = (xts_uint128 *)dst;
+ for (i = 0; i < lim; i++, S++, D++) {
+ xts_tweak_encdec(datactx, encfunc, S, D, &T);
+ }
+ } else {
+ xts_uint128 D;
- for (i = 0; i < lim; i++) {
- xts_tweak_encrypt(datactx, encfunc, src, dst, T);
+ for (i = 0; i < lim; i++) {
+ memcpy(&D, src, XTS_BLOCK_SIZE);
+ xts_tweak_encdec(datactx, encfunc, &D, &D, &T);
+ memcpy(dst, &D, XTS_BLOCK_SIZE);
- dst += XTS_BLOCK_SIZE;
- src += XTS_BLOCK_SIZE;
+ dst += XTS_BLOCK_SIZE;
+ src += XTS_BLOCK_SIZE;
+ }
}
/* if length is not a multiple of XTS_BLOCK_SIZE then */
if (mo > 0) {
+ xts_uint128 S, D;
/* CC = tweak encrypt block m-1 */
- xts_tweak_encrypt(datactx, encfunc, src, CC, T);
+ memcpy(&S, src, XTS_BLOCK_SIZE);
+ xts_tweak_encdec(datactx, encfunc, &S, &CC, &T);
/* Cm = first length % XTS_BLOCK_SIZE bytes of CC */
for (i = 0; i < mo; i++) {
- PP[i] = src[XTS_BLOCK_SIZE + i];
- dst[XTS_BLOCK_SIZE + i] = CC[i];
+ PP.b[i] = src[XTS_BLOCK_SIZE + i];
+ dst[XTS_BLOCK_SIZE + i] = CC.b[i];
}
for (; i < XTS_BLOCK_SIZE; i++) {
- PP[i] = CC[i];
+ PP.b[i] = CC.b[i];
}
/* Cm-1 = Tweak encrypt PP */
- xts_tweak_encrypt(datactx, encfunc, PP, dst, T);
+ xts_tweak_encdec(datactx, encfunc, &PP, &D, &T);
+ memcpy(dst, &D, XTS_BLOCK_SIZE);
}
/* Decrypt the iv back */
- decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T);
+ decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T.b);
}
diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak
index bbe361f01a..eb58b40254 100644
--- a/default-configs/alpha-softmmu.mak
+++ b/default-configs/alpha-softmmu.mak
@@ -19,3 +19,4 @@ CONFIG_IDE_CMD646=y
CONFIG_I8259=y
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y
+CONFIG_SMC37C669=y
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 210cff2781..64c998c4c8 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -51,7 +51,8 @@ CONFIG_PCI_Q35=y
CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_PVPANIC=y
-CONFIG_MEM_HOTPLUG=y
+CONFIG_MEM_DEVICE=y
+CONFIG_DIMM=y
CONFIG_NVDIMM=y
CONFIG_ACPI_NVDIMM=y
CONFIG_PCIE_PORT=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index b94af6c7c6..f550573782 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -16,4 +16,5 @@ CONFIG_VIRTIO_VGA=y
CONFIG_XICS=$(CONFIG_PSERIES)
CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
-CONFIG_MEM_HOTPLUG=y
+CONFIG_MEM_DEVICE=y
+CONFIG_DIMM=y
diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak
index 52edafe547..ce63d47046 100644
--- a/default-configs/sparc64-softmmu.mak
+++ b/default-configs/sparc64-softmmu.mak
@@ -16,5 +16,4 @@ CONFIG_SIMBA=y
CONFIG_SUNHME=y
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y
-CONFIG_EMPTY_SLOT=y
CONFIG_SUN4V_RTC=y
diff --git a/device-hotplug.c b/device-hotplug.c
index cd427e2c76..6090d5f1e9 100644
--- a/device-hotplug.c
+++ b/device-hotplug.c
@@ -28,6 +28,7 @@
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "qapi/qmp/qdict.h"
+#include "qapi/error.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "sysemu/sysemu.h"
@@ -36,6 +37,7 @@
static DriveInfo *add_init_drive(const char *optstr)
{
+ Error *err = NULL;
DriveInfo *dinfo;
QemuOpts *opts;
MachineClass *mc;
@@ -45,8 +47,9 @@ static DriveInfo *add_init_drive(const char *optstr)
return NULL;
mc = MACHINE_GET_CLASS(current_machine);
- dinfo = drive_new(opts, mc->block_default_type);
+ dinfo = drive_new(opts, mc->block_default_type, &err);
if (!dinfo) {
+ error_report_err(err);
qemu_opts_del(opts);
return NULL;
}
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 213be2fab2..3c1cdce026 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_NANOMIPS_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/nanomips.cpp b/disas/nanomips.cpp
new file mode 100644
index 0000000000..1238c2ff33
--- /dev/null
+++ b/disas/nanomips.cpp
@@ -0,0 +1,22242 @@
+/*
+ * Source file for nanoMIPS disassembler component of QEMU
+ *
+ * Copyright (C) 2018 Wave Computing
+ * Copyright (C) 2018 Matthew Fortune <matthew.fortune@mips.com>
+ * Copyright (C) 2018 Aleksandar Markovic <aleksandar.markovic@wavecomp.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+extern "C" {
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+}
+
+#include <cstring>
+#include <stdexcept>
+#include <sstream>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "nanomips.h"
+
+#define IMGASSERTONCE(test)
+
+
+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;
+}
+
+int print_insn_nanomips(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;
+
+ 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;
+}
+
+
+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;
+}
+
+
+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];
+ }
+}
+
+
+int NMD::Disassemble(const uint16 * data, std::string & dis,
+ NMD::TABLE_ENTRY_TYPE & type)
+{
+ return Disassemble(data, dis, type, MAJOR, 2);
+}
+
+
+/*
+ * 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, 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_categories &
+ 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::extract_code_18_to_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 19);
+ return value;
+}
+
+
+uint64 NMD::extract_shift3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 3);
+ return value;
+}
+
+
+uint64 NMD::extr_uil3il3bs9Fmsb11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 3, 9) << 3;
+ return value;
+}
+
+
+uint64 NMD::extract_count_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 4);
+ return value;
+}
+
+
+uint64 NMD::extract_rtz3_9_8_7(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 7, 3);
+ 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);
+ 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::extract_u_10(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 10, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_rtz4_27_26_25_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 3);
+ value |= extract_bits(instruction, 25, 1) << 3;
+ return value;
+}
+
+
+uint64 NMD::extract_sa_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_shift_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_shiftxil7il1bs4Fmsb4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 7, 4) << 1;
+ return value;
+}
+
+
+uint64 NMD::extract_hint_25_24_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_count3_14_13_12(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 12, 3);
+ 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::extract_u2_10_9(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 9, 2);
+ return value;
+}
+
+
+uint64 NMD::extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 10);
+ return value;
+}
+
+
+uint64 NMD::extract_rs_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_uil1il1bs2Fmsb2(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 1, 2) << 1;
+ return value;
+}
+
+
+uint64 NMD::extract_stripe_6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 1);
+ return value;
+}
+
+
+uint64 NMD::extr_xil17il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 17, 1);
+ return value;
+}
+
+
+uint64 NMD::extr_xil2il0bs1_il15il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 2, 1);
+ value |= extract_bits(instruction, 15, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_ac_13_12(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 14, 2);
+ return value;
+}
+
+
+uint64 NMD::extract_shift_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_rdl_25_24(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 24, 1);
+ 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::extract_eu_6_5_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 7);
+ return value;
+}
+
+
+uint64 NMD::extract_shift_5_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 6);
+ return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs6Fmsb5(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 10, 6);
+ return value;
+}
+
+
+uint64 NMD::extract_count_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 4);
+ return value;
+}
+
+
+uint64 NMD::extract_code_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 3);
+ return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs4_il22il0bs4Fmsb3(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 10, 4);
+ value |= extract_bits(instruction, 22, 4);
+ return value;
+}
+
+
+uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 12);
+ return value;
+}
+
+
+uint64 NMD::extract_rs_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 5);
+ 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);
+ return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs4Fmsb5(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 4) << 2;
+ return value;
+}
+
+
+uint64 NMD::extract_cofun_25_24_23(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 3, 23);
+ 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);
+ return value;
+}
+
+
+uint64 NMD::extract_rd3_3_2_1(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 1, 3);
+ return value;
+}
+
+
+uint64 NMD::extract_sa_15_14_13_12(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 12, 4);
+ return value;
+}
+
+
+uint64 NMD::extract_rt_25_24_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_ru_7_6_5_4_3(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 3, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil21il0bs5Fmsb4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil9il0bs3Fmsb2(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 9, 3);
+ return value;
+}
+
+
+uint64 NMD::extract_u_17_to_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 18);
+ return value;
+}
+
+
+uint64 NMD::extr_xil14il0bs1_il15il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 14, 1);
+ value |= extract_bits(instruction, 15, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_rsz4_4_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 3);
+ value |= extract_bits(instruction, 4, 1) << 3;
+ return value;
+}
+
+
+uint64 NMD::extr_xil24il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 24, 1);
+ 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::extract_op_25_to_3(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 3, 23);
+ return value;
+}
+
+
+uint64 NMD::extract_rs4_4_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 3);
+ value |= extract_bits(instruction, 4, 1) << 3;
+ return value;
+}
+
+
+uint64 NMD::extract_bit_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 3);
+ return value;
+}
+
+
+uint64 NMD::extract_rt_41_40_39_38_37(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 37, 5);
+ return value;
+}
+
+
+int64 NMD::extract_shift_21_20_19_18_17_16(uint64 instruction)
+{
+ int64 value = 0;
+ value |= extract_bits(instruction, 16, 6);
+ value = sign_extend(value, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil6il0bs3_il10il0bs1Fmsb2(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 3);
+ value |= extract_bits(instruction, 10, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_rd2_3_8(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 3, 1) << 1;
+ value |= extract_bits(instruction, 8, 1);
+ return value;
+}
+
+
+uint64 NMD::extr_xil16il0bs5Fmsb4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_code_17_to_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 18);
+ return value;
+}
+
+
+uint64 NMD::extr_xil0il0bs12Fmsb11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 12);
+ return value;
+}
+
+
+uint64 NMD::extract_size_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ 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::extract_u_15_to_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 16);
+ return value;
+}
+
+
+uint64 NMD::extract_fs_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+int64 NMD::extr_sil0il0bs8_il15il8bs1Tmsb8(uint64 instruction)
+{
+ int64 value = 0;
+ value |= extract_bits(instruction, 0, 8);
+ value |= extract_bits(instruction, 15, 1) << 8;
+ value = sign_extend(value, 8);
+ return value;
+}
+
+
+uint64 NMD::extract_stype_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_rtl_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 9, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_hs_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs1_il14il0bs2Fmsb1(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 10, 1);
+ value |= extract_bits(instruction, 14, 2);
+ return value;
+}
+
+
+uint64 NMD::extract_sel_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 3);
+ return value;
+}
+
+
+uint64 NMD::extract_lsb_4_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil14il0bs2Fmsb1(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 14, 2);
+ return value;
+}
+
+
+uint64 NMD::extract_gp_2(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 2, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_rt3_9_8_7(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 7, 3);
+ return value;
+}
+
+
+uint64 NMD::extract_ft_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_u_17_16_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 7);
+ return value;
+}
+
+
+uint64 NMD::extract_cs_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil16il0bs10Fmsb9(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 10);
+ return value;
+}
+
+
+uint64 NMD::extract_rt4_9_7_6_5(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 5, 3);
+ value |= extract_bits(instruction, 9, 1) << 3;
+ return value;
+}
+
+
+uint64 NMD::extract_msbt_10_9_8_7_6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 5);
+ 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);
+ return value;
+}
+
+
+uint64 NMD::extract_sa_15_14_13(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 13, 3);
+ 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::extract_rs3_6_5_4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 4, 3);
+ return value;
+}
+
+
+uint64 NMD::extr_uil0il32bs32Fmsb63(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 32) << 32;
+ return value;
+}
+
+
+uint64 NMD::extract_shift_10_9_8_7_6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_cs_25_24_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_shiftx_11_10_9_8_7_6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 6);
+ return value;
+}
+
+
+uint64 NMD::extract_rt_9_8_7_6_5(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 5, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_op_25_24_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs7Fmsb8(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 7) << 2;
+ return value;
+}
+
+
+uint64 NMD::extract_bit_16_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 6);
+ return value;
+}
+
+
+uint64 NMD::extr_xil10il0bs1_il11il0bs5Fmsb4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 10, 1);
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_mask_20_19_18_17_16_15_14(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 14, 7);
+ return value;
+}
+
+
+uint64 NMD::extract_eu_3_2_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 4);
+ 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::extract_ft_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ 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);
+ value = sign_extend(value, 31);
+ return value;
+}
+
+
+uint64 NMD::extract_u_20_19_18_17_16_15_14_13(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 13, 8);
+ return value;
+}
+
+
+uint64 NMD::extr_xil15il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 15, 1);
+ return value;
+}
+
+
+uint64 NMD::extr_xil11il0bs5Fmsb4(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_uil2il2bs16Fmsb17(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 2, 16) << 2;
+ return value;
+}
+
+
+uint64 NMD::extract_rd_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_c0s_20_19_18_17_16(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_code_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 2);
+ 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);
+ value |= extract_bits(instruction, 4, 1);
+ return value;
+}
+
+
+uint64 NMD::extract_u_1_0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 2);
+ 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);
+ value |= extract_bits(instruction, 16, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_fd_10_9_8_7_6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil6il0bs3Fmsb2(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 6, 3);
+ return value;
+}
+
+
+uint64 NMD::extr_uil0il2bs5Fmsb6(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 0, 5) << 2;
+ return value;
+}
+
+
+uint64 NMD::extract_rtz4_9_7_6_5(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 5, 3);
+ value |= extract_bits(instruction, 9, 1) << 3;
+ return value;
+}
+
+
+uint64 NMD::extract_sel_15_14_13_12_11(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 5);
+ return value;
+}
+
+
+uint64 NMD::extract_ct_25_24_23_22_21(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 21, 5);
+ return value;
+}
+
+
+uint64 NMD::extr_xil11il0bs1Fmsb0(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 11, 1);
+ return value;
+}
+
+
+uint64 NMD::extr_uil2il2bs19Fmsb20(uint64 instruction)
+{
+ uint64 value = 0;
+ value |= extract_bits(instruction, 2, 19) << 2;
+ return value;
+}
+
+
+int64 NMD::extract_s_4_2_1_0(uint64 instruction)
+{
+ int64 value = 0;
+ value |= extract_bits(instruction, 0, 3);
+ 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);
+ return value;
+}
+
+
+
+bool NMD::ADDIU_32__cond(uint64 instruction)
+{
+ uint64 rt = extract_rt_25_24_23_22_21(instruction);
+ return rt != 0;
+}
+
+
+bool NMD::ADDIU_RS5__cond(uint64 instruction)
+{
+ uint64 rt = extract_rt_9_8_7_6_5(instruction);
+ return rt != 0;
+}
+
+
+bool NMD::BALRSC_cond(uint64 instruction)
+{
+ uint64 rt = extract_rt_25_24_23_22_21(instruction);
+ return rt != 0;
+}
+
+
+bool NMD::BEQC_16__cond(uint64 instruction)
+{
+ uint64 rs3 = extract_rs3_6_5_4(instruction);
+ uint64 rt3 = extract_rt3_9_8_7(instruction);
+ uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+ return rs3 < rt3 && u != 0;
+}
+
+
+bool NMD::BNEC_16__cond(uint64 instruction)
+{
+ uint64 rs3 = extract_rs3_6_5_4(instruction);
+ uint64 rt3 = extract_rt3_9_8_7(instruction);
+ uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+ return rs3 >= rt3 && u != 0;
+}
+
+
+bool NMD::MOVE_cond(uint64 instruction)
+{
+ uint64 rt = extract_rt_9_8_7_6_5(instruction);
+ return rt != 0;
+}
+
+
+bool NMD::P16_BR1_cond(uint64 instruction)
+{
+ uint64 u = extr_uil0il1bs4Fmsb4(instruction);
+ return u != 0;
+}
+
+
+bool NMD::PREF_S9__cond(uint64 instruction)
+{
+ uint64 hint = extract_hint_25_24_23_22_21(instruction);
+ return hint != 31;
+}
+
+
+bool NMD::PREFE_cond(uint64 instruction)
+{
+ uint64 hint = extract_hint_25_24_23_22_21(instruction);
+ return hint != 31;
+}
+
+
+bool NMD::SLTU_cond(uint64 instruction)
+{
+ uint64 rd = extract_rd_20_19_18_17_16(instruction);
+ return rd != 0;
+}
+
+
+
+/*
+ * ABS.D fd, fs - Floating Point Absolute Value
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 010001 00000 000101
+ * fmt -----
+ * fs -----
+ * fd -----
+ */
+std::string NMD::ABS_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 fd_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string fs = FPR(copy(fs_value));
+ std::string fd = FPR(copy(fd_value));
+
+ return img::format("ABS.D %s, %s", fd, fs);
+}
+
+
+/*
+ * ABS.S fd, fs - Floating Point Absolute Value
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 010001 00000 000101
+ * fmt -----
+ * fd -----
+ * fs -----
+ */
+std::string NMD::ABS_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 fd_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string fs = FPR(copy(fs_value));
+ std::string fd = FPR(copy(fd_value));
+
+ return img::format("ABS.S %s, %s", fd, fs);
+}
+
+
+/*
+ * ABSQ_S.PH rt, rs - Find Absolute Value of Two Fractional Halfwords
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0001000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ABSQ_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ABSQ_S.QB rt, rs - Find Absolute Value of Four Fractional Byte Values
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0000000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ABSQ_S_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ABSQ_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ACLR(uint64 instruction)
+{
+ uint64 bit_value = extract_bit_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADD.D fd, fs, ft - Floating Point Add
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 010001 000101
+ * fmt -----
+ * ft -----
+ * fs -----
+ * fd -----
+ */
+std::string NMD::ADD_D(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+ std::string fd = FPR(copy(fd_value));
+
+ return img::format("ADD.D %s, %s, %s", fd, fs, ft);
+}
+
+
+/*
+ * ADD.S fd, fs, ft - Floating Point Add
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 010001 000101
+ * fmt -----
+ * ft -----
+ * fs -----
+ * fd -----
+ */
+std::string NMD::ADD_S(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+ std::string fd = FPR(copy(fd_value));
+
+ return img::format("ADD.S %s, %s, %s", fd, fs, ft);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_15_to_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_GP48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_GP_B_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_17_to_0(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_GP_W_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_NEG_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_R1_SP_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il2bs6Fmsb7(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0010000100111111
+ * rt -----
+ * rs -----
+ */
+std::string NMD::ADDIU_R2_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il2bs3Fmsb4(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDIU[RS5] rt, s5 - Add Signed Word and Set Carry Bit
+ *
+ * 5432109876543210
+ * 100100 1
+ * rt -----
+ * s - ---
+ */
+std::string NMD::ADDIU_RS5_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(instruction);
+ int64 s_value = extract_s_4_2_1_0(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string s = IMMEDIATE(copy(s_value));
+
+ return img::format("ADDIU %s, %s", rt, s);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDIUPC_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDIUPC_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ * ADDQ.PH rd, rt, rs - Add Fractional Halfword Vectors
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00000001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQ_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQ_S.PH rd, rt, rs - Add Fractional Halfword Vectors
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10000001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQ_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQ_S.W rd, rt, rs - Add Fractional Words
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1100000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQ_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH.PH rd, rt, rs - Add Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQH_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.PH rd, rt, rs - Add Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQH_R_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQH_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDQH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDSC rd, rt, rs - Add Signed Word and Set Carry Bit
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDSC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDU[16] rd3, rs3, rt3 -
+ *
+ * 5432109876543210
+ * 101100 0
+ * rt3 ---
+ * rs3 ---
+ * rd3 ---
+ */
+std::string NMD::ADDU_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(instruction);
+ uint64 rd3_value = extract_rd3_3_2_1(instruction);
+
+ std::string rt3 = GPR(encode_gpr3(rt3_value));
+ std::string rs3 = GPR(encode_gpr3(rs3_value));
+ std::string rd3 = GPR(encode_gpr3(rd3_value));
+
+ return img::format("ADDU %s, %s, %s", rd3, rs3, rt3);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_4X4_(uint64 instruction)
+{
+ uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
+ uint64 rt4_value = extract_rt4_9_7_6_5(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);
+}
+
+
+/*
+ * ADDU.PH rd, rt, rs - Unsigned Add Integer Halfwords
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00100001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDU.QB rd, rt, rs - Unsigned Add Quad Byte Vectors
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00011001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDU_S.PH rd, rt, rs - Unsigned Add Integer Halfwords
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10100001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDU_S.QB rd, rt, rs - Unsigned Add Quad Byte Vectors
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10011001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDU_S_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDUH.QB rd, rt, rs - Unsigned Add Vector Quad-Bytes And Right Shift
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00101001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDUH_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDUH_R.QB rd, rt, rs - Unsigned Add Vector Quad-Bytes And Right Shift
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 10101001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDUH_R_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+/*
+ * ADDWC rd, rt, rs - Add Word with Carry Bit
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1111000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ADDWC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ALUIPC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ * AND[16] rt3, rs3 -
+ *
+ * 5432109876543210
+ * 101100
+ * rt3 ---
+ * rs3 ---
+ * eu ----
+ */
+std::string NMD::AND_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(instruction);
+
+ std::string rt3 = GPR(encode_gpr3(rt3_value));
+ std::string rs3 = GPR(encode_gpr3(rs3_value));
+
+ return img::format("AND %s, %s", rs3, rt3);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::AND_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ANDI rt, rs, u -
+ *
+ * 5432109876543210
+ * 101100
+ * rt3 ---
+ * rs3 ---
+ * eu ----
+ */
+std::string NMD::ANDI_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(instruction);
+ uint64 eu_value = extract_eu_3_2_1_0(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ANDI_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::APPEND(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ASET(uint64 instruction)
+{
+ uint64 bit_value = extract_bit_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BALRSC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("BALRSC %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BBEQZC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 bit_value = extract_bit_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BBNEZC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 bit_value = extract_bit_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BC1EQZC(uint64 instruction)
+{
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BC1NEZC(uint64 instruction)
+{
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BC2EQZC(uint64 instruction)
+{
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 ct_value = extract_ct_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BC2NEZC(uint64 instruction)
+{
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 ct_value = extract_ct_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BEQC_16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il1bs4Fmsb4(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BEQC_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BEQIC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BEQZC_16_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il7bs1_il1il1bs6Tmsb7(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BGEC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BGEIC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BGEIUC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BGEUC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BLTC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BLTIC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BLTIUC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BLTUC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BNEC_16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il1bs4Fmsb4(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BNEC_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il14bs1_il1il1bs13Tmsb14(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BNEIC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il11bs1_il1il1bs10Tmsb11(instruction);
+ uint64 u_value = extract_u_17_16_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BNEZC_16_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il7bs1_il1il1bs6Tmsb7(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BREAK_16_(uint64 instruction)
+{
+ uint64 code_value = extract_code_2_1_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("BREAK %s", code);
+}
+
+
+/*
+ * BREAK code - Break. Cause a Breakpoint exception
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BREAK_32_(uint64 instruction)
+{
+ uint64 code_value = extract_code_18_to_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("BREAK %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::BRSC(uint64 instruction)
+{
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("BRSC %s", rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CACHE(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 op_value = extract_op_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CACHEE(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 op_value = extract_op_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CEIL_L_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CEIL_L_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CEIL_W_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CEIL_W_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CFC1(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("CFC1 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CFC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("CFC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CLASS_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("CLASS.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CLASS_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("CLASS.S %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CLO(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("CLO %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CLZ(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("CLZ %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_AF_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_AF_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_EQ_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_EQ_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_EQ_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LE_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LT_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LT_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_LT_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_NE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_NE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_OR_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_OR_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SAF_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SAF_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SEQ_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SEQ_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SLE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SLE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SLT_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SLT_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SNE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SNE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SOR_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SOR_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUEQ_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUEQ_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SULE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SULE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SULT_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SULT_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUN_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUNE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUNE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_SUN_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UEQ_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UEQ_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_ULE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_ULE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_ULT_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_ULT_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UN_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UNE_D(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UNE_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMP_UN_S(uint64 instruction)
+{
+ uint64 fd_value = extract_fd_10_9_8_7_6(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGDU_EQ_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGDU_LE_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGDU_LT_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGU_EQ_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGU_LE_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPGU_LT_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPU_EQ_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPU_LE_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CMPU_LT_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::COP2_1(uint64 instruction)
+{
+ uint64 cofun_value = extract_cofun_25_24_23(instruction);
+
+ std::string cofun = IMMEDIATE(copy(cofun_value));
+
+ return img::format("COP2_1 %s", cofun);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CTC1(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("CTC1 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CTC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("CTC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_D_L(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_D_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_D_W(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_L_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_L_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_S_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_S_L(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_S_PL(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_S_PU(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_S_W(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_W_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::CVT_W_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DADDIU_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DADDIU_NEG_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DADDIU_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DADD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DADDU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DCLO(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("DCLO %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DCLZ(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("DCLZ %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DDIV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DDIVU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DERET(uint64 instruction)
+{
+ (void)instruction;
+
+ return "DERET ";
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DEXTM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DEXT(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DEXTU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DINSM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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 */
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DINS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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 */
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DINSU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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 */
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("DI %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DIV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DIV_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DIV_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DIVU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DLSA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 u2_value = extract_u2_10_9(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DLUI_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMFC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMFC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("DMFC1 %s, %s", rt, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMFC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("DMFC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMFGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMOD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMODU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMTC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMTC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("DMTC1 %s, %s", rt, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMTC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("DMTC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMTGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMT(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("DMT %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMUH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMUHU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMUL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DMULU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPA_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAQ_SA_L_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAQ_S_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAQX_SA_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAQX_S_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAU_H_QBL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAU_H_QBR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPAX_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPS_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSQ_SA_L_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSQ_S_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSQX_SA_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSQX_S_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSU_H_QBL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSU_H_QBR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DPSX_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DROTR -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DROTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DROTR[32] -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0110
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DROTR32(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DROTRV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DROTX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_5_4_3_2_1_0(instruction);
+ uint64 shiftx_value = extract_shiftx_11_10_9_8_7_6(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSLL -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0000
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSLL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSLL[32] -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0000
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSLL32(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DSLLV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSRA -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0100
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSRA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSRA[32] -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0100
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSRA32(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DSRAV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSRL -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0100
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSRL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * DSRL[32] -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 10o000 1100xxx0010
+ * rt -----
+ * rs -----
+ * shift -----
+ */
+std::string NMD::DSRL32(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DSRLV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DSUB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DSUBU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DVPE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("DVPE %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::DVP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("DVP %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EHB(uint64 instruction)
+{
+ (void)instruction;
+
+ return "EHB ";
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("EI %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EMT(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("EMT %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ERET(uint64 instruction)
+{
+ (void)instruction;
+
+ return "ERET ";
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ERETNC(uint64 instruction)
+{
+ (void)instruction;
+
+ return "ERETNC ";
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EVP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("EVP %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EVPE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("EVPE %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXT(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_10_9_8_7_6(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTD32(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_10_9_8_7_6(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTPDP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 size_value = extract_size_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTPDPV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 size_value = extract_size_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTPV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTR_RS_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTR_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTR_S_H(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTR_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTRV_RS_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTRV_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTRV_S_H(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::EXTRV_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * EXTW - Extract Word
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 011111
+ * rt -----
+ * rs -----
+ * rd -----
+ * shift -----
+ */
+std::string NMD::EXTW(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_10_9_8_7_6(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::FLOOR_L_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::FLOOR_L_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::FLOOR_W_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::FLOOR_W_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::FORK(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::HYPCALL(uint64 instruction)
+{
+ uint64 code_value = extract_code_17_to_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("HYPCALL %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::HYPCALL_16_(uint64 instruction)
+{
+ uint64 code_value = extract_code_1_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("HYPCALL %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::INS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction);
+ uint64 lsb_value = extract_lsb_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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 */
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::INSV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("INSV %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::IRET(uint64 instruction)
+{
+ (void)instruction;
+
+ return "IRET ";
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::JALRC_16_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("JALRC $%d, %s", 31, rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::JALRC_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("JALRC %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::JALRC_HB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("JALRC.HB %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::JRC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("JRC %s", rt);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LB_16_(uint64 instruction)
+{
+ uint64 u_value = extract_u_1_0(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LB_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_17_to_0(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LB_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LB_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBU_16_(uint64 instruction)
+{
+ uint64 u_value = extract_u_1_0(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBU_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_17_to_0(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBU_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBU_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBUE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBUX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LBX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LD_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LD_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LD_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC1_GP_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC1_S9_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC1_U12_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC1XS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC1X(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDC2(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDPC_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LDXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LH_16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LH_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LH_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LH_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHU_16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHU_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHU_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHU_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHUE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHUX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHUXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LHX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LI_16_(uint64 instruction)
+{
+ uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LI_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LLD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil3il3bs5_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LLDP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LLE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LLWP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LLWPE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LSA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 u2_value = extract_u2_10_9(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LUI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il2bs4Fmsb5(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_4X4_(uint64 instruction)
+{
+ uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
+ uint64 rt4_value = extract_rt4_9_7_6_5(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_GP16_(uint64 instruction)
+{
+ uint64 u_value = extr_uil0il2bs7Fmsb8(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_SP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LW_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC1_GP_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC1_S9_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC1_U12_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC1X(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC1XS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWC2(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ct_value = extract_ct_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWPC_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWU_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWU_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWU_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWUX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWUXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWXS_16_(uint64 instruction)
+{
+ uint64 rd3_value = extract_rd3_3_2_1(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::LWXS_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MADD_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MADDF_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MADDF_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MADDU_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAQ_S_W_PHL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAQ_S_W_PHR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAQ_SA_W_PHL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAQ_SA_W_PHR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAX_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAX_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAXA_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MAXA_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MFC1 %s, %s", rt, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("MFC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MFHC1 %s, %s", rt, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("MFHC2 %s, %s", rt, cs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHI_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("MFHI %s, %s", rt, ac);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFHTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
+ uint64 u_value = extract_u_10(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFLO_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("MFLO %s, %s", rt, ac);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MFTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
+ uint64 u_value = extract_u_10(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MIN_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MIN_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MINA_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MINA_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MODSUB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MODU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOV_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MOV.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOV_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MOV.S %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVE_BALC(uint64 instruction)
+{
+ uint64 rd1_value = extract_rdl_25_24(instruction);
+ int64 s_value = extr_sil0il21bs1_il1il1bs20Tmsb21(instruction);
+ uint64 rtz4_value = extract_rtz4_27_26_25_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVEP(uint64 instruction)
+{
+ uint64 rsz4_value = extract_rsz4_4_2_1_0(instruction);
+ uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction);
+ uint64 rd2_value = extract_rd2_3_8(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 */
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVEP_REV_(uint64 instruction)
+{
+ uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
+ uint64 rt4_value = extract_rt4_9_7_6_5(instruction);
+ uint64 rd2_value = extract_rd2_3_8(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 */
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(instruction);
+ uint64 rs_value = extract_rs_4_3_2_1_0(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("MOVE %s, %s", rt, rs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVN(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MOVZ(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MSUB_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MSUBF_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MSUBF_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MSUBU_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MTC1 %s, %s", rt, fs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("MTC2 %s, %s", rt, cs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHC1(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("MTHC1 %s, %s", rt, fs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_20_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string cs = CPR(copy(cs_value));
+
+ return img::format("MTHC2 %s, %s", rt, cs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHGC0(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHI_DSP_(uint64 instruction)
+{
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("MTHI %s, %s", rs, ac);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHLIP(uint64 instruction)
+{
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("MTHLIP %s, %s", rs, ac);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTHTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
+ uint64 u_value = extract_u_10(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTLO_DSP_(uint64 instruction)
+{
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("MTLO %s, %s", rs, ac);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MTTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 c0s_value = extract_c0s_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_15_14_13_12_11(instruction);
+ uint64 u_value = extract_u_10(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUHU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_4X4_(uint64 instruction)
+{
+ uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
+ uint64 rt4_value = extract_rt4_9_7_6_5(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MUL_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULEQ_S_W_PHL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULEQ_S_W_PHR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULEU_S_PH_QBL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULEU_S_PH_QBR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULQ_RS_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULQ_RS_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULQ_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULQ_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULSA_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULSAQ_S_W_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULT_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULTU_DSP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::MULU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NEG_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("NEG.D %s, %s", ft, fs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NEG_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("NEG.S %s, %s", ft, fs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NOP_16_(uint64 instruction)
+{
+ (void)instruction;
+
+ return "NOP ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NOP_32_(uint64 instruction)
+{
+ (void)instruction;
+
+ return "NOP ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NOR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::NOT_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::OR_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::OR_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ORI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PACKRL_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PAUSE(uint64 instruction)
+{
+ (void)instruction;
+
+ return "PAUSE ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PICK_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PICK_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQ_W_PHL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQ_W_PHR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQU_PH_QBLA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQU_PH_QBL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQU_PH_QBRA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEQU_PH_QBR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEU_PH_QBLA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEU_PH_QBL(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEU_PH_QBRA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECEU_PH_QBR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECR_QB_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECR_SRA_PH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECRQ_PH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECRQ_QB_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECRQ_RS_PH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PRECRQU_S_QB_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PREF_S9_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 hint_value = extract_hint_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PREF_U12_(uint64 instruction)
+{
+ uint64 hint_value = extract_hint_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PREFE(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 hint_value = extract_hint_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::PREPEND(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RADDU_W_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RDDSP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string mask = IMMEDIATE(copy(mask_value));
+
+ return img::format("RDDSP %s, %s", rt, mask);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RDHWR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 hs_value = extract_hs_20_19_18_17_16(instruction);
+ uint64 sel_value = extract_sel_13_12_11(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RDPGPR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("RDPGPR %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RECIP_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RECIP.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RECIP_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RECIP.S %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::REPL_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::REPL_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_20_19_18_17_16_15_14_13(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string u = IMMEDIATE(copy(u_value));
+
+ return img::format("REPL.QB %s, %s", rt, u);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::REPLV_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("REPLV.PH %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::REPLV_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("REPLV.QB %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RESTORE_32_(uint64 instruction)
+{
+ uint64 count_value = extract_count_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+ uint64 gp_value = extract_gp_2(instruction);
+
+ std::string u = IMMEDIATE(copy(u_value));
+ return img::format("RESTORE %s%s", u,
+ save_restore_list(rt_value, count_value, gp_value));
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RESTORE_JRC_16_(uint64 instruction)
+{
+ uint64 count_value = extract_count_3_2_1_0(instruction);
+ uint64 rt1_value = extract_rtl_11(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));
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RESTORE_JRC_32_(uint64 instruction)
+{
+ uint64 count_value = extract_count_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+ uint64 gp_value = extract_gp_2(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));
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RESTOREF(uint64 instruction)
+{
+ uint64 count_value = extract_count_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RINT_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RINT.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RINT_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RINT.S %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROTR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROTRV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROTX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 shiftx_value = extr_shiftxil7il1bs4Fmsb4(instruction);
+ uint64 stripe_value = extract_stripe_6(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROUND_L_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROUND_L_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROUND_W_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::ROUND_W_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RSQRT_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RSQRT.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 x1110000101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::RSQRT_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("RSQRT.S %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SAVE_16_(uint64 instruction)
+{
+ uint64 count_value = extract_count_3_2_1_0(instruction);
+ uint64 rt1_value = extract_rtl_11(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));
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SAVE_32_(uint64 instruction)
+{
+ uint64 count_value = extract_count_19_18_17_16(instruction);
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extr_uil3il3bs9Fmsb11(instruction);
+ uint64 gp_value = extract_gp_2(instruction);
+
+ std::string u = IMMEDIATE(copy(u_value));
+ return img::format("SAVE %s%s", u,
+ save_restore_list(rt_value, count_value, gp_value));
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SAVEF(uint64 instruction)
+{
+ uint64 count_value = extract_count_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SB_16_(uint64 instruction)
+{
+ uint64 rtz3_value = extract_rtz3_9_8_7(instruction);
+ uint64 u_value = extract_u_1_0(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SB_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_17_to_0(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SB_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SB_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SBE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SBX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SC(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SCD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil3il3bs5_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SCDP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SCE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil2il2bs6_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SCWP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SCWPE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ru_value = extract_ru_7_6_5_4_3(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SD_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SD_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SD_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDBBP_16_(uint64 instruction)
+{
+ uint64 code_value = extract_code_2_1_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("SDBBP %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDBBP_32_(uint64 instruction)
+{
+ uint64 code_value = extract_code_18_to_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("SDBBP %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC1_GP_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC1_S9_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC1_U12_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC1X(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC1XS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDPC_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SDX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SEB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("SEB %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SEH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("SEH %s, %s", rt, rs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SEL_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SEL_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SELEQZ_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SELEQZ_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SELNEZ_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SELNEZ_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SEQI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SH_16_(uint64 instruction)
+{
+ uint64 rtz3_value = extract_rtz3_9_8_7(instruction);
+ uint64 u_value = extr_uil1il1bs2Fmsb2(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SH_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SH_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SH_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SHILO ac, shift - Shift an Accumulator Value Leaving the Result in the Same
+ * Accumulator
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000xxxx xxxx0000011101
+ * shift ------
+ * ac --
+ */
+std::string NMD::SHILO(uint64 instruction)
+{
+ int64 shift_value = extract_shift_21_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+
+ std::string shift = IMMEDIATE(copy(shift_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("SHILO %s, %s", ac, shift);
+}
+
+
+/*
+ * SHILOV ac, rs - Variable Shift of Accumulator Value Leaving the Result in
+ * the Same Accumulator
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000xxxxx 01001001111111
+ * rs -----
+ * ac --
+ */
+std::string NMD::SHILOV(uint64 instruction)
+{
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+ uint64 ac_value = extract_ac_13_12(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string ac = AC(copy(ac_value));
+
+ return img::format("SHILOV %s, %s", ac, rs);
+}
+
+
+/*
+ * SHLL.PH rt, rs, sa - Shift Left Logical Vector Pair Halfwords
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 001110110101
+ * rt -----
+ * rs -----
+ * sa ----
+ */
+std::string NMD::SHLL_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12(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);
+}
+
+
+/*
+ * SHLL.QB rt, rs, sa - Shift Left Logical Vector Quad Bytes
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 0100001111111
+ * rt -----
+ * rs -----
+ * sa ---
+ */
+std::string NMD::SHLL_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+ uint64 sa_value = extract_sa_15_14_13(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);
+}
+
+
+/*
+ * SHLL_S.PH rt, rs, sa - Shift Left Logical Vector Pair Halfwords (saturated)
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 001110110101
+ * rt -----
+ * rs -----
+ * sa ----
+ */
+std::string NMD::SHLL_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHLL_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHLLV_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHLLV_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHLLV_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHLLV_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRA_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRA_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRA_R_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRA_R_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRA_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRAV_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRAV_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRAV_R_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRAV_R_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRAV_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRL_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13_12(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRL_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 sa_value = extract_sa_15_14_13(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRLV_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHRLV_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SHXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SIGRIE(uint64 instruction)
+{
+ uint64 code_value = extract_code_18_to_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("SIGRIE %s", code);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLL_16_(uint64 instruction)
+{
+ uint64 shift3_value = extract_shift3_2_1_0(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLL_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLLV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLT(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLTI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLTIU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SLTU(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SOV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SPECIAL2(uint64 instruction)
+{
+ uint64 op_value = extract_op_25_to_3(instruction);
+
+ std::string op = IMMEDIATE(copy(op_value));
+
+ return img::format("SPECIAL2 %s", op);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SQRT_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("SQRT.D %s, %s", ft, fs);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SQRT_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+
+ std::string ft = FPR(copy(ft_value));
+ std::string fs = FPR(copy(fs_value));
+
+ return img::format("SQRT.S %s, %s", ft, fs);
+}
+
+
+/*
+ * SRA rd, rt, sa - Shift Word Right Arithmetic
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 00000000000 000011
+ * rt -----
+ * rd -----
+ * sa -----
+ */
+std::string NMD::SRA(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(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);
+}
+
+
+/*
+ * SRAV rd, rt, rs - Shift Word Right Arithmetic Variable
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00000000111
+ * rs -----
+ * rt -----
+ * rd -----
+ */
+std::string NMD::SRAV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00000000111
+ * rs -----
+ * rt -----
+ * rd -----
+ */
+std::string NMD::SRL_16_(uint64 instruction)
+{
+ uint64 shift3_value = extract_shift3_2_1_0(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SRL_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 shift_value = extract_shift_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SRLV(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUB_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUB_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 fd_value = extract_fd_10_9_8_7_6(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);
+}
+
+
+/*
+ *
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQ_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQ_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQ_S_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQH_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
+ * to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQH_R_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH_R.PH rd, rt, rs - Subtract Fractional Halfword Vectors And Shift Right
+ * to Halve Results (rounding)
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 11001001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQH_R_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBQH.W rd, rs, rt - Subtract Fractional Words And Shift Right to Halve
+ * Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBQH_W(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_16_(uint64 instruction)
+{
+ uint64 rd3_value = extract_rd3_3_2_1(instruction);
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBU.PH rd, rs, rt - Subtract Unsigned Integer Halfwords
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01100001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBU.QB rd, rs, rt - Subtract Unsigned Quad Byte Vector
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01011001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBU_S.PH rd, rs, rt - Subtract Unsigned Integer Halfwords (saturating)
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 11100001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_S_PH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBU_S.QB rd, rs, rt - Subtract Unsigned Quad Byte Vector (saturating)
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 11011001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBU_S_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBUH.QB rd, rs, rt - Subtract Unsigned Bytes And Right Shift to Halve
+ * Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01101001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBUH_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * SUBUH_R.QB rd, rs, rt - Subtract Unsigned Bytes And Right Shift to Halve
+ * Results (rounding)
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 11101001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SUBUH_R_QB(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_16_(uint64 instruction)
+{
+ uint64 rtz3_value = extract_rtz3_9_8_7(instruction);
+ uint64 u_value = extr_uil0il2bs4Fmsb5(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_4X4_(uint64 instruction)
+{
+ uint64 rs4_value = extract_rs4_4_2_1_0(instruction);
+ uint64 rtz4_value = extract_rtz4_9_7_6_5(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_GP16_(uint64 instruction)
+{
+ uint64 rtz3_value = extract_rtz3_9_8_7(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_GP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_S9_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_SP_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_9_8_7_6_5(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SW_U12_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC1_GP_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC1_S9_(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC1_U12_(uint64 instruction)
+{
+ uint64 ft_value = extract_ft_20_19_18_17_16(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC1X(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC1XS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 ft_value = extract_ft_15_14_13_12_11(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWC2(uint64 instruction)
+{
+ uint64 cs_value = extract_cs_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWPC_48_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_41_40_39_38_37(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWX(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SWXS(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SYNC(uint64 instruction)
+{
+ uint64 stype_value = extract_stype_20_19_18_17_16(instruction);
+
+ std::string stype = IMMEDIATE(copy(stype_value));
+
+ return img::format("SYNC %s", stype);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SYNCI(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string s = IMMEDIATE(copy(s_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("SYNCI %s(%s)", s, rs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SYNCIE(uint64 instruction)
+{
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string s = IMMEDIATE(copy(s_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("SYNCIE %s(%s)", s, rs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::SYSCALL_16_(uint64 instruction)
+{
+ uint64 code_value = extract_code_1_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("SYSCALL %s", code);
+}
+
+
+/*
+ * SYSCALL code - System Call. Cause a System Call Exception
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 00000000000010
+ * code ------------------
+ */
+std::string NMD::SYSCALL_32_(uint64 instruction)
+{
+ uint64 code_value = extract_code_17_to_0(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("SYSCALL %s", code);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TEQ(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("TEQ %s, %s", rs, rt);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGINV(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGINV ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGINVF(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGINVF ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGP(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGP ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGR(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGR ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGWI(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGWI ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBGWR(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBGWR ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBINV(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBINV ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBINVF(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBINVF ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBP(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBP ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBR(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBR ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBWI(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBWI ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TLBWR(uint64 instruction)
+{
+ (void)instruction;
+
+ return "TLBWR ";
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TNE(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rs = GPR(copy(rs_value));
+ std::string rt = GPR(copy(rt_value));
+
+ return img::format("TNE %s, %s", rs, rt);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TRUNC_L_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TRUNC_L_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TRUNC_W_D(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::TRUNC_W_S(uint64 instruction)
+{
+ uint64 fs_value = extract_fs_15_14_13_12_11(instruction);
+ uint64 ft_value = extract_ft_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UALDM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UALH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UALWM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UASDM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UASH(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UASWM(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 count3_value = extract_count3_14_13_12(instruction);
+ int64 s_value = extr_sil0il0bs8_il15il8bs1Tmsb8(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::UDI(uint64 instruction)
+{
+ uint64 op_value = extract_op_25_to_3(instruction);
+
+ std::string op = IMMEDIATE(copy(op_value));
+
+ return img::format("UDI %s", op);
+}
+
+
+/*
+ * WAIT code - Enter Wait State
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 1100001101111111
+ * code ----------
+ */
+std::string NMD::WAIT(uint64 instruction)
+{
+ uint64 code_value = extract_code_25_24_23_22_21_20_19_18_17_16(instruction);
+
+ std::string code = IMMEDIATE(copy(code_value));
+
+ return img::format("WAIT %s", code);
+}
+
+
+/*
+ * WRDSP rt, mask - Write Fields to DSPControl Register from a GPR
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 01011001111111
+ * rt -----
+ * mask -------
+ */
+std::string NMD::WRDSP(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 mask_value = extract_mask_20_19_18_17_16_15_14(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string mask = IMMEDIATE(copy(mask_value));
+
+ return img::format("WRDSP %s, %s", rt, mask);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::WRPGPR(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("WRPGPR %s, %s", rt, rs);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::XOR_16_(uint64 instruction)
+{
+ uint64 rt3_value = extract_rt3_9_8_7(instruction);
+ uint64 rs3_value = extract_rs3_6_5_4(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::XOR_32_(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rd_value = extract_rd_20_19_18_17_16(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * ADDQH_R.W rd, rt, rs - Add Fractional Words And Shift Right to Halve Results
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ * rd -----
+ */
+std::string NMD::XORI(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(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);
+}
+
+
+/*
+ * YIELD rt, rs -
+ *
+ * 3 2 1
+ * 10987654321098765432109876543210
+ * 001000 00010001101
+ * rt -----
+ * rs -----
+ */
+std::string NMD::YIELD(uint64 instruction)
+{
+ uint64 rt_value = extract_rt_25_24_23_22_21(instruction);
+ uint64 rs_value = extract_rs_20_19_18_17_16(instruction);
+
+ std::string rt = GPR(copy(rt_value));
+ std::string rs = GPR(copy(rs_value));
+
+ return img::format("YIELD %s, %s", rt, rs);
+}
+
+
+
+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 */
+};
diff --git a/disas/nanomips.h b/disas/nanomips.h
new file mode 100644
index 0000000000..84cc9a6dfc
--- /dev/null
+++ b/disas/nanomips.h
@@ -0,0 +1,1099 @@
+/*
+ * Header file for nanoMIPS disassembler component of QEMU
+ *
+ * Copyright (C) 2018 Wave Computing
+ * Copyright (C) 2018 Matthew Fortune <matthew.fortune@mips.com>
+ * Copyright (C) 2018 Aleksandar Markovic <aleksandar.markovic@wavecomp.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef NANOMIPS_DISASSEMBLER_H
+#define NANOMIPS_DISASSEMBLER_H
+
+#include <string>
+
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef long long int64;
+typedef unsigned long long uint64;
+
+namespace img
+{
+ typedef unsigned long long address;
+}
+
+
+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_categories)
+ : m_pc(pc)
+ , m_requested_instruction_categories(requested_instruction_categories)
+ {
+ }
+
+ int Disassemble(const uint16 *data, std::string & dis,
+ TABLE_ENTRY_TYPE & type);
+
+private:
+
+ img::address m_pc;
+ TABLE_ATTRIBUTE_TYPE m_requested_instruction_categories;
+
+ 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);
+
+ int64 extract_s_4_2_1_0(uint64 instruction);
+ int64 extr_sil0il0bs8_il15il8bs1Tmsb8(uint64 instruction);
+ int64 extr_sil0il10bs1_il1il1bs9Tmsb10(uint64 instruction);
+ int64 extr_sil0il11bs1_il1il1bs10Tmsb11(uint64 instruction);
+ int64 extr_sil0il14bs1_il1il1bs13Tmsb14(uint64 instruction);
+ int64 extr_sil0il16bs16_il16il0bs16Tmsb31(uint64 instruction);
+ int64 extr_sil0il21bs1_il1il1bs20Tmsb21(uint64 instruction);
+ int64 extr_sil0il25bs1_il1il1bs24Tmsb25(uint64 instruction);
+ int64 extr_sil0il31bs1_il2il21bs10_il12il12bs9Tmsb31(uint64 instruction);
+ int64 extr_sil0il7bs1_il1il1bs6Tmsb7(uint64 instruction);
+ int64 extr_sil11il0bs10Tmsb9(uint64 instruction);
+ int64 extract_shift_21_20_19_18_17_16(uint64 instruction);
+ int64 extr_sil2il2bs6_il15il8bs1Tmsb8(uint64 instruction);
+ int64 extr_sil3il3bs5_il15il8bs1Tmsb8(uint64 instruction);
+
+ uint64 extract_ac_13_12(uint64 instruction);
+ uint64 extract_bit_16_15_14_13_12_11(uint64 instruction);
+ uint64 extract_bit_23_22_21(uint64 instruction);
+ uint64 extract_c0s_20_19_18_17_16(uint64 instruction);
+ uint64 extract_code_17_to_0(uint64 instruction);
+ uint64 extract_code_18_to_0(uint64 instruction);
+ uint64 extract_code_1_0(uint64 instruction);
+ uint64 extract_code_2_1_0(uint64 instruction);
+ uint64 extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction);
+ uint64 extract_cofun_25_24_23(uint64 instruction);
+ uint64 extract_count3_14_13_12(uint64 instruction);
+ uint64 extract_count_3_2_1_0(uint64 instruction);
+ uint64 extract_count_19_18_17_16(uint64 instruction);
+ uint64 extract_cs_20_19_18_17_16(uint64 instruction);
+ uint64 extract_cs_25_24_23_22_21(uint64 instruction);
+ uint64 extract_ct_25_24_23_22_21(uint64 instruction);
+ uint64 extract_eu_3_2_1_0(uint64 instruction);
+ uint64 extract_eu_6_5_4_3_2_1_0(uint64 instruction);
+ uint64 extract_fd_10_9_8_7_6(uint64 instruction);
+ uint64 extract_fs_15_14_13_12_11(uint64 instruction);
+ uint64 extract_ft_15_14_13_12_11(uint64 instruction);
+ uint64 extract_ft_20_19_18_17_16(uint64 instruction);
+ uint64 extract_gp_2(uint64 instruction);
+ uint64 extract_hint_25_24_23_22_21(uint64 instruction);
+ uint64 extract_hs_20_19_18_17_16(uint64 instruction);
+ uint64 extract_lsb_4_3_2_1_0(uint64 instruction);
+ uint64 extract_mask_20_19_18_17_16_15_14(uint64 instruction);
+ uint64 extract_msbt_10_9_8_7_6(uint64 instruction);
+ uint64 extract_op_25_24_23_22_21(uint64 instruction);
+ uint64 extract_op_25_to_3(uint64 instruction);
+ uint64 extract_rdl_25_24(uint64 instruction);
+ uint64 extract_rd2_3_8(uint64 instruction);
+ uint64 extract_rd3_3_2_1(uint64 instruction);
+ uint64 extract_rd_20_19_18_17_16(uint64 instruction);
+ uint64 extract_rs3_6_5_4(uint64 instruction);
+ uint64 extract_rs4_4_2_1_0(uint64 instruction);
+ uint64 extract_rs_4_3_2_1_0(uint64 instruction);
+ uint64 extract_rs_20_19_18_17_16(uint64 instruction);
+ uint64 extract_rsz4_4_2_1_0(uint64 instruction);
+ uint64 extract_rtl_11(uint64 instruction);
+ uint64 extract_rt3_9_8_7(uint64 instruction);
+ uint64 extract_rt4_9_7_6_5(uint64 instruction);
+ uint64 extract_rt_25_24_23_22_21(uint64 instruction);
+ uint64 extract_rt_41_40_39_38_37(uint64 instruction);
+ uint64 extract_rt_9_8_7_6_5(uint64 instruction);
+ uint64 extract_rtz3_9_8_7(uint64 instruction);
+ uint64 extract_rtz4_27_26_25_23_22_21(uint64 instruction);
+ uint64 extract_rtz4_9_7_6_5(uint64 instruction);
+ uint64 extract_ru_7_6_5_4_3(uint64 instruction);
+ uint64 extract_sa_15_14_13_12_11(uint64 instruction);
+ uint64 extract_sa_15_14_13_12(uint64 instruction);
+ uint64 extract_sa_15_14_13(uint64 instruction);
+ uint64 extract_sel_13_12_11(uint64 instruction);
+ uint64 extract_sel_15_14_13_12_11(uint64 instruction);
+ uint64 extract_shift3_2_1_0(uint64 instruction);
+ uint64 extract_shift_4_3_2_1_0(uint64 instruction);
+ uint64 extract_shift_5_4_3_2_1_0(uint64 instruction);
+ uint64 extract_shift_20_19_18_17_16(uint64 instruction);
+ uint64 extract_shift_10_9_8_7_6(uint64 instruction);
+ uint64 extract_shiftx_11_10_9_8_7_6(uint64 instruction);
+ uint64 extr_shiftxil7il1bs4Fmsb4(uint64 instruction);
+ uint64 extract_size_20_19_18_17_16(uint64 instruction);
+ uint64 extract_stripe_6(uint64 instruction);
+ uint64 extract_stype_20_19_18_17_16(uint64 instruction);
+ uint64 extract_u2_10_9(uint64 instruction);
+ uint64 extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction);
+ uint64 extract_u_15_to_0(uint64 instruction);
+ uint64 extract_u_17_to_0(uint64 instruction);
+ uint64 extract_u_1_0(uint64 instruction);
+ uint64 extr_uil0il1bs4Fmsb4(uint64 instruction);
+ uint64 extr_uil0il2bs3Fmsb4(uint64 instruction);
+ uint64 extr_uil0il2bs4Fmsb5(uint64 instruction);
+ uint64 extr_uil0il2bs5Fmsb6(uint64 instruction);
+ uint64 extr_uil0il2bs6Fmsb7(uint64 instruction);
+ uint64 extr_uil0il2bs7Fmsb8(uint64 instruction);
+ uint64 extr_uil0il32bs32Fmsb63(uint64 instruction);
+ uint64 extract_u_10(uint64 instruction);
+ uint64 extract_u_17_16_15_14_13_12_11(uint64 instruction);
+ uint64 extract_u_20_19_18_17_16_15_14_13(uint64 instruction);
+ uint64 extr_uil1il1bs17Fmsb17(uint64 instruction);
+ uint64 extr_uil1il1bs2Fmsb2(uint64 instruction);
+ uint64 extr_uil2il2bs16Fmsb17(uint64 instruction);
+ uint64 extr_uil2il2bs19Fmsb20(uint64 instruction);
+ uint64 extr_uil3il3bs18Fmsb20(uint64 instruction);
+ uint64 extr_uil3il3bs1_il8il2bs1Fmsb3(uint64 instruction);
+ uint64 extr_uil3il3bs9Fmsb11(uint64 instruction);
+ uint64 extr_uil4il4bs4Fmsb7(uint64 instruction);
+ uint64 extr_xil0il0bs12Fmsb11(uint64 instruction);
+ uint64 extr_xil0il0bs3_il4il0bs1Fmsb2(uint64 instruction);
+ uint64 extr_xil10il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil10il0bs1_il11il0bs5Fmsb4(uint64 instruction);
+ uint64 extr_xil10il0bs1_il14il0bs2Fmsb1(uint64 instruction);
+ uint64 extr_xil10il0bs4_il22il0bs4Fmsb3(uint64 instruction);
+ uint64 extr_xil10il0bs6Fmsb5(uint64 instruction);
+ uint64 extr_xil11il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil11il0bs5Fmsb4(uint64 instruction);
+ uint64 extr_xil12il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil14il0bs1_il15il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil14il0bs2Fmsb1(uint64 instruction);
+ uint64 extr_xil15il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil16il0bs10Fmsb9(uint64 instruction);
+ uint64 extr_xil16il0bs5Fmsb4(uint64 instruction);
+ uint64 extr_xil17il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil17il0bs9Fmsb8(uint64 instruction);
+ uint64 extr_xil21il0bs5Fmsb4(uint64 instruction);
+ uint64 extr_xil24il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil2il0bs1_il15il0bs1Fmsb0(uint64 instruction);
+ uint64 extr_xil6il0bs3Fmsb2(uint64 instruction);
+ uint64 extr_xil6il0bs3_il10il0bs1Fmsb2(uint64 instruction);
+ uint64 extr_xil9il0bs2Fmsb1(uint64 instruction);
+ uint64 extr_xil9il0bs3Fmsb2(uint64 instruction);
+ uint64 extr_xil9il0bs3_il16il0bs5Fmsb4(uint64 instruction);
+
+ bool ADDIU_32__cond(uint64 instruction);
+ bool ADDIU_RS5__cond(uint64 instruction);
+ bool BALRSC_cond(uint64 instruction);
+ bool BEQC_16__cond(uint64 instruction);
+ bool BNEC_16__cond(uint64 instruction);
+ bool MOVE_cond(uint64 instruction);
+ bool P16_BR1_cond(uint64 instruction);
+ bool PREF_S9__cond(uint64 instruction);
+ bool PREFE_cond(uint64 instruction);
+ bool SLTU_cond(uint64 instruction);
+
+ std::string ABS_D(uint64 instruction);
+ std::string ABS_S(uint64 instruction);
+ std::string ABSQ_S_PH(uint64 instruction);
+ std::string ABSQ_S_QB(uint64 instruction);
+ std::string ABSQ_S_W(uint64 instruction);
+ std::string ACLR(uint64 instruction);
+ std::string ADD(uint64 instruction);
+ std::string ADD_D(uint64 instruction);
+ std::string ADD_S(uint64 instruction);
+ std::string ADDIU_32_(uint64 instruction);
+ std::string ADDIU_48_(uint64 instruction);
+ std::string ADDIU_GP48_(uint64 instruction);
+ std::string ADDIU_GP_B_(uint64 instruction);
+ std::string ADDIU_GP_W_(uint64 instruction);
+ std::string ADDIU_NEG_(uint64 instruction);
+ std::string ADDIU_R1_SP_(uint64 instruction);
+ std::string ADDIU_R2_(uint64 instruction);
+ std::string ADDIU_RS5_(uint64 instruction);
+ std::string ADDIUPC_32_(uint64 instruction);
+ std::string ADDIUPC_48_(uint64 instruction);
+ std::string ADDQ_PH(uint64 instruction);
+ std::string ADDQ_S_PH(uint64 instruction);
+ std::string ADDQ_S_W(uint64 instruction);
+ std::string ADDQH_PH(uint64 instruction);
+ std::string ADDQH_R_PH(uint64 instruction);
+ std::string ADDQH_R_W(uint64 instruction);
+ std::string ADDQH_W(uint64 instruction);
+ std::string ADDSC(uint64 instruction);
+ std::string ADDU_16_(uint64 instruction);
+ std::string ADDU_32_(uint64 instruction);
+ std::string ADDU_4X4_(uint64 instruction);
+ std::string ADDU_PH(uint64 instruction);
+ std::string ADDU_QB(uint64 instruction);
+ std::string ADDU_S_PH(uint64 instruction);
+ std::string ADDU_S_QB(uint64 instruction);
+ std::string ADDUH_QB(uint64 instruction);
+ std::string ADDUH_R_QB(uint64 instruction);
+ std::string ADDWC(uint64 instruction);
+ std::string ALUIPC(uint64 instruction);
+ std::string AND_16_(uint64 instruction);
+ std::string AND_32_(uint64 instruction);
+ std::string ANDI_16_(uint64 instruction);
+ std::string ANDI_32_(uint64 instruction);
+ std::string APPEND(uint64 instruction);
+ std::string ASET(uint64 instruction);
+ std::string BALC_16_(uint64 instruction);
+ std::string BALC_32_(uint64 instruction);
+ std::string BALRSC(uint64 instruction);
+ std::string BBEQZC(uint64 instruction);
+ std::string BBNEZC(uint64 instruction);
+ std::string BC_16_(uint64 instruction);
+ std::string BC_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 BEQC_16_(uint64 instruction);
+ std::string BEQC_32_(uint64 instruction);
+ std::string BEQIC(uint64 instruction);
+ std::string BEQZC_16_(uint64 instruction);
+ std::string BGEC(uint64 instruction);
+ std::string BGEIC(uint64 instruction);
+ std::string BGEIUC(uint64 instruction);
+ std::string BGEUC(uint64 instruction);
+ std::string BLTC(uint64 instruction);
+ std::string BLTIC(uint64 instruction);
+ std::string BLTIUC(uint64 instruction);
+ std::string BLTUC(uint64 instruction);
+ std::string BNEC_16_(uint64 instruction);
+ std::string BNEC_32_(uint64 instruction);
+ std::string BNEIC(uint64 instruction);
+ std::string BNEZC_16_(uint64 instruction);
+ std::string BPOSGE32C(uint64 instruction);
+ std::string BREAK_16_(uint64 instruction);
+ std::string BREAK_32_(uint64 instruction);
+ std::string BRSC(uint64 instruction);
+ std::string CACHE(uint64 instruction);
+ std::string CACHEE(uint64 instruction);
+ std::string CEIL_L_D(uint64 instruction);
+ std::string CEIL_L_S(uint64 instruction);
+ std::string CEIL_W_D(uint64 instruction);
+ std::string CEIL_W_S(uint64 instruction);
+ std::string CFC1(uint64 instruction);
+ std::string CFC2(uint64 instruction);
+ std::string CLASS_D(uint64 instruction);
+ std::string CLASS_S(uint64 instruction);
+ std::string CLO(uint64 instruction);
+ std::string CLZ(uint64 instruction);
+ std::string CMP_AF_D(uint64 instruction);
+ std::string CMP_AF_S(uint64 instruction);
+ std::string CMP_EQ_D(uint64 instruction);
+ std::string CMP_EQ_PH(uint64 instruction);
+ std::string CMP_EQ_S(uint64 instruction);
+ std::string CMP_LE_D(uint64 instruction);
+ std::string CMP_LE_PH(uint64 instruction);
+ std::string CMP_LE_S(uint64 instruction);
+ std::string CMP_LT_D(uint64 instruction);
+ std::string CMP_LT_PH(uint64 instruction);
+ std::string CMP_LT_S(uint64 instruction);
+ std::string CMP_NE_D(uint64 instruction);
+ std::string CMP_NE_S(uint64 instruction);
+ std::string CMP_OR_D(uint64 instruction);
+ std::string CMP_OR_S(uint64 instruction);
+ std::string CMP_SAF_D(uint64 instruction);
+ std::string CMP_SAF_S(uint64 instruction);
+ std::string CMP_SEQ_D(uint64 instruction);
+ std::string CMP_SEQ_S(uint64 instruction);
+ std::string CMP_SLE_D(uint64 instruction);
+ std::string CMP_SLE_S(uint64 instruction);
+ std::string CMP_SLT_D(uint64 instruction);
+ std::string CMP_SLT_S(uint64 instruction);
+ std::string CMP_SNE_D(uint64 instruction);
+ std::string CMP_SNE_S(uint64 instruction);
+ std::string CMP_SOR_D(uint64 instruction);
+ std::string CMP_SOR_S(uint64 instruction);
+ std::string CMP_SUEQ_D(uint64 instruction);
+ std::string CMP_SUEQ_S(uint64 instruction);
+ std::string CMP_SULE_D(uint64 instruction);
+ std::string CMP_SULE_S(uint64 instruction);
+ std::string CMP_SULT_D(uint64 instruction);
+ std::string CMP_SULT_S(uint64 instruction);
+ std::string CMP_SUN_D(uint64 instruction);
+ std::string CMP_SUN_S(uint64 instruction);
+ std::string CMP_SUNE_D(uint64 instruction);
+ std::string CMP_SUNE_S(uint64 instruction);
+ std::string CMP_UEQ_D(uint64 instruction);
+ std::string CMP_UEQ_S(uint64 instruction);
+ std::string CMP_ULE_D(uint64 instruction);
+ std::string CMP_ULE_S(uint64 instruction);
+ std::string CMP_ULT_D(uint64 instruction);
+ std::string CMP_ULT_S(uint64 instruction);
+ std::string CMP_UN_D(uint64 instruction);
+ std::string CMP_UN_S(uint64 instruction);
+ std::string CMP_UNE_D(uint64 instruction);
+ std::string CMP_UNE_S(uint64 instruction);
+ std::string CMPGDU_EQ_QB(uint64 instruction);
+ std::string CMPGDU_LE_QB(uint64 instruction);
+ std::string CMPGDU_LT_QB(uint64 instruction);
+ std::string CMPGU_EQ_QB(uint64 instruction);
+ std::string CMPGU_LE_QB(uint64 instruction);
+ std::string CMPGU_LT_QB(uint64 instruction);
+ std::string CMPU_EQ_QB(uint64 instruction);
+ std::string CMPU_LE_QB(uint64 instruction);
+ std::string CMPU_LT_QB(uint64 instruction);
+ std::string COP2_1(uint64 instruction);
+ std::string CTC1(uint64 instruction);
+ std::string CTC2(uint64 instruction);
+ std::string CVT_D_L(uint64 instruction);
+ std::string CVT_D_S(uint64 instruction);
+ std::string CVT_D_W(uint64 instruction);
+ std::string CVT_L_D(uint64 instruction);
+ std::string CVT_L_S(uint64 instruction);
+ std::string CVT_S_D(uint64 instruction);
+ std::string CVT_S_L(uint64 instruction);
+ std::string CVT_S_PL(uint64 instruction);
+ std::string CVT_S_PU(uint64 instruction);
+ std::string CVT_S_W(uint64 instruction);
+ std::string CVT_W_D(uint64 instruction);
+ std::string CVT_W_S(uint64 instruction);
+ std::string DADDIU_48_(uint64 instruction);
+ std::string DADDIU_NEG_(uint64 instruction);
+ std::string DADDIU_U12_(uint64 instruction);
+ std::string DADD(uint64 instruction);
+ std::string DADDU(uint64 instruction);
+ std::string DCLO(uint64 instruction);
+ std::string DCLZ(uint64 instruction);
+ std::string DDIV(uint64 instruction);
+ std::string DDIVU(uint64 instruction);
+ std::string DERET(uint64 instruction);
+ std::string DEXTM(uint64 instruction);
+ std::string DEXT(uint64 instruction);
+ std::string DEXTU(uint64 instruction);
+ std::string DINSM(uint64 instruction);
+ std::string DINS(uint64 instruction);
+ std::string DINSU(uint64 instruction);
+ std::string DI(uint64 instruction);
+ std::string DIV(uint64 instruction);
+ std::string DIV_D(uint64 instruction);
+ std::string DIV_S(uint64 instruction);
+ std::string DIVU(uint64 instruction);
+ std::string DLSA(uint64 instruction);
+ std::string DLUI_48_(uint64 instruction);
+ std::string DMFC0(uint64 instruction);
+ std::string DMFC1(uint64 instruction);
+ std::string DMFC2(uint64 instruction);
+ std::string DMFGC0(uint64 instruction);
+ std::string DMOD(uint64 instruction);
+ std::string DMODU(uint64 instruction);
+ std::string DMTC0(uint64 instruction);
+ std::string DMTC1(uint64 instruction);
+ std::string DMTC2(uint64 instruction);
+ std::string DMTGC0(uint64 instruction);
+ std::string DMT(uint64 instruction);
+ std::string DMUH(uint64 instruction);
+ std::string DMUHU(uint64 instruction);
+ std::string DMUL(uint64 instruction);
+ std::string DMULU(uint64 instruction);
+ std::string DPAQ_S_W_PH(uint64 instruction);
+ std::string DPAQ_SA_L_W(uint64 instruction);
+ std::string DPAQX_S_W_PH(uint64 instruction);
+ std::string DPAQX_SA_W_PH(uint64 instruction);
+ std::string DPAU_H_QBL(uint64 instruction);
+ std::string DPAU_H_QBR(uint64 instruction);
+ std::string DPA_W_PH(uint64 instruction);
+ std::string DPAX_W_PH(uint64 instruction);
+ std::string DPS_W_PH(uint64 instruction);
+ std::string DPSQ_SA_L_W(uint64 instruction);
+ std::string DPSQ_S_W_PH(uint64 instruction);
+ std::string DPSQX_SA_W_PH(uint64 instruction);
+ std::string DPSQX_S_W_PH(uint64 instruction);
+ std::string DPSU_H_QBL(uint64 instruction);
+ std::string DPSU_H_QBR(uint64 instruction);
+ std::string DPSX_W_PH(uint64 instruction);
+ std::string DROTR(uint64 instruction);
+ std::string DROTR32(uint64 instruction);
+ std::string DROTRV(uint64 instruction);
+ std::string DROTX(uint64 instruction);
+ std::string DSLL(uint64 instruction);
+ std::string DSLL32(uint64 instruction);
+ std::string DSLLV(uint64 instruction);
+ std::string DSRA(uint64 instruction);
+ std::string DSRA32(uint64 instruction);
+ std::string DSRAV(uint64 instruction);
+ std::string DSRL32(uint64 instruction);
+ std::string DSRL(uint64 instruction);
+ std::string DSRLV(uint64 instruction);
+ std::string DSUB(uint64 instruction);
+ std::string DSUBU(uint64 instruction);
+ std::string DVP(uint64 instruction);
+ std::string DVPE(uint64 instruction);
+ std::string EHB(uint64 instruction);
+ std::string EI(uint64 instruction);
+ std::string EMT(uint64 instruction);
+ std::string ERET(uint64 instruction);
+ std::string ERETNC(uint64 instruction);
+ std::string EVP(uint64 instruction);
+ std::string EVPE(uint64 instruction);
+ std::string EXT(uint64 instruction);
+ std::string EXTD(uint64 instruction);
+ std::string EXTD32(uint64 instruction);
+ std::string EXTP(uint64 instruction);
+ std::string EXTPDP(uint64 instruction);
+ std::string EXTPDPV(uint64 instruction);
+ std::string EXTPV(uint64 instruction);
+ std::string EXTR_RS_W(uint64 instruction);
+ std::string EXTR_R_W(uint64 instruction);
+ std::string EXTR_S_H(uint64 instruction);
+ std::string EXTR_W(uint64 instruction);
+ std::string EXTRV_R_W(uint64 instruction);
+ std::string EXTRV_RS_W(uint64 instruction);
+ std::string EXTRV_S_H(uint64 instruction);
+ std::string EXTRV_W(uint64 instruction);
+ std::string EXTW(uint64 instruction);
+ std::string FLOOR_L_D(uint64 instruction);
+ std::string FLOOR_L_S(uint64 instruction);
+ std::string FLOOR_W_D(uint64 instruction);
+ std::string FLOOR_W_S(uint64 instruction);
+ std::string FORK(uint64 instruction);
+ std::string HYPCALL(uint64 instruction);
+ std::string HYPCALL_16_(uint64 instruction);
+ std::string INS(uint64 instruction);
+ std::string INSV(uint64 instruction);
+ std::string IRET(uint64 instruction);
+ std::string JALRC_16_(uint64 instruction);
+ std::string JALRC_32_(uint64 instruction);
+ std::string JALRC_HB(uint64 instruction);
+ std::string JRC(uint64 instruction);
+ std::string LB_16_(uint64 instruction);
+ std::string LB_GP_(uint64 instruction);
+ std::string LB_S9_(uint64 instruction);
+ std::string LB_U12_(uint64 instruction);
+ std::string LBE(uint64 instruction);
+ std::string LBU_16_(uint64 instruction);
+ std::string LBU_GP_(uint64 instruction);
+ std::string LBU_S9_(uint64 instruction);
+ std::string LBU_U12_(uint64 instruction);
+ std::string LBUE(uint64 instruction);
+ std::string LBUX(uint64 instruction);
+ std::string LBX(uint64 instruction);
+ std::string LD_GP_(uint64 instruction);
+ std::string LD_S9_(uint64 instruction);
+ std::string LD_U12_(uint64 instruction);
+ std::string LDC1_GP_(uint64 instruction);
+ std::string LDC1_S9_(uint64 instruction);
+ std::string LDC1_U12_(uint64 instruction);
+ std::string LDC1X(uint64 instruction);
+ std::string LDC1XS(uint64 instruction);
+ std::string LDC2(uint64 instruction);
+ std::string LDM(uint64 instruction);
+ std::string LDPC_48_(uint64 instruction);
+ std::string LDX(uint64 instruction);
+ std::string LDXS(uint64 instruction);
+ std::string LH_16_(uint64 instruction);
+ std::string LH_GP_(uint64 instruction);
+ std::string LH_S9_(uint64 instruction);
+ std::string LH_U12_(uint64 instruction);
+ std::string LHE(uint64 instruction);
+ std::string LHU_16_(uint64 instruction);
+ std::string LHU_GP_(uint64 instruction);
+ std::string LHU_S9_(uint64 instruction);
+ std::string LHU_U12_(uint64 instruction);
+ std::string LHUE(uint64 instruction);
+ std::string LHUX(uint64 instruction);
+ std::string LHUXS(uint64 instruction);
+ std::string LHX(uint64 instruction);
+ std::string LHXS(uint64 instruction);
+ std::string LI_16_(uint64 instruction);
+ std::string LI_48_(uint64 instruction);
+ std::string LL(uint64 instruction);
+ std::string LLD(uint64 instruction);
+ std::string LLDP(uint64 instruction);
+ std::string LLE(uint64 instruction);
+ std::string LLWP(uint64 instruction);
+ std::string LLWPE(uint64 instruction);
+ std::string LSA(uint64 instruction);
+ std::string LUI(uint64 instruction);
+ std::string LW_16_(uint64 instruction);
+ std::string LW_4X4_(uint64 instruction);
+ std::string LWC1_GP_(uint64 instruction);
+ std::string LWC1_S9_(uint64 instruction);
+ std::string LWC1_U12_(uint64 instruction);
+ std::string LWC1X(uint64 instruction);
+ std::string LWC1XS(uint64 instruction);
+ std::string LWC2(uint64 instruction);
+ std::string LWE(uint64 instruction);
+ std::string LW_GP_(uint64 instruction);
+ std::string LW_GP16_(uint64 instruction);
+ std::string LWM(uint64 instruction);
+ std::string LWPC_48_(uint64 instruction);
+ std::string LW_S9_(uint64 instruction);
+ std::string LW_SP_(uint64 instruction);
+ std::string LW_U12_(uint64 instruction);
+ std::string LWU_GP_(uint64 instruction);
+ std::string LWU_S9_(uint64 instruction);
+ std::string LWU_U12_(uint64 instruction);
+ std::string LWUX(uint64 instruction);
+ std::string LWUXS(uint64 instruction);
+ std::string LWX(uint64 instruction);
+ std::string LWXS_16_(uint64 instruction);
+ std::string LWXS_32_(uint64 instruction);
+ std::string MADD_DSP_(uint64 instruction);
+ std::string MADDF_D(uint64 instruction);
+ std::string MADDF_S(uint64 instruction);
+ std::string MADDU_DSP_(uint64 instruction);
+ std::string MAQ_S_W_PHL(uint64 instruction);
+ std::string MAQ_S_W_PHR(uint64 instruction);
+ std::string MAQ_SA_W_PHL(uint64 instruction);
+ std::string MAQ_SA_W_PHR(uint64 instruction);
+ std::string MAX_D(uint64 instruction);
+ std::string MAX_S(uint64 instruction);
+ std::string MAXA_D(uint64 instruction);
+ std::string MAXA_S(uint64 instruction);
+ std::string MFC0(uint64 instruction);
+ std::string MFC1(uint64 instruction);
+ std::string MFC2(uint64 instruction);
+ std::string MFGC0(uint64 instruction);
+ std::string MFHC0(uint64 instruction);
+ std::string MFHC1(uint64 instruction);
+ std::string MFHC2(uint64 instruction);
+ std::string MFHGC0(uint64 instruction);
+ std::string MFHI_DSP_(uint64 instruction);
+ std::string MFHTR(uint64 instruction);
+ std::string MFLO_DSP_(uint64 instruction);
+ std::string MFTR(uint64 instruction);
+ std::string MIN_D(uint64 instruction);
+ std::string MIN_S(uint64 instruction);
+ std::string MINA_D(uint64 instruction);
+ std::string MINA_S(uint64 instruction);
+ std::string MOD(uint64 instruction);
+ std::string MODSUB(uint64 instruction);
+ std::string MODU(uint64 instruction);
+ std::string MOV_D(uint64 instruction);
+ std::string MOV_S(uint64 instruction);
+ std::string MOVE_BALC(uint64 instruction);
+ std::string MOVEP(uint64 instruction);
+ std::string MOVEP_REV_(uint64 instruction);
+ std::string MOVE(uint64 instruction);
+ std::string MOVN(uint64 instruction);
+ std::string MOVZ(uint64 instruction);
+ std::string MSUB_DSP_(uint64 instruction);
+ std::string MSUBF_D(uint64 instruction);
+ std::string MSUBF_S(uint64 instruction);
+ std::string MSUBU_DSP_(uint64 instruction);
+ std::string MTC0(uint64 instruction);
+ std::string MTC1(uint64 instruction);
+ std::string MTC2(uint64 instruction);
+ std::string MTGC0(uint64 instruction);
+ std::string MTHC0(uint64 instruction);
+ std::string MTHC1(uint64 instruction);
+ std::string MTHC2(uint64 instruction);
+ std::string MTHGC0(uint64 instruction);
+ std::string MTHI_DSP_(uint64 instruction);
+ std::string MTHLIP(uint64 instruction);
+ std::string MTHTR(uint64 instruction);
+ std::string MTLO_DSP_(uint64 instruction);
+ std::string MTTR(uint64 instruction);
+ std::string MUH(uint64 instruction);
+ std::string MUHU(uint64 instruction);
+ std::string MUL_32_(uint64 instruction);
+ std::string MUL_4X4_(uint64 instruction);
+ std::string MUL_D(uint64 instruction);
+ std::string MUL_PH(uint64 instruction);
+ std::string MUL_S(uint64 instruction);
+ std::string MUL_S_PH(uint64 instruction);
+ std::string MULEQ_S_W_PHL(uint64 instruction);
+ std::string MULEQ_S_W_PHR(uint64 instruction);
+ std::string MULEU_S_PH_QBL(uint64 instruction);
+ std::string MULEU_S_PH_QBR(uint64 instruction);
+ std::string MULQ_RS_PH(uint64 instruction);
+ std::string MULQ_RS_W(uint64 instruction);
+ std::string MULQ_S_PH(uint64 instruction);
+ std::string MULQ_S_W(uint64 instruction);
+ std::string MULSA_W_PH(uint64 instruction);
+ std::string MULSAQ_S_W_PH(uint64 instruction);
+ std::string MULT_DSP_(uint64 instruction);
+ std::string MULTU_DSP_(uint64 instruction);
+ std::string MULU(uint64 instruction);
+ std::string NEG_D(uint64 instruction);
+ std::string NEG_S(uint64 instruction);
+ std::string NOP_16_(uint64 instruction);
+ std::string NOP_32_(uint64 instruction);
+ std::string NOR(uint64 instruction);
+ std::string NOT_16_(uint64 instruction);
+ std::string OR_16_(uint64 instruction);
+ std::string OR_32_(uint64 instruction);
+ std::string ORI(uint64 instruction);
+ std::string PACKRL_PH(uint64 instruction);
+ std::string PAUSE(uint64 instruction);
+ std::string PICK_PH(uint64 instruction);
+ std::string PICK_QB(uint64 instruction);
+ std::string PRECEQ_W_PHL(uint64 instruction);
+ std::string PRECEQ_W_PHR(uint64 instruction);
+ std::string PRECEQU_PH_QBL(uint64 instruction);
+ std::string PRECEQU_PH_QBLA(uint64 instruction);
+ std::string PRECEQU_PH_QBR(uint64 instruction);
+ std::string PRECEQU_PH_QBRA(uint64 instruction);
+ std::string PRECEU_PH_QBL(uint64 instruction);
+ std::string PRECEU_PH_QBLA(uint64 instruction);
+ std::string PRECEU_PH_QBR(uint64 instruction);
+ std::string PRECEU_PH_QBRA(uint64 instruction);
+ std::string PRECR_QB_PH(uint64 instruction);
+ std::string PRECR_SRA_PH_W(uint64 instruction);
+ std::string PRECR_SRA_R_PH_W(uint64 instruction);
+ std::string PRECRQ_PH_W(uint64 instruction);
+ std::string PRECRQ_QB_PH(uint64 instruction);
+ std::string PRECRQ_RS_PH_W(uint64 instruction);
+ std::string PRECRQU_S_QB_PH(uint64 instruction);
+ std::string PREF_S9_(uint64 instruction);
+ std::string PREF_U12_(uint64 instruction);
+ std::string PREFE(uint64 instruction);
+ std::string PREPEND(uint64 instruction);
+ std::string RADDU_W_QB(uint64 instruction);
+ std::string RDDSP(uint64 instruction);
+ std::string RDHWR(uint64 instruction);
+ std::string RDPGPR(uint64 instruction);
+ std::string RECIP_D(uint64 instruction);
+ std::string RECIP_S(uint64 instruction);
+ std::string REPL_PH(uint64 instruction);
+ std::string REPL_QB(uint64 instruction);
+ std::string REPLV_PH(uint64 instruction);
+ std::string REPLV_QB(uint64 instruction);
+ std::string RESTORE_32_(uint64 instruction);
+ std::string RESTORE_JRC_16_(uint64 instruction);
+ std::string RESTORE_JRC_32_(uint64 instruction);
+ std::string RESTOREF(uint64 instruction);
+ std::string RINT_D(uint64 instruction);
+ std::string RINT_S(uint64 instruction);
+ std::string ROTR(uint64 instruction);
+ std::string ROTRV(uint64 instruction);
+ std::string ROTX(uint64 instruction);
+ std::string ROUND_L_D(uint64 instruction);
+ std::string ROUND_L_S(uint64 instruction);
+ std::string ROUND_W_D(uint64 instruction);
+ std::string ROUND_W_S(uint64 instruction);
+ std::string RSQRT_D(uint64 instruction);
+ std::string RSQRT_S(uint64 instruction);
+ std::string SAVE_16_(uint64 instruction);
+ std::string SAVE_32_(uint64 instruction);
+ std::string SAVEF(uint64 instruction);
+ std::string SB_16_(uint64 instruction);
+ std::string SB_GP_(uint64 instruction);
+ std::string SB_S9_(uint64 instruction);
+ std::string SB_U12_(uint64 instruction);
+ std::string SBE(uint64 instruction);
+ std::string SBX(uint64 instruction);
+ std::string SC(uint64 instruction);
+ std::string SCD(uint64 instruction);
+ std::string SCDP(uint64 instruction);
+ std::string SCE(uint64 instruction);
+ std::string SCWP(uint64 instruction);
+ std::string SCWPE(uint64 instruction);
+ std::string SD_GP_(uint64 instruction);
+ std::string SD_S9_(uint64 instruction);
+ std::string SD_U12_(uint64 instruction);
+ std::string SDBBP_16_(uint64 instruction);
+ std::string SDBBP_32_(uint64 instruction);
+ std::string SDC1_GP_(uint64 instruction);
+ std::string SDC1_S9_(uint64 instruction);
+ std::string SDC1_U12_(uint64 instruction);
+ std::string SDC1X(uint64 instruction);
+ std::string SDC1XS(uint64 instruction);
+ std::string SDC2(uint64 instruction);
+ std::string SDM(uint64 instruction);
+ std::string SDPC_48_(uint64 instruction);
+ std::string SDX(uint64 instruction);
+ std::string SDXS(uint64 instruction);
+ std::string SEB(uint64 instruction);
+ std::string SEH(uint64 instruction);
+ std::string SEL_D(uint64 instruction);
+ std::string SEL_S(uint64 instruction);
+ std::string SELEQZ_D(uint64 instruction);
+ std::string SELEQZ_S(uint64 instruction);
+ std::string SELNEZ_D(uint64 instruction);
+ std::string SELNEZ_S(uint64 instruction);
+ std::string SEQI(uint64 instruction);
+ std::string SH_16_(uint64 instruction);
+ std::string SH_GP_(uint64 instruction);
+ std::string SH_S9_(uint64 instruction);
+ std::string SH_U12_(uint64 instruction);
+ std::string SHE(uint64 instruction);
+ std::string SHILO(uint64 instruction);
+ std::string SHILOV(uint64 instruction);
+ std::string SHLL_PH(uint64 instruction);
+ std::string SHLL_QB(uint64 instruction);
+ std::string SHLL_S_PH(uint64 instruction);
+ std::string SHLL_S_W(uint64 instruction);
+ std::string SHLLV_PH(uint64 instruction);
+ std::string SHLLV_QB(uint64 instruction);
+ std::string SHLLV_S_PH(uint64 instruction);
+ std::string SHLLV_S_W(uint64 instruction);
+ std::string SHRA_PH(uint64 instruction);
+ std::string SHRA_QB(uint64 instruction);
+ std::string SHRA_R_PH(uint64 instruction);
+ std::string SHRA_R_QB(uint64 instruction);
+ std::string SHRA_R_W(uint64 instruction);
+ std::string SHRAV_PH(uint64 instruction);
+ std::string SHRAV_QB(uint64 instruction);
+ std::string SHRAV_R_PH(uint64 instruction);
+ std::string SHRAV_R_QB(uint64 instruction);
+ std::string SHRAV_R_W(uint64 instruction);
+ std::string SHRL_PH(uint64 instruction);
+ std::string SHRL_QB(uint64 instruction);
+ std::string SHRLV_PH(uint64 instruction);
+ std::string SHRLV_QB(uint64 instruction);
+ std::string SHX(uint64 instruction);
+ std::string SHXS(uint64 instruction);
+ std::string SIGRIE(uint64 instruction);
+ std::string SLL_16_(uint64 instruction);
+ std::string SLL_32_(uint64 instruction);
+ std::string SLLV(uint64 instruction);
+ std::string SLT(uint64 instruction);
+ std::string SLTI(uint64 instruction);
+ std::string SLTIU(uint64 instruction);
+ std::string SLTU(uint64 instruction);
+ std::string SOV(uint64 instruction);
+ std::string SPECIAL2(uint64 instruction);
+ std::string SQRT_D(uint64 instruction);
+ std::string SQRT_S(uint64 instruction);
+ std::string SRA(uint64 instruction);
+ std::string SRAV(uint64 instruction);
+ std::string SRL_16_(uint64 instruction);
+ std::string SRL_32_(uint64 instruction);
+ std::string SRLV(uint64 instruction);
+ std::string SUB(uint64 instruction);
+ std::string SUB_D(uint64 instruction);
+ std::string SUB_S(uint64 instruction);
+ std::string SUBQ_PH(uint64 instruction);
+ std::string SUBQ_S_PH(uint64 instruction);
+ std::string SUBQ_S_W(uint64 instruction);
+ std::string SUBQH_PH(uint64 instruction);
+ std::string SUBQH_R_PH(uint64 instruction);
+ std::string SUBQH_R_W(uint64 instruction);
+ std::string SUBQH_W(uint64 instruction);
+ std::string SUBU_16_(uint64 instruction);
+ std::string SUBU_32_(uint64 instruction);
+ std::string SUBU_PH(uint64 instruction);
+ std::string SUBU_QB(uint64 instruction);
+ std::string SUBU_S_PH(uint64 instruction);
+ std::string SUBU_S_QB(uint64 instruction);
+ std::string SUBUH_QB(uint64 instruction);
+ std::string SUBUH_R_QB(uint64 instruction);
+ std::string SW_16_(uint64 instruction);
+ std::string SW_4X4_(uint64 instruction);
+ std::string SW_GP16_(uint64 instruction);
+ std::string SW_GP_(uint64 instruction);
+ std::string SW_S9_(uint64 instruction);
+ std::string SW_SP_(uint64 instruction);
+ std::string SW_U12_(uint64 instruction);
+ std::string SWC1_GP_(uint64 instruction);
+ std::string SWC1_S9_(uint64 instruction);
+ std::string SWC1_U12_(uint64 instruction);
+ std::string SWC1X(uint64 instruction);
+ std::string SWC1XS(uint64 instruction);
+ std::string SWC2(uint64 instruction);
+ std::string SWE(uint64 instruction);
+ std::string SWM(uint64 instruction);
+ std::string SWPC_48_(uint64 instruction);
+ std::string SWX(uint64 instruction);
+ std::string SWXS(uint64 instruction);
+ std::string SYNC(uint64 instruction);
+ std::string SYNCI(uint64 instruction);
+ std::string SYNCIE(uint64 instruction);
+ std::string SYSCALL_16_(uint64 instruction);
+ std::string SYSCALL_32_(uint64 instruction);
+ std::string TEQ(uint64 instruction);
+ std::string TLBGINV(uint64 instruction);
+ std::string TLBGINVF(uint64 instruction);
+ std::string TLBGP(uint64 instruction);
+ std::string TLBGR(uint64 instruction);
+ std::string TLBGWI(uint64 instruction);
+ std::string TLBGWR(uint64 instruction);
+ std::string TLBINV(uint64 instruction);
+ std::string TLBINVF(uint64 instruction);
+ std::string TLBP(uint64 instruction);
+ std::string TLBR(uint64 instruction);
+ std::string TLBWI(uint64 instruction);
+ std::string TLBWR(uint64 instruction);
+ std::string TNE(uint64 instruction);
+ std::string TRUNC_L_D(uint64 instruction);
+ std::string TRUNC_L_S(uint64 instruction);
+ std::string TRUNC_W_D(uint64 instruction);
+ std::string TRUNC_W_S(uint64 instruction);
+ std::string UALDM(uint64 instruction);
+ std::string UALH(uint64 instruction);
+ std::string UALWM(uint64 instruction);
+ std::string UASDM(uint64 instruction);
+ std::string UASH(uint64 instruction);
+ std::string UASWM(uint64 instruction);
+ std::string UDI(uint64 instruction);
+ std::string WAIT(uint64 instruction);
+ std::string WRDSP(uint64 instruction);
+ std::string WRPGPR(uint64 instruction);
+ std::string XOR_16_(uint64 instruction);
+ std::string XOR_32_(uint64 instruction);
+ std::string XORI(uint64 instruction);
+ std::string YIELD(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/fsdev/qemu-fsdev-dummy.c b/fsdev/qemu-fsdev-dummy.c
index 6dc0fbc4c4..489cd29081 100644
--- a/fsdev/qemu-fsdev-dummy.c
+++ b/fsdev/qemu-fsdev-dummy.c
@@ -15,7 +15,7 @@
#include "qemu/config-file.h"
#include "qemu/module.h"
-int qemu_fsdev_add(QemuOpts *opts)
+int qemu_fsdev_add(QemuOpts *opts, Error **errp)
{
return 0;
}
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 8a4afbffbd..7a3b87cc9e 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -30,7 +30,7 @@ static FsDriverTable FsDrivers[] = {
{ .name = "proxy", .ops = &proxy_ops},
};
-int qemu_fsdev_add(QemuOpts *opts)
+int qemu_fsdev_add(QemuOpts *opts, Error **errp)
{
int i;
struct FsDriverListEntry *fsle;
@@ -38,10 +38,9 @@ int qemu_fsdev_add(QemuOpts *opts)
const char *fsdriver = qemu_opt_get(opts, "fsdriver");
const char *writeout = qemu_opt_get(opts, "writeout");
bool ro = qemu_opt_get_bool(opts, "readonly", 0);
- Error *local_err = NULL;
if (!fsdev_id) {
- error_report("fsdev: No id specified");
+ error_setg(errp, "fsdev: No id specified");
return -1;
}
@@ -53,11 +52,11 @@ int qemu_fsdev_add(QemuOpts *opts)
}
if (i == ARRAY_SIZE(FsDrivers)) {
- error_report("fsdev: fsdriver %s not found", fsdriver);
+ error_setg(errp, "fsdev: fsdriver %s not found", fsdriver);
return -1;
}
} else {
- error_report("fsdev: No fsdriver specified");
+ error_setg(errp, "fsdev: No fsdriver specified");
return -1;
}
@@ -76,8 +75,7 @@ int qemu_fsdev_add(QemuOpts *opts)
}
if (fsle->fse.ops->parse_opts) {
- if (fsle->fse.ops->parse_opts(opts, &fsle->fse, &local_err)) {
- error_report_err(local_err);
+ if (fsle->fse.ops->parse_opts(opts, &fsle->fse, errp)) {
g_free(fsle->fse.fsdev_id);
g_free(fsle);
return -1;
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index 65e4b1cfab..d9716b4144 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -38,7 +38,7 @@ typedef struct FsDriverListEntry {
QTAILQ_ENTRY(FsDriverListEntry) next;
} FsDriverListEntry;
-int qemu_fsdev_add(QemuOpts *opts);
+int qemu_fsdev_add(QemuOpts *opts, Error **errp);
FsDriverEntry *get_fsdev_fsentry(char *id);
extern FileOperations local_ops;
extern FileOperations handle_ops;
diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index f3641dbe4a..3465b1ef30 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -19,6 +19,7 @@
#include <grp.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include "qapi/error.h"
#include "qemu/xattr.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
@@ -655,12 +656,13 @@ static int handle_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
warn_report("handle backend is deprecated");
if (sec_model) {
- error_report("Invalid argument security_model specified with handle fsdriver");
+ error_setg(errp,
+ "Invalid argument security_model specified with handle fsdriver");
return -1;
}
if (!path) {
- error_report("fsdev: No path specified");
+ error_setg(errp, "fsdev: No path specified");
return -1;
}
fse->path = g_strdup(path);
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index c30f4f26bd..08e673a79c 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1509,8 +1509,8 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp)
fsdev_throttle_parse_opts(opts, &fse->fst, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "invalid throttle configuration: ");
+ error_propagate_prepend(errp, local_err,
+ "invalid throttle configuration: ");
return -1;
}
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 6026780f95..3f54a21c76 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -14,6 +14,7 @@
#include "hw/9pfs/9p.h"
#include "hw/xen/xen_backend.h"
#include "hw/9pfs/xen-9pfs.h"
+#include "qapi/error.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "fsdev/qemu-fsdev.h"
@@ -355,6 +356,7 @@ static int xen_9pfs_free(struct XenDevice *xendev)
static int xen_9pfs_connect(struct XenDevice *xendev)
{
+ Error *err = NULL;
int i;
Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
V9fsState *s = &xen_9pdev->state;
@@ -452,7 +454,10 @@ static int xen_9pfs_connect(struct XenDevice *xendev)
qemu_opt_set(fsdev, "path", xen_9pdev->path, NULL);
qemu_opt_set(fsdev, "security_model", xen_9pdev->security_model, NULL);
qemu_opts_set_id(fsdev, s->fsconf.fsdev_id);
- qemu_fsdev_add(fsdev);
+ qemu_fsdev_add(fsdev, &err);
+ if (err) {
+ error_report_err(err);
+ }
v9fs_device_realize_common(s, &xen_9p_transport, NULL);
return 0;
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 30722ccf98..39d882af6f 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -34,7 +34,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += vfio/
devices-dirs-$(CONFIG_SOFTMMU) += virtio/
devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
devices-dirs-$(CONFIG_SOFTMMU) += xen/
-devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
+devices-dirs-$(CONFIG_MEM_DEVICE) += mem/
devices-dirs-$(CONFIG_SOFTMMU) += smbios/
devices-dirs-y += core/
common-obj-y += $(devices-dirs-y)
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index d74b5b55e1..8004afe45b 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -932,23 +932,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
return b;
}
-static int typhoon_pcihost_init(SysBusDevice *dev)
-{
- return 0;
-}
-
-static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = typhoon_pcihost_init;
-}
-
static const TypeInfo typhoon_pcihost_info = {
.name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(TyphoonState),
- .class_init = typhoon_pcihost_class_init,
};
static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 20c71d7d96..586baa9b64 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -24,6 +24,7 @@
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "exec/address-spaces.h"
+#include "qemu/units.h"
/* Kernel boot protocol is specified in the kernel docs
* Documentation/arm/Booting and Documentation/arm64/booting.txt
@@ -36,6 +37,8 @@
#define ARM64_TEXT_OFFSET_OFFSET 8
#define ARM64_MAGIC_OFFSET 56
+#define BOOTLOADER_MAX_SIZE (4 * KiB)
+
AddressSpace *arm_boot_address_space(ARMCPU *cpu,
const struct arm_boot_info *info)
{
@@ -184,6 +187,8 @@ static void write_bootloader(const char *name, hwaddr addr,
code[i] = tswap32(insn);
}
+ assert((len * sizeof(uint32_t)) < BOOTLOADER_MAX_SIZE);
+
rom_add_blob_fixed_as(name, code, len * sizeof(uint32_t), addr, as);
g_free(code);
@@ -919,6 +924,19 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
if (hdrvals[1] != 0) {
kernel_load_offset = le64_to_cpu(hdrvals[0]);
+
+ /*
+ * We write our startup "bootloader" at the very bottom of RAM,
+ * so that bit can't be used for the image. Luckily the Image
+ * format specification is that the image requests only an offset
+ * from a 2MB boundary, not an absolute load address. So if the
+ * image requests an offset that might mean it overlaps with the
+ * bootloader, we can just load it starting at 2MB+offset rather
+ * than 0MB + offset.
+ */
+ if (kernel_load_offset < BOOTLOADER_MAX_SIZE) {
+ kernel_load_offset += 2 * MiB;
+ }
}
}
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index b736ce223a..a799c83815 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -21,5 +21,4 @@ common-obj-$(CONFIG_SOFTMMU) += or-irq.o
common-obj-$(CONFIG_SOFTMMU) += split-irq.o
common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
common-obj-$(CONFIG_SOFTMMU) += generic-loader.o
-
-obj-$(CONFIG_SOFTMMU) += null-machine.o
+common-obj-$(CONFIG_SOFTMMU) += null-machine.o
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1987557833..da50ad6de7 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -636,7 +636,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
machine_get_memory_encryption, machine_set_memory_encryption,
&error_abort);
object_class_property_set_description(oc, "memory-encryption",
- "Set memory encyption object to use", &error_abort);
+ "Set memory encryption object to use", &error_abort);
}
static void machine_class_base_init(ObjectClass *oc, void *data)
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index cde4d3eb57..76d3f8e39c 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -18,7 +18,7 @@
#include "hw/boards.h"
#include "sysemu/sysemu.h"
#include "exec/address-spaces.h"
-#include "cpu.h"
+#include "qom/cpu.h"
static void machine_none_init(MachineState *mch)
{
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index 1c199ab369..e50d97e48c 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -307,7 +307,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
ret = load_image_mr(fcode_filename, &s->rom);
g_free(fcode_filename);
if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
+ warn_report("cg3: could not load prom '%s'", CG3_ROM_FILE);
}
}
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
index b2786ee8d0..66f2459226 100644
--- a/hw/display/tcx.c
+++ b/hw/display/tcx.c
@@ -823,7 +823,7 @@ static void tcx_realizefn(DeviceState *dev, Error **errp)
ret = load_image_mr(fcode_filename, &s->rom);
g_free(fcode_filename);
if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
- error_report("tcx: could not load prom '%s'", TCX_ROM_FILE);
+ warn_report("tcx: could not load prom '%s'", TCX_ROM_FILE);
}
}
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
index 564b938e3a..31e09942b5 100644
--- a/hw/hppa/dino.c
+++ b/hw/hppa/dino.c
@@ -488,17 +488,10 @@ PCIBus *dino_init(MemoryRegion *addr_space,
return b;
}
-static int dino_pcihost_init(SysBusDevice *dev)
-{
- return 0;
-}
-
static void dino_pcihost_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = dino_pcihost_init;
dc->vmsd = &vmstate_dino;
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index cd5029c149..f095725dba 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1704,7 +1704,7 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- pc_dimm_pre_plug(dev, MACHINE(hotplug_dev),
+ pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev),
pcmc->enforce_aligned_dimm ? NULL : &legacy_align, errp);
}
@@ -1716,7 +1716,7 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev,
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
- pc_dimm_plug(dev, MACHINE(pcms), &local_err);
+ pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms), &local_err);
if (local_err) {
goto out;
}
@@ -1776,7 +1776,7 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev,
goto out;
}
- pc_dimm_unplug(dev, MACHINE(pcms));
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(pcms));
object_unparent(OBJECT(dev));
out:
@@ -2209,8 +2209,9 @@ static void pc_machine_set_nvdimm_persistence(Object *obj, const char *value,
else if (strcmp(value, "mem-ctrl") == 0)
nvdimm_state->persistence = 2;
else {
- error_report("-machine nvdimm-persistence=%s: unsupported option", value);
- exit(EXIT_FAILURE);
+ error_setg(errp, "-machine nvdimm-persistence=%s: unsupported option",
+ value);
+ return;
}
g_free(nvdimm_state->persistence_string);
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 0d816fdd2c..0beefb05d4 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1055,17 +1055,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
case 0xd5c: /* MMFR3. */
return cpu->id_mmfr3;
case 0xd60: /* ISAR0. */
- return cpu->id_isar0;
+ return cpu->isar.id_isar0;
case 0xd64: /* ISAR1. */
- return cpu->id_isar1;
+ return cpu->isar.id_isar1;
case 0xd68: /* ISAR2. */
- return cpu->id_isar2;
+ return cpu->isar.id_isar2;
case 0xd6c: /* ISAR3. */
- return cpu->id_isar3;
+ return cpu->isar.id_isar3;
case 0xd70: /* ISAR4. */
- return cpu->id_isar4;
+ return cpu->isar.id_isar4;
case 0xd74: /* ISAR5. */
- return cpu->id_isar5;
+ return cpu->isar.id_isar5;
case 0xd78: /* CLIDR */
return cpu->clidr;
case 0xd7c: /* CTR */
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index b6896ac4ce..4e529729b4 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -21,7 +21,7 @@
*/
#include "qemu/osdep.h"
-#include "qemu/error-report.h"
+#include "qapi/error.h"
#include "monitor/monitor.h"
#include "hw/hw.h"
#include "hw/i386/pc.h"
@@ -393,9 +393,9 @@ static void ioapic_realize(DeviceState *dev, Error **errp)
IOAPICCommonState *s = IOAPIC_COMMON(dev);
if (s->version != 0x11 && s->version != 0x20) {
- error_report("IOAPIC only supports version 0x11 or 0x20 "
- "(default: 0x%x).", IOAPIC_VER_DEF);
- exit(1);
+ error_setg(errp, "IOAPIC only supports version 0x11 or 0x20 "
+ "(default: 0x%x).", IOAPIC_VER_DEF);
+ return;
}
memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s,
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index c90c893228..406efee064 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -320,8 +320,9 @@ static void icp_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), ICP_PROP_XICS, &err);
if (!obj) {
- error_propagate(errp, err);
- error_prepend(errp, "required link '" ICP_PROP_XICS "' not found: ");
+ error_propagate_prepend(errp, err,
+ "required link '" ICP_PROP_XICS
+ "' not found: ");
return;
}
@@ -329,8 +330,9 @@ static void icp_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
if (!obj) {
- error_propagate(errp, err);
- error_prepend(errp, "required link '" ICP_PROP_CPU "' not found: ");
+ error_propagate_prepend(errp, err,
+ "required link '" ICP_PROP_CPU
+ "' not found: ");
return;
}
@@ -624,8 +626,9 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), ICS_PROP_XICS, &err);
if (!obj) {
- error_propagate(errp, err);
- error_prepend(errp, "required link '" ICS_PROP_XICS "' not found: ");
+ error_propagate_prepend(errp, err,
+ "required link '" ICS_PROP_XICS
+ "' not found: ");
return;
}
ics->xics = XICS_FABRIC(obj);
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index 30c3769a20..e8fa9a53ae 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -198,17 +198,12 @@ static void ics_get_kvm_state(ICSState *ics)
{
uint64_t state;
int i;
- Error *local_err = NULL;
for (i = 0; i < ics->nr_irqs; i++) {
ICSIRQState *irq = &ics->irqs[i];
kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
- i + ics->offset, &state, false, &local_err);
- if (local_err) {
- error_report_err(local_err);
- exit(1);
- }
+ i + ics->offset, &state, false, &error_fatal);
irq->server = state & KVM_XICS_DESTINATION_MASK;
irq->saved_priority = (state >> KVM_XICS_PRIORITY_SHIFT)
diff --git a/hw/isa/Makefile.objs b/hw/isa/Makefile.objs
index 83e06f6c04..9e106df186 100644
--- a/hw/isa/Makefile.objs
+++ b/hw/isa/Makefile.objs
@@ -1,9 +1,10 @@
common-obj-$(CONFIG_ISA_BUS) += isa-bus.o
-common-obj-$(CONFIG_ISA_BUS) += isa-superio.o smc37c669-superio.o
+common-obj-$(CONFIG_ISA_BUS) += isa-superio.o
common-obj-$(CONFIG_APM) += apm.o
common-obj-$(CONFIG_I82378) += i82378.o
common-obj-$(CONFIG_PC87312) += pc87312.o
common-obj-$(CONFIG_PIIX4) += piix4.o
common-obj-$(CONFIG_VT82C686) += vt82c686.o
+common-obj-$(CONFIG_SMC37C669) += smc37c669-superio.o
obj-$(CONFIG_LPC_ICH9) += lpc_ich9.o
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
index 10be4df2a2..3e2f7c5ca2 100644
--- a/hw/mem/Makefile.objs
+++ b/hw/mem/Makefile.objs
@@ -1,3 +1,3 @@
-common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
-common-obj-$(CONFIG_MEM_HOTPLUG) += memory-device.o
+common-obj-$(CONFIG_DIMM) += pc-dimm.o
+common-obj-$(CONFIG_MEM_DEVICE) += memory-device.o
common-obj-$(CONFIG_NVDIMM) += nvdimm.o
diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c
index 6de4f70bb4..7de1ccd497 100644
--- a/hw/mem/memory-device.c
+++ b/hw/mem/memory-device.c
@@ -17,6 +17,7 @@
#include "qemu/range.h"
#include "hw/virtio/vhost.h"
#include "sysemu/kvm.h"
+#include "trace.h"
static gint memory_device_addr_sort(gconstpointer a, gconstpointer b)
{
@@ -57,10 +58,9 @@ static int memory_device_used_region_size(Object *obj, void *opaque)
if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) {
const DeviceState *dev = DEVICE(obj);
const MemoryDeviceState *md = MEMORY_DEVICE(obj);
- const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj);
if (dev->realized) {
- *size += mdc->get_region_size(md);
+ *size += memory_device_get_region_size(md, &error_abort);
}
}
@@ -87,16 +87,17 @@ static void memory_device_check_addable(MachineState *ms, uint64_t size,
memory_device_used_region_size(OBJECT(ms), &used_region_size);
if (used_region_size + size > ms->maxram_size - ms->ram_size) {
error_setg(errp, "not enough space, currently 0x%" PRIx64
- " in use of total hot pluggable 0x" RAM_ADDR_FMT,
+ " in use of total space for memory devices 0x" RAM_ADDR_FMT,
used_region_size, ms->maxram_size - ms->ram_size);
return;
}
}
-uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
- uint64_t align, uint64_t size,
- Error **errp)
+static uint64_t memory_device_get_free_addr(MachineState *ms,
+ const uint64_t *hint,
+ uint64_t align, uint64_t size,
+ Error **errp)
{
uint64_t address_space_start, address_space_end;
GSList *list = NULL, *item;
@@ -120,7 +121,7 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
/* address_space_start indicates the maximum alignment we expect */
if (QEMU_ALIGN_UP(address_space_start, align) != address_space_start) {
- error_setg(errp, "the alignment (0%" PRIx64 ") is not supported",
+ error_setg(errp, "the alignment (0x%" PRIx64 ") is not supported",
align);
return 0;
}
@@ -145,11 +146,12 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
if (hint) {
new_addr = *hint;
if (new_addr < address_space_start) {
- error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
- "] at 0x%" PRIx64, new_addr, size, address_space_start);
+ error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64
+ "] before 0x%" PRIx64, new_addr, size,
+ address_space_start);
return 0;
} else if ((new_addr + size) > address_space_end) {
- error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+ error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64
"] beyond 0x%" PRIx64, new_addr, size,
address_space_end);
return 0;
@@ -166,15 +168,13 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
uint64_t md_size, md_addr;
md_addr = mdc->get_addr(md);
- md_size = mdc->get_region_size(md);
- if (*errp) {
- goto out;
- }
+ md_size = memory_device_get_region_size(md, &error_abort);
if (ranges_overlap(md_addr, md_size, new_addr, size)) {
if (hint) {
const DeviceState *d = DEVICE(md);
- error_setg(errp, "address range conflicts with '%s'", d->id);
+ error_setg(errp, "address range conflicts with memory device"
+ " id='%s'", d->id ? d->id : "(unnamed)");
goto out;
}
new_addr = QEMU_ALIGN_UP(md_addr + md_size, align);
@@ -232,7 +232,7 @@ static int memory_device_plugged_size(Object *obj, void *opaque)
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj);
if (dev->realized) {
- *size += mdc->get_plugged_size(md);
+ *size += mdc->get_plugged_size(md, &error_abort);
}
}
@@ -249,22 +249,83 @@ uint64_t get_plugged_memory_size(void)
return size;
}
-void memory_device_plug_region(MachineState *ms, MemoryRegion *mr,
- uint64_t addr)
+void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
+ const uint64_t *legacy_align, Error **errp)
+{
+ const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
+ Error *local_err = NULL;
+ uint64_t addr, align;
+ MemoryRegion *mr;
+
+ mr = mdc->get_memory_region(md, &local_err);
+ if (local_err) {
+ goto out;
+ }
+
+ align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);
+ addr = mdc->get_addr(md);
+ addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align,
+ memory_region_size(mr), &local_err);
+ if (local_err) {
+ goto out;
+ }
+ mdc->set_addr(md, addr, &local_err);
+ if (!local_err) {
+ trace_memory_device_pre_plug(DEVICE(md)->id ? DEVICE(md)->id : "",
+ addr);
+ }
+out:
+ error_propagate(errp, local_err);
+}
+
+void memory_device_plug(MemoryDeviceState *md, MachineState *ms)
{
- /* we expect a previous call to memory_device_get_free_addr() */
+ const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
+ const uint64_t addr = mdc->get_addr(md);
+ MemoryRegion *mr;
+
+ /*
+ * We expect that a previous call to memory_device_pre_plug() succeeded, so
+ * it can't fail at this point.
+ */
+ mr = mdc->get_memory_region(md, &error_abort);
g_assert(ms->device_memory);
memory_region_add_subregion(&ms->device_memory->mr,
addr - ms->device_memory->base, mr);
+ trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
}
-void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr)
+void memory_device_unplug(MemoryDeviceState *md, MachineState *ms)
{
- /* we expect a previous call to memory_device_get_free_addr() */
+ const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
+ MemoryRegion *mr;
+
+ /*
+ * We expect that a previous call to memory_device_pre_plug() succeeded, so
+ * it can't fail at this point.
+ */
+ mr = mdc->get_memory_region(md, &error_abort);
g_assert(ms->device_memory);
memory_region_del_subregion(&ms->device_memory->mr, mr);
+ trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
+ mdc->get_addr(md));
+}
+
+uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
+ Error **errp)
+{
+ const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
+ MemoryRegion *mr;
+
+ /* dropping const here is fine as we don't touch the memory region */
+ mr = mdc->get_memory_region((MemoryDeviceState *)md, errp);
+ if (!mr) {
+ return 0;
+ }
+
+ return memory_region_size(mr);
}
static const TypeInfo memory_device_info = {
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 1c6674c4ed..49324f3fae 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -27,6 +27,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/mem/nvdimm.h"
+#include "hw/mem/memory-device.h"
static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
@@ -118,9 +119,10 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp)
nvdimm->nvdimm_mr->align = align;
}
-static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
+static MemoryRegion *nvdimm_md_get_memory_region(MemoryDeviceState *md,
+ Error **errp)
{
- NVDIMMDevice *nvdimm = NVDIMM(dimm);
+ NVDIMMDevice *nvdimm = NVDIMM(md);
Error *local_err = NULL;
if (!nvdimm->nvdimm_mr) {
@@ -190,11 +192,12 @@ static Property nvdimm_properties[] = {
static void nvdimm_class_init(ObjectClass *oc, void *data)
{
PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
+ MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
NVDIMMClass *nvc = NVDIMM_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
ddc->realize = nvdimm_realize;
- ddc->get_memory_region = nvdimm_get_memory_region;
+ mdc->get_memory_region = nvdimm_md_get_memory_region;
dc->props = nvdimm_properties;
nvc->read_label_data = nvdimm_read_label_data;
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index fb6bcaedc4..0c9b9e8292 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -29,72 +29,47 @@
static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
-void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine,
+void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
const uint64_t *legacy_align, Error **errp)
{
- PCDIMMDevice *dimm = PC_DIMM(dev);
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
Error *local_err = NULL;
- MemoryRegion *mr;
- uint64_t addr, align;
int slot;
- slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
+ slot = object_property_get_int(OBJECT(dimm), PC_DIMM_SLOT_PROP,
&error_abort);
slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
machine->ram_slots, &local_err);
if (local_err) {
goto out;
}
- object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &error_abort);
+ object_property_set_int(OBJECT(dimm), slot, PC_DIMM_SLOT_PROP,
+ &error_abort);
trace_mhp_pc_dimm_assigned_slot(slot);
- mr = ddc->get_memory_region(dimm, &local_err);
- if (local_err) {
- goto out;
- }
-
- align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);
- addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
- &error_abort);
- addr = memory_device_get_free_addr(machine, !addr ? NULL : &addr, align,
- memory_region_size(mr), &local_err);
- if (local_err) {
- goto out;
- }
- trace_mhp_pc_dimm_assigned_address(addr);
- object_property_set_uint(OBJECT(dev), addr, PC_DIMM_ADDR_PROP,
- &error_abort);
+ memory_device_pre_plug(MEMORY_DEVICE(dimm), machine, legacy_align,
+ &local_err);
out:
error_propagate(errp, local_err);
}
-void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp)
+void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp)
{
- PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
&error_abort);
- MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
- uint64_t addr;
-
- addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
- &error_abort);
- memory_device_plug_region(machine, mr, addr);
- vmstate_register_ram(vmstate_mr, dev);
+ memory_device_plug(MEMORY_DEVICE(dimm), machine);
+ vmstate_register_ram(vmstate_mr, DEVICE(dimm));
}
-void pc_dimm_unplug(DeviceState *dev, MachineState *machine)
+void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
{
- PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
&error_abort);
- MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
- memory_device_unplug_region(machine, mr);
- vmstate_unregister_ram(vmstate_mr, dev);
+ memory_device_unplug(MEMORY_DEVICE(dimm), machine);
+ vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
}
static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
@@ -163,16 +138,14 @@ static Property pc_dimm_properties[] = {
static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
+ Error *local_err = NULL;
uint64_t value;
- MemoryRegion *mr;
- PCDIMMDevice *dimm = PC_DIMM(obj);
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);
- mr = ddc->get_memory_region(dimm, errp);
- if (!mr) {
+ value = memory_device_get_region_size(MEMORY_DEVICE(obj), &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
return;
}
- value = memory_region_size(mr);
visit_type_uint64(v, name, &value, errp);
}
@@ -236,19 +209,16 @@ static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md)
return dimm->addr;
}
-static uint64_t pc_dimm_md_get_region_size(const MemoryDeviceState *md)
+static void pc_dimm_md_set_addr(MemoryDeviceState *md, uint64_t addr,
+ Error **errp)
{
- /* dropping const here is fine as we don't touch the memory region */
- PCDIMMDevice *dimm = PC_DIMM(md);
- const PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(md);
- MemoryRegion *mr;
-
- mr = ddc->get_memory_region(dimm, &error_abort);
- if (!mr) {
- return 0;
- }
+ object_property_set_uint(OBJECT(md), addr, PC_DIMM_ADDR_PROP, errp);
+}
- return memory_region_size(mr);
+static MemoryRegion *pc_dimm_md_get_memory_region(MemoryDeviceState *md,
+ Error **errp)
+{
+ return pc_dimm_get_memory_region(PC_DIMM(md), errp);
}
static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,
@@ -292,13 +262,13 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data)
dc->props = pc_dimm_properties;
dc->desc = "DIMM memory module";
- ddc->get_memory_region = pc_dimm_get_memory_region;
ddc->get_vmstate_memory_region = pc_dimm_get_memory_region;
mdc->get_addr = pc_dimm_md_get_addr;
+ mdc->set_addr = pc_dimm_md_set_addr;
/* for a dimm plugged_size == region_size */
- mdc->get_plugged_size = pc_dimm_md_get_region_size;
- mdc->get_region_size = pc_dimm_md_get_region_size;
+ mdc->get_plugged_size = memory_device_get_region_size;
+ mdc->get_memory_region = pc_dimm_md_get_memory_region;
mdc->fill_device_info = pc_dimm_md_fill_device_info;
}
diff --git a/hw/mem/trace-events b/hw/mem/trace-events
index e150dcc497..0f2f278ff2 100644
--- a/hw/mem/trace-events
+++ b/hw/mem/trace-events
@@ -2,4 +2,7 @@
# hw/mem/pc-dimm.c
mhp_pc_dimm_assigned_slot(int slot) "%d"
-mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
+# hw/mem/memory-device.c
+memory_device_pre_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
+memory_device_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
+memory_device_unplug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 24ad0ad024..1cd8aac658 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -992,9 +992,9 @@ static void gt64120_pci_set_irq(void *opaque, int irq_num, int level)
}
-static void gt64120_reset(void *opaque)
+static void gt64120_reset(DeviceState *dev)
{
- GT64120State *s = opaque;
+ GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
/* FIXME: Malta specific hw assumptions ahead */
@@ -1184,16 +1184,6 @@ PCIBus *gt64120_register(qemu_irq *pic)
return phb->bus;
}
-static int gt64120_init(SysBusDevice *dev)
-{
- GT64120State *s;
-
- s = GT64120_PCI_HOST_BRIDGE(dev);
-
- qemu_register_reset(gt64120_reset, s);
- return 0;
-}
-
static void gt64120_pci_realize(PCIDevice *d, Error **errp)
{
/* FIXME: Malta specific hw assumptions ahead */
@@ -1241,9 +1231,9 @@ static const TypeInfo gt64120_pci_info = {
static void gt64120_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
- sdc->init = gt64120_init;
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+ dc->reset = gt64120_reset;
dc->vmsd = &vmstate_gt64120;
}
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 29b90bacf3..c1cf0fe12e 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1422,23 +1422,10 @@ void mips_malta_init(MachineState *machine)
pci_vga_init(pci_bus);
}
-static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
-{
- return 0;
-}
-
-static void mips_malta_class_init(ObjectClass *klass, void *data)
-{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
- k->init = mips_malta_sysbus_device_init;
-}
-
static const TypeInfo mips_malta_device = {
.name = TYPE_MIPS_MALTA,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MaltaState),
- .class_init = mips_malta_class_init,
};
static void mips_malta_machine_init(MachineClass *mc)
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 8cb17b9dd4..f88910e55c 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -1288,8 +1288,8 @@ static void ivshmem_realize(PCIDevice *dev, Error **errp)
IVShmemState *s = IVSHMEM_COMMON(dev);
if (!qtest_enabled()) {
- error_report("ivshmem is deprecated, please use ivshmem-plain"
- " or ivshmem-doorbell instead");
+ warn_report("ivshmem is deprecated, please use ivshmem-plain"
+ " or ivshmem-doorbell instead");
}
if (qemu_chr_fe_backend_connected(&s->server_chr) + !!s->shmobj != 1) {
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 1795998928..d95cc27f58 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -142,6 +142,7 @@
#define GEM_DESCONF4 (0x0000028C/4)
#define GEM_DESCONF5 (0x00000290/4)
#define GEM_DESCONF6 (0x00000294/4)
+#define GEM_DESCONF6_64B_MASK (1U << 23)
#define GEM_DESCONF7 (0x00000298/4)
#define GEM_INT_Q1_STATUS (0x00000400 / 4)
@@ -1283,6 +1284,7 @@ static void gem_reset(DeviceState *d)
int i;
CadenceGEMState *s = CADENCE_GEM(d);
const uint8_t *a;
+ uint32_t queues_mask = 0;
DB_PRINT("\n");
@@ -1299,7 +1301,12 @@ static void gem_reset(DeviceState *d)
s->regs[GEM_DESCONF] = 0x02500111;
s->regs[GEM_DESCONF2] = 0x2ab13fff;
s->regs[GEM_DESCONF5] = 0x002f2045;
- s->regs[GEM_DESCONF6] = 0x00000200;
+ s->regs[GEM_DESCONF6] = GEM_DESCONF6_64B_MASK;
+
+ if (s->num_priority_queues > 1) {
+ queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
+ s->regs[GEM_DESCONF6] |= queues_mask;
+ }
/* Set MAC address */
a = &s->conf.macaddr.a[0];
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index a6932432b1..36855804db 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/cris/etraxfs.h"
@@ -126,7 +127,7 @@ tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data)
}
static void
-tdk_init(struct qemu_phy *phy)
+tdk_reset(struct qemu_phy *phy)
{
phy->regs[0] = 0x3100;
/* PHY Id. */
@@ -135,9 +136,6 @@ tdk_init(struct qemu_phy *phy)
/* Autonegotiation advertisement reg. */
phy->regs[4] = 0x01E1;
phy->link = 1;
-
- phy->read = tdk_read;
- phy->write = tdk_write;
}
struct qemu_mdio
@@ -584,14 +582,35 @@ static NetClientInfo net_etraxfs_info = {
.link_status_changed = eth_set_link,
};
-static int fs_eth_init(SysBusDevice *sbd)
+static void etraxfs_eth_reset(DeviceState *dev)
+{
+ ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
+
+ memset(s->regs, 0, sizeof(s->regs));
+ memset(s->macaddr, 0, sizeof(s->macaddr));
+ s->duplex_mismatch = 0;
+
+ s->mdio_bus.mdc = 0;
+ s->mdio_bus.mdio = 0;
+ s->mdio_bus.state = 0;
+ s->mdio_bus.drive = 0;
+ s->mdio_bus.cnt = 0;
+ s->mdio_bus.addr = 0;
+ s->mdio_bus.opc = 0;
+ s->mdio_bus.req = 0;
+ s->mdio_bus.data = 0;
+
+ tdk_reset(&s->phy);
+}
+
+static void etraxfs_eth_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
if (!s->dma_out || !s->dma_in) {
- error_report("Unconnected ETRAX-FS Ethernet MAC");
- return -1;
+ error_setg(errp, "Unconnected ETRAX-FS Ethernet MAC");
+ return;
}
s->dma_out->client.push = eth_tx_push;
@@ -608,10 +627,9 @@ static int fs_eth_init(SysBusDevice *sbd)
object_get_typename(OBJECT(s)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-
- tdk_init(&s->phy);
+ s->phy.read = tdk_read;
+ s->phy.write = tdk_write;
mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
- return 0;
}
static Property etraxfs_eth_properties[] = {
@@ -625,9 +643,9 @@ static Property etraxfs_eth_properties[] = {
static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = fs_eth_init;
+ dc->realize = etraxfs_eth_realize;
+ dc->reset = etraxfs_eth_reset;
dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
dc->user_creatable = false;
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index b9032dac59..a6269d9463 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1320,9 +1320,9 @@ static NetClientInfo net_lan9118_info = {
.link_status_changed = lan9118_set_link,
};
-static int lan9118_init1(SysBusDevice *sbd)
+static void lan9118_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
lan9118_state *s = LAN9118(dev);
QEMUBH *bh;
int i;
@@ -1349,8 +1349,6 @@ static int lan9118_init1(SysBusDevice *sbd)
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
ptimer_set_freq(s->timer, 10000);
ptimer_set_limit(s->timer, 0xffff, 1);
-
- return 0;
}
static Property lan9118_properties[] = {
@@ -1362,12 +1360,11 @@ static Property lan9118_properties[] = {
static void lan9118_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = lan9118_init1;
dc->reset = lan9118_reset;
dc->props = lan9118_properties;
dc->vmsd = &vmstate_lan9118;
+ dc->realize = lan9118_realize;
}
static const TypeInfo lan9118_info = {
diff --git a/hw/net/lance.c b/hw/net/lance.c
index a08d5ac6a8..f987b2fd18 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -97,9 +97,9 @@ static const VMStateDescription vmstate_lance = {
}
};
-static int lance_init(SysBusDevice *sbd)
+static void lance_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
SysBusPCNetState *d = SYSBUS_PCNET(dev);
PCNetState *s = &d->state;
@@ -115,7 +115,6 @@ static int lance_init(SysBusDevice *sbd)
s->phys_mem_read = ledma_memory_read;
s->phys_mem_write = ledma_memory_write;
pcnet_common_init(dev, s, &net_lance_info);
- return 0;
}
static void lance_reset(DeviceState *dev)
@@ -144,9 +143,8 @@ static Property lance_properties[] = {
static void lance_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = lance_init;
+ dc->realize = lance_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->fw_name = "ethernet";
dc->reset = lance_reset;
diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c
index 3eaa19dfde..7ef1daee41 100644
--- a/hw/net/milkymist-minimac2.c
+++ b/hw/net/milkymist-minimac2.c
@@ -452,9 +452,9 @@ static NetClientInfo net_milkymist_minimac2_info = {
.receive = minimac2_rx,
};
-static int milkymist_minimac2_init(SysBusDevice *sbd)
+static void milkymist_minimac2_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev);
size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
@@ -479,8 +479,6 @@ static int milkymist_minimac2_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-
- return 0;
}
static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
@@ -521,9 +519,8 @@ static Property milkymist_minimac2_properties[] = {
static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = milkymist_minimac2_init;
+ dc->realize = milkymist_minimac2_realize;
dc->reset = milkymist_minimac2_reset;
dc->vmsd = &vmstate_milkymist_minimac2;
dc->props = milkymist_minimac2_properties;
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index 5a63df7ccb..03b3104278 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -236,9 +236,9 @@ static const MemoryRegionOps mipsnet_ioport_ops = {
.impl.max_access_size = 4,
};
-static int mipsnet_sysbus_init(SysBusDevice *sbd)
+static void mipsnet_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
MIPSnetState *s = MIPS_NET(dev);
memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s,
@@ -249,8 +249,6 @@ static int mipsnet_sysbus_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-
- return 0;
}
static void mipsnet_sysbus_reset(DeviceState *dev)
@@ -267,9 +265,8 @@ static Property mipsnet_properties[] = {
static void mipsnet_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = mipsnet_sysbus_init;
+ dc->realize = mipsnet_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "MIPS Simulator network device";
dc->reset = mipsnet_sysbus_reset;
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index d42b79c08c..d6f54f8d82 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -715,9 +715,9 @@ static const MemoryRegionOps open_eth_desc_ops = {
.write = open_eth_desc_write,
};
-static int sysbus_open_eth_init(SysBusDevice *sbd)
+static void sysbus_open_eth_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
OpenEthState *s = OPEN_ETH(dev);
memory_region_init_io(&s->reg_io, OBJECT(dev), &open_eth_reg_ops, s,
@@ -732,7 +732,6 @@ static int sysbus_open_eth_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s);
- return 0;
}
static void qdev_open_eth_reset(DeviceState *dev)
@@ -750,9 +749,8 @@ static Property open_eth_properties[] = {
static void open_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = sysbus_open_eth_init;
+ dc->realize = sysbus_open_eth_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "Opencores 10/100 Mbit Ethernet";
dc->reset = qdev_open_eth_reset;
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index d2fd2040e8..99da2d9297 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -766,9 +766,9 @@ static NetClientInfo net_smc91c111_info = {
.receive = smc91c111_receive,
};
-static int smc91c111_init1(SysBusDevice *sbd)
+static void smc91c111_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
smc91c111_state *s = SMC91C111(dev);
memory_region_init_io(&s->mmio, OBJECT(s), &smc91c111_mem_ops, s,
@@ -780,7 +780,6 @@ static int smc91c111_init1(SysBusDevice *sbd)
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
/* ??? Save/restore. */
- return 0;
}
static Property smc91c111_properties[] = {
@@ -791,9 +790,8 @@ static Property smc91c111_properties[] = {
static void smc91c111_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = smc91c111_init1;
+ dc->realize = smc91c111_realize;
dc->reset = smc91c111_reset;
dc->vmsd = &vmstate_smc91c111;
dc->props = smc91c111_properties;
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 165562d788..b3375ebb45 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -457,8 +457,10 @@ static const MemoryRegionOps stellaris_enet_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static void stellaris_enet_reset(stellaris_enet_state *s)
+static void stellaris_enet_reset(DeviceState *dev)
{
+ stellaris_enet_state *s = STELLARIS_ENET(dev);
+
s->mdv = 0x80;
s->rctl = SE_RCTL_BADCRC;
s->im = SE_INT_PHY | SE_INT_MD | SE_INT_RXER | SE_INT_FOV | SE_INT_TXEMP
@@ -473,9 +475,9 @@ static NetClientInfo net_stellaris_enet_info = {
.receive = stellaris_enet_receive,
};
-static int stellaris_enet_init(SysBusDevice *sbd)
+static void stellaris_enet_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
stellaris_enet_state *s = STELLARIS_ENET(dev);
memory_region_init_io(&s->mmio, OBJECT(s), &stellaris_enet_ops, s,
@@ -487,9 +489,6 @@ static int stellaris_enet_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-
- stellaris_enet_reset(s);
- return 0;
}
static Property stellaris_enet_properties[] = {
@@ -500,9 +499,9 @@ static Property stellaris_enet_properties[] = {
static void stellaris_enet_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = stellaris_enet_init;
+ dc->realize = stellaris_enet_realize;
+ dc->reset = stellaris_enet_reset;
dc->props = stellaris_enet_properties;
dc->vmsd = &vmstate_stellaris_enet;
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 4bdd5b8532..385b1a03e9 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2020,10 +2020,10 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
if (n->net_conf.tx && strcmp(n->net_conf.tx, "timer")
&& strcmp(n->net_conf.tx, "bh")) {
- error_report("virtio-net: "
- "Unknown option tx=%s, valid options: \"timer\" \"bh\"",
- n->net_conf.tx);
- error_report("Defaulting to \"bh\"");
+ warn_report("virtio-net: "
+ "Unknown option tx=%s, valid options: \"timer\" \"bh\"",
+ n->net_conf.tx);
+ error_printf("Defaulting to \"bh\"");
}
n->net_conf.tx_queue_size = MIN(virtio_net_max_tx_queue_size(n),
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index fa001563d3..63f5a62ebf 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -374,9 +374,9 @@ static NetClientInfo net_xgmac_enet_info = {
.receive = eth_rx,
};
-static int xgmac_enet_init(SysBusDevice *sbd)
+static void xgmac_enet_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
XgmacState *s = XGMAC(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &enet_mem_ops, s,
@@ -397,8 +397,6 @@ static int xgmac_enet_init(SysBusDevice *sbd)
(s->conf.macaddr.a[2] << 16) |
(s->conf.macaddr.a[1] << 8) |
s->conf.macaddr.a[0];
-
- return 0;
}
static Property xgmac_properties[] = {
@@ -408,10 +406,9 @@ static Property xgmac_properties[] = {
static void xgmac_enet_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- sbc->init = xgmac_enet_init;
+ dc->realize = xgmac_enet_realize;
dc->vmsd = &vmstate_xgmac;
dc->props = xgmac_properties;
}
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 9868e2eccc..9f33582706 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -595,7 +595,7 @@ static const VMStateDescription vmstate_bonito = {
}
};
-static int bonito_pcihost_initfn(SysBusDevice *dev)
+static void bonito_pcihost_realize(DeviceState *dev, Error **errp)
{
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
@@ -603,8 +603,6 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
pci_bonito_set_irq, pci_bonito_map_irq,
dev, get_system_memory(), get_system_io(),
0x28, 32, TYPE_PCI_BUS);
-
- return 0;
}
static void bonito_realize(PCIDevice *dev, Error **errp)
@@ -684,7 +682,6 @@ PCIBus *bonito_init(qemu_irq *pic)
pcihost->pic = pic;
qdev_init_nofail(dev);
- /* set the pcihost pointer before bonito_initfn is called */
d = pci_create(phb->bus, PCI_DEVFN(0, 0), TYPE_PCI_BONITO);
s = PCI_BONITO(d);
s->pcihost = pcihost;
@@ -726,9 +723,9 @@ static const TypeInfo bonito_info = {
static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = bonito_pcihost_initfn;
+ dc->realize = bonito_pcihost_realize;
}
static const TypeInfo bonito_pcihost_info = {
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 9750464bf4..ad1bcc7990 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -148,8 +148,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
chip = object_property_get_link(OBJECT(dev), "chip", &local_err);
if (!chip) {
- error_propagate(errp, local_err);
- error_prepend(errp, "required link 'chip' not found: ");
+ error_propagate_prepend(errp, local_err,
+ "required link 'chip' not found: ");
return;
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 98868d893a..c08130facb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3128,14 +3128,12 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error *local_err = NULL;
sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
- MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint64_t size, addr;
uint32_t node;
- size = memory_region_size(mr);
+ size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort);
- pc_dimm_plug(dev, MACHINE(ms), &local_err);
+ pc_dimm_plug(dimm, MACHINE(ms), &local_err);
if (local_err) {
goto out;
}
@@ -3158,7 +3156,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
out_unplug:
- pc_dimm_unplug(dev, MACHINE(ms));
+ pc_dimm_unplug(dimm, MACHINE(ms));
out:
error_propagate(errp, local_err);
}
@@ -3169,9 +3167,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
Error *local_err = NULL;
- MemoryRegion *mr;
uint64_t size;
Object *memdev;
hwaddr pagesize;
@@ -3181,11 +3177,11 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- mr = ddc->get_memory_region(dimm, errp);
- if (!mr) {
+ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
return;
}
- size = memory_region_size(mr);
if (size % SPAPR_MEMORY_BLOCK_SIZE) {
error_setg(errp, "Hotplugged memory size must be a multiple of "
@@ -3202,7 +3198,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), NULL, errp);
+ pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp);
}
struct sPAPRDIMMState {
@@ -3257,9 +3253,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
PCDIMMDevice *dimm)
{
sPAPRDRConnector *drc;
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
- MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
- uint64_t size = memory_region_size(mr);
+ uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm),
+ &error_abort);
uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
uint32_t avail_lmbs = 0;
uint64_t addr_start, addr;
@@ -3314,7 +3309,7 @@ static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
- pc_dimm_unplug(dev, MACHINE(hotplug_dev));
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
object_unparent(OBJECT(dev));
spapr_pending_dimm_unplugs_remove(spapr, ds);
}
@@ -3325,14 +3320,12 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
Error *local_err = NULL;
PCDIMMDevice *dimm = PC_DIMM(dev);
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
- MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint32_t nr_lmbs;
uint64_t size, addr_start, addr;
int i;
sPAPRDRConnector *drc;
- size = memory_region_size(mr);
+ size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index c2271e6ed4..58afa46204 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1724,16 +1724,15 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
if (smc->legacy_irq_allocation) {
irq = spapr_irq_findone(spapr, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "can't allocate LSIs: ");
+ error_propagate_prepend(errp, local_err,
+ "can't allocate LSIs: ");
return;
}
}
spapr_irq_claim(spapr, irq, true, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- error_prepend(errp, "can't allocate LSIs: ");
+ error_propagate_prepend(errp, local_err, "can't allocate LSIs: ");
return;
}
diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index 7cc606e065..0d2fd52487 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -47,12 +47,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value)
if (cpu->env.timecmp <= rtc_r) {
/* if we're setting an MTIMECMP value in the "past",
immediately raise the timer interrupt */
- riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
return;
}
/* otherwise, set up the future timer interrupt */
- riscv_set_local_interrupt(cpu, MIP_MTIP, 0);
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
diff = cpu->env.timecmp - rtc_r;
/* back to ns (note args switched in muldiv64) */
next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -67,7 +67,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value)
static void sifive_clint_timer_cb(void *opaque)
{
RISCVCPU *cpu = opaque;
- riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+ riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
}
/* CPU wants to read rtc or timecmp register */
@@ -132,7 +132,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
if (!env) {
error_report("clint: invalid timecmp hartid: %zu", hartid);
} else if ((addr & 0x3) == 0) {
- riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MSIP, value != 0);
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
} else {
error_report("clint: invalid sip write: %08x", (uint32_t)addr);
}
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index f635e6ff67..9cf9a1f986 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -142,10 +142,10 @@ static void sifive_plic_update(SiFivePLICState *plic)
int level = sifive_plic_irqs_pending(plic, addrid);
switch (mode) {
case PLICMode_M:
- riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level);
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
break;
case PLICMode_S:
- riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_SEIP, level);
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
break;
default:
break;
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 862f8ff5f7..ef07df2442 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -230,7 +230,9 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
qemu_fdt_add_subnode(fdt, "/chosen");
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ if (cmdline) {
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ }
g_free(nodename);
}
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index be5ef85e81..8a712ed490 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -156,8 +156,10 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
g_free(cells);
g_free(nodename);
- qemu_fdt_add_subnode(fdt, "/chosen");
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ if (cmdline) {
+ qemu_fdt_add_subnode(fdt, "/chosen");
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ }
}
static void spike_v1_10_0_board_init(MachineState *machine)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 005169eabc..4a137a503c 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -254,7 +254,9 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
qemu_fdt_add_subnode(fdt, "/chosen");
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ if (cmdline) {
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+ }
g_free(nodename);
return fdt;
@@ -385,6 +387,8 @@ static void riscv_virt_board_init(MachineState *machine)
serial_mm_init(system_memory, memmap[VIRT_UART0].base,
0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+ g_free(plic_hart_config);
}
static void riscv_virt_board_machine_init(MachineClass *mc)
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 95a143bfba..623d0333e8 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -284,6 +284,8 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
k->cs_polarity = SSI_CS_LOW;
dc->vmsd = &vmstate_ssi_sd;
dc->reset = ssi_sd_reset;
+ /* Reason: init() method uses drive_get_next() */
+ dc->user_creatable = false;
}
static const TypeInfo ssi_sd_info = {
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index 4ec2e35500..379d0685ed 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -120,16 +120,15 @@ static void sh_pci_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num], level);
}
-static int sh_pci_device_init(SysBusDevice *dev)
+static void sh_pci_device_realize(DeviceState *dev, Error **errp)
{
- PCIHostState *phb;
- SHPCIState *s;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ SHPCIState *s = SH_PCI_HOST_BRIDGE(dev);
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
int i;
- s = SH_PCI_HOST_BRIDGE(dev);
- phb = PCI_HOST_BRIDGE(s);
for (i = 0; i < 4; i++) {
- sysbus_init_irq(dev, &s->irq[i]);
+ sysbus_init_irq(sbd, &s->irq[i]);
}
phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
sh_pci_set_irq, sh_pci_map_irq,
@@ -143,13 +142,12 @@ static int sh_pci_device_init(SysBusDevice *dev)
&s->memconfig_p4, 0, 0x224);
memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa",
get_system_io(), 0, 0x40000);
- sysbus_init_mmio(dev, &s->memconfig_p4);
- sysbus_init_mmio(dev, &s->memconfig_a7);
+ sysbus_init_mmio(sbd, &s->memconfig_p4);
+ sysbus_init_mmio(sbd, &s->memconfig_a7);
s->iobr = 0xfe240000;
memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
- return 0;
}
static void sh_pci_host_realize(PCIDevice *d, Error **errp)
@@ -187,9 +185,9 @@ static const TypeInfo sh_pci_host_info = {
static void sh_pci_device_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- sdc->init = sh_pci_device_init;
+ dc->realize = sh_pci_device_realize;
}
static const TypeInfo sh_pci_device_info = {
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index a27e54b2fa..920939454e 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -950,6 +950,7 @@ static void save_opt_list(size_t *ndest, const char ***dest,
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
+ Error *err = NULL;
const char *val;
assert(!smbios_immutable);
@@ -960,12 +961,16 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
int size;
struct smbios_table *table; /* legacy mode only */
- qemu_opts_validate(opts, qemu_smbios_file_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_file_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
size = get_image_size(val);
if (size == -1 || size < sizeof(struct smbios_structure_header)) {
- error_report("Cannot read SMBIOS file %s", val);
- exit(1);
+ error_setg(errp, "Cannot read SMBIOS file %s", val);
+ return;
}
/*
@@ -978,14 +983,15 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
smbios_tables_len);
if (load_image(val, (uint8_t *)header) != size) {
- error_report("Failed to load SMBIOS file %s", val);
- exit(1);
+ error_setg(errp, "Failed to load SMBIOS file %s", val);
+ return;
}
if (test_bit(header->type, have_fields_bitmap)) {
- error_report("can't load type %d struct, fields already specified!",
- header->type);
- exit(1);
+ error_setg(errp,
+ "can't load type %d struct, fields already specified!",
+ header->type);
+ return;
}
set_bit(header->type, have_binfile_bitmap);
@@ -1030,19 +1036,23 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
unsigned long type = strtoul(val, NULL, 0);
if (type > SMBIOS_MAX_TYPE) {
- error_report("out of range!");
- exit(1);
+ error_setg(errp, "out of range!");
+ return;
}
if (test_bit(type, have_binfile_bitmap)) {
- error_report("can't add fields, binary file already loaded!");
- exit(1);
+ error_setg(errp, "can't add fields, binary file already loaded!");
+ return;
}
set_bit(type, have_fields_bitmap);
switch (type) {
case 0:
- qemu_opts_validate(opts, qemu_smbios_type0_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type0_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type0.vendor, opts, "vendor");
save_opt(&type0.version, opts, "version");
save_opt(&type0.date, opts, "date");
@@ -1051,14 +1061,18 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
val = qemu_opt_get(opts, "release");
if (val) {
if (sscanf(val, "%hhu.%hhu", &type0.major, &type0.minor) != 2) {
- error_report("Invalid release");
- exit(1);
+ error_setg(errp, "Invalid release");
+ return;
}
type0.have_major_minor = true;
}
return;
case 1:
- qemu_opts_validate(opts, qemu_smbios_type1_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type1_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type1.manufacturer, opts, "manufacturer");
save_opt(&type1.product, opts, "product");
save_opt(&type1.version, opts, "version");
@@ -1069,14 +1083,18 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
val = qemu_opt_get(opts, "uuid");
if (val) {
if (qemu_uuid_parse(val, &qemu_uuid) != 0) {
- error_report("Invalid UUID");
- exit(1);
+ error_setg(errp, "Invalid UUID");
+ return;
}
qemu_uuid_set = true;
}
return;
case 2:
- qemu_opts_validate(opts, qemu_smbios_type2_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type2_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type2.manufacturer, opts, "manufacturer");
save_opt(&type2.product, opts, "product");
save_opt(&type2.version, opts, "version");
@@ -1085,7 +1103,11 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type2.location, opts, "location");
return;
case 3:
- qemu_opts_validate(opts, qemu_smbios_type3_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type3_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type3.manufacturer, opts, "manufacturer");
save_opt(&type3.version, opts, "version");
save_opt(&type3.serial, opts, "serial");
@@ -1093,7 +1115,11 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type3.sku, opts, "sku");
return;
case 4:
- qemu_opts_validate(opts, qemu_smbios_type4_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type4_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type4.sock_pfx, opts, "sock_pfx");
save_opt(&type4.manufacturer, opts, "manufacturer");
save_opt(&type4.version, opts, "version");
@@ -1102,11 +1128,19 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type4.part, opts, "part");
return;
case 11:
- qemu_opts_validate(opts, qemu_smbios_type11_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type11_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt_list(&type11.nvalues, &type11.values, opts, "value");
return;
case 17:
- qemu_opts_validate(opts, qemu_smbios_type17_opts, &error_fatal);
+ qemu_opts_validate(opts, qemu_smbios_type17_opts, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
save_opt(&type17.loc_pfx, opts, "loc_pfx");
save_opt(&type17.bank, opts, "bank");
save_opt(&type17.manufacturer, opts, "manufacturer");
@@ -1116,12 +1150,12 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
type17.speed = qemu_opt_get_number(opts, "speed", 0);
return;
default:
- error_report("Don't know how to build fields for SMBIOS type %ld",
- type);
- exit(1);
+ error_setg(errp,
+ "Don't know how to build fields for SMBIOS type %ld",
+ type);
+ return;
}
}
- error_report("Must specify type= or file=");
- exit(1);
+ error_setg(errp, "Must specify type= or file=");
}
diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
index 4fa8cb2904..f8a856f611 100644
--- a/hw/sparc64/niagara.c
+++ b/hw/sparc64/niagara.c
@@ -29,7 +29,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/char/serial.h"
-#include "hw/empty_slot.h"
+#include "hw/misc/unimp.h"
#include "hw/loader.h"
#include "hw/sparc/sparc64.h"
#include "hw/timer/sun4v-rtc.h"
@@ -161,7 +161,7 @@ static void niagara_init(MachineState *machine)
serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200,
serial_hd(0), DEVICE_BIG_ENDIAN);
}
- empty_slot_init(NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
+ create_unimplemented_device("sun4v-iob", NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
sun4v_rtc_init(NIAGARA_RTC_BASE);
}
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index 83585bc8b2..3dae303d5b 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -319,9 +319,9 @@ static const MemoryRegionOps spi_ops = {
}
};
-static int xilinx_spi_init(SysBusDevice *sbd)
+static void xilinx_spi_realize(DeviceState *dev, Error **errp)
{
- DeviceState *dev = DEVICE(sbd);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
XilinxSPI *s = XILINX_SPI(dev);
int i;
@@ -344,8 +344,6 @@ static int xilinx_spi_init(SysBusDevice *sbd)
fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
-
- return 0;
}
static const VMStateDescription vmstate_xilinx_spi = {
@@ -368,9 +366,8 @@ static Property xilinx_spi_properties[] = {
static void xilinx_spi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = xilinx_spi_init;
+ dc->realize = xilinx_spi_realize;
dc->reset = xlx_spi_reset;
dc->props = xilinx_spi_properties;
dc->vmsd = &vmstate_xilinx_spi;
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 54b400b94a..5c786e5128 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -454,8 +454,7 @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
obj = object_property_get_link(OBJECT(dev), "scu", &err);
if (!obj) {
- error_propagate(errp, err);
- error_prepend(errp, "required link 'scu' not found: ");
+ error_propagate_prepend(errp, err, "required link 'scu' not found: ");
return;
}
s->scu = ASPEED_SCU(obj);
diff --git a/hw/timer/sun4v-rtc.c b/hw/timer/sun4v-rtc.c
index 310523225f..4e7f6a1eff 100644
--- a/hw/timer/sun4v-rtc.c
+++ b/hw/timer/sun4v-rtc.c
@@ -14,15 +14,8 @@
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/timer/sun4v-rtc.h"
+#include "trace.h"
-//#define DEBUG_SUN4V_RTC
-
-#ifdef DEBUG_SUN4V_RTC
-#define DPRINTF(fmt, ...) \
- do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
#define TYPE_SUN4V_RTC "sun4v_rtc"
#define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC)
@@ -41,14 +34,14 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
/* accessing the high 32 bits */
val >>= 32;
}
- DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val);
+ trace_sun4v_rtc_read(addr, val);
return val;
}
static void sun4v_rtc_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr);
+ trace_sun4v_rtc_read(addr, val);
}
static const MemoryRegionOps sun4v_rtc_ops = {
@@ -70,21 +63,21 @@ void sun4v_rtc_init(hwaddr addr)
sysbus_mmio_map(s, 0, addr);
}
-static int sun4v_rtc_init1(SysBusDevice *dev)
+static void sun4v_rtc_realize(DeviceState *dev, Error **errp)
{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Sun4vRtc *s = SUN4V_RTC(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s,
"sun4v-rtc", 0x08ULL);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
+ sysbus_init_mmio(sbd, &s->iomem);
}
static void sun4v_rtc_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = sun4v_rtc_init1;
+ dc->realize = sun4v_rtc_realize;
}
static const TypeInfo sun4v_rtc_info = {
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index fa4213df5b..75bd3b1042 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -56,7 +56,7 @@ systick_timer_tick(void) "systick reload"
systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
-# hw/char/cmsdk_apb_timer.c
+# hw/timer/cmsdk_apb_timer.c
cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
@@ -66,5 +66,9 @@ cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK A
cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
+# hw/timer/sun4v-rtc.c
+sun4v_rtc_read(uint64_t addr, uint64_t value) "read: addr 0x%" PRIx64 " value 0x%" PRIx64
+sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value 0x%" PRIx64
+
# hw/timer/xlnx-zynqmp-rtc.c
xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 11f7720d71..bf796d67e6 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -340,8 +340,9 @@ static USBDevice *usb_try_create_simple(USBBus *bus, const char *name,
}
object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (err) {
- error_propagate(errp, err);
- error_prepend(errp, "Failed to initialize USB device '%s': ", name);
+ error_propagate_prepend(errp, err,
+ "Failed to initialize USB device '%s': ",
+ name);
return NULL;
}
return dev;
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index 481fd08df7..eae31c74d6 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1670,7 +1670,7 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
* but also no point in us enabling VGA if disabled in hardware.
*/
if (!(gmch & 0x2) && !vdev->vga && vfio_populate_vga(vdev, &err)) {
- error_reportf_err(err, ERR_PREFIX, vdev->vbasedev.name);
+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
error_report("IGD device %s failed to enable VGA access, "
"legacy mode disabled", vdev->vbasedev.name);
goto out;
@@ -1696,7 +1696,7 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
ret = vfio_pci_igd_opregion_init(vdev, opregion, &err);
if (ret) {
error_append_hint(&err, "IGD legacy mode disabled\n");
- error_reportf_err(err, ERR_PREFIX, vdev->vbasedev.name);
+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
goto out;
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 8b73582d51..5c7bd96984 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -252,7 +252,7 @@ static void vfio_intx_update(PCIDevice *pdev)
vfio_intx_enable_kvm(vdev, &err);
if (err) {
- error_reportf_err(err, WARN_PREFIX, vdev->vbasedev.name);
+ warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
/* Re-enable the interrupt in cased we missed an EOI */
@@ -317,7 +317,7 @@ static int vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp)
vfio_intx_enable_kvm(vdev, &err);
if (err) {
- error_reportf_err(err, WARN_PREFIX, vdev->vbasedev.name);
+ warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
vdev->interrupt = VFIO_INT_INTx;
@@ -745,7 +745,7 @@ static void vfio_msi_disable_common(VFIOPCIDevice *vdev)
vfio_intx_enable(vdev, &err);
if (err) {
- error_reportf_err(err, ERR_PREFIX, vdev->vbasedev.name);
+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
}
@@ -1283,8 +1283,7 @@ static int vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
if (ret == -ENOTSUP) {
return 0;
}
- error_prepend(&err, "msi_init failed: ");
- error_propagate(errp, err);
+ error_propagate_prepend(errp, err, "msi_init failed: ");
return ret;
}
vdev->msi_cap_size = 0xa + (msi_maskbit ? 0xa : 0) + (msi_64bit ? 0x4 : 0);
@@ -1558,7 +1557,7 @@ static int vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp)
&err);
if (ret < 0) {
if (ret == -ENOTSUP) {
- error_report_err(err);
+ warn_report_err(err);
return 0;
}
@@ -2197,7 +2196,7 @@ static void vfio_pci_post_reset(VFIOPCIDevice *vdev)
vfio_intx_enable(vdev, &err);
if (err) {
- error_reportf_err(err, ERR_PREFIX, vdev->vbasedev.name);
+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
for (nr = 0; nr < PCI_NUM_REGIONS - 1; ++nr) {
@@ -2591,9 +2590,9 @@ static void vfio_populate_device(VFIOPCIDevice *vdev, Error **errp)
} else if (irq_info.count == 1) {
vdev->pci_aer = true;
} else {
- error_report(WARN_PREFIX
- "Could not enable error recovery for the device",
- vbasedev->name);
+ warn_report(VFIO_MSG_PREFIX
+ "Could not enable error recovery for the device",
+ vbasedev->name);
}
}
@@ -2718,7 +2717,7 @@ static void vfio_req_notifier_handler(void *opaque)
qdev_unplug(&vdev->pdev.qdev, &err);
if (err) {
- error_reportf_err(err, WARN_PREFIX, vdev->vbasedev.name);
+ warn_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
}
@@ -2831,7 +2830,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
if (stat(vdev->vbasedev.sysfsdev, &st) < 0) {
error_setg_errno(errp, errno, "no such host device");
- error_prepend(errp, ERR_PREFIX, vdev->vbasedev.sysfsdev);
+ error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.sysfsdev);
return;
}
@@ -3086,7 +3085,7 @@ out_teardown:
vfio_teardown_msi(vdev);
vfio_bars_exit(vdev);
error:
- error_prepend(errp, ERR_PREFIX, vdev->vbasedev.name);
+ error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
}
static void vfio_instance_finalize(Object *obj)
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index 64c1af653d..398db38f14 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -679,8 +679,8 @@ static void vfio_platform_realize(DeviceState *dev, Error **errp)
for (i = 0; i < vbasedev->num_regions; i++) {
if (vfio_region_mmap(vdev->regions[i])) {
- error_report("%s mmap unsupported. Performance may be slow",
- memory_region_name(vdev->regions[i]->mem));
+ warn_report("%s mmap unsupported, performance may be slow",
+ memory_region_name(vdev->regions[i]->mem));
}
sysbus_init_mmio(sbdev, vdev->regions[i]->mem);
}
@@ -690,7 +690,7 @@ out:
}
if (vdev->vbasedev.name) {
- error_prepend(errp, ERR_PREFIX, vdev->vbasedev.name);
+ error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name);
} else {
error_prepend(errp, "vfio error: ");
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 3a01fe90f0..a954799267 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1683,8 +1683,8 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
if (err) {
/* Notice when a system that supports MSIx can't initialize it */
if (err != -ENOTSUP) {
- error_report("unable to init msix vectors to %" PRIu32,
- proxy->nvectors);
+ warn_report("unable to init msix vectors to %" PRIu32,
+ proxy->nvectors);
}
proxy->nvectors = 0;
}
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index e5a6eff44f..f1f3a3727c 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -830,7 +830,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
xen_pt_config_init(s, &err);
if (err) {
error_append_hint(&err, "PCI Config space initialisation failed");
- error_report_err(err);
+ error_propagate(errp, err);
rc = -1;
goto err_out;
}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 1f69a6e9d3..41b61c85f9 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_nanomips (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/include/exec/poison.h b/include/exec/poison.h
index 97d3b56640..32d53789f8 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -75,6 +75,7 @@
#pragma GCC poison CONFIG_M68K_DIS
#pragma GCC poison CONFIG_MICROBLAZE_DIS
#pragma GCC poison CONFIG_MIPS_DIS
+#pragma GCC poison CONFIG_NANOMIPS_DIS
#pragma GCC poison CONFIG_MOXIE_DIS
#pragma GCC poison CONFIG_NIOS2_DIS
#pragma GCC poison CONFIG_PPC_DIS
diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h
index 2853b084b5..e904e194d5 100644
--- a/include/hw/mem/memory-device.h
+++ b/include/hw/mem/memory-device.h
@@ -29,23 +29,81 @@ typedef struct MemoryDeviceState {
Object parent_obj;
} MemoryDeviceState;
+/**
+ * MemoryDeviceClass:
+ *
+ * All memory devices need to implement TYPE_MEMORY_DEVICE as an interface.
+ *
+ * A memory device is a device that owns a memory region which is
+ * mapped into guest physical address space at a certain address. The
+ * address in guest physical memory can either be specified explicitly
+ * or get assigned automatically.
+ *
+ * Conceptually, memory devices only span one memory region. If multiple
+ * successive memory regions are used, a covering memory region has to
+ * be provided. Scattered memory regions are not supported for single
+ * devices.
+ */
typedef struct MemoryDeviceClass {
+ /* private */
InterfaceClass parent_class;
+ /*
+ * Return the address of the memory device in guest physical memory.
+ *
+ * Called when (un)plugging a memory device or when iterating over
+ * all memory devices mapped into guest physical address space.
+ *
+ * If "0" is returned, no address has been specified by the user and
+ * no address has been assigned to this memory device yet.
+ */
uint64_t (*get_addr)(const MemoryDeviceState *md);
- uint64_t (*get_plugged_size)(const MemoryDeviceState *md);
- uint64_t (*get_region_size)(const MemoryDeviceState *md);
+
+ /*
+ * Set the address of the memory device in guest physical memory.
+ *
+ * Called when plugging the memory device to configure the determined
+ * address in guest physical memory.
+ */
+ void (*set_addr)(MemoryDeviceState *md, uint64_t addr, Error **errp);
+
+ /*
+ * Return the amount of memory provided by the memory device currently
+ * usable ("plugged") by the VM.
+ *
+ * Called when calculating the total amount of ram available to the
+ * VM (e.g. to report memory stats to the user).
+ *
+ * This is helpful for devices that dynamically manage the amount of
+ * memory accessible by the guest via the reserved memory region. For
+ * most devices, this corresponds to the size of the memory region.
+ */
+ uint64_t (*get_plugged_size)(const MemoryDeviceState *md, Error **errp);
+
+ /*
+ * Return the memory region of the memory device.
+ *
+ * Called when (un)plugging the memory device, to (un)map the
+ * memory region in guest physical memory, but also to detect the
+ * required alignment during address assignment or when the size of the
+ * memory region is required.
+ */
+ MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
+
+ /*
+ * Translate the memory device into #MemoryDeviceInfo.
+ */
void (*fill_device_info)(const MemoryDeviceState *md,
MemoryDeviceInfo *info);
} MemoryDeviceClass;
MemoryDeviceInfoList *qmp_memory_device_list(void);
uint64_t get_plugged_memory_size(void);
-uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
- uint64_t align, uint64_t size,
- Error **errp);
-void memory_device_plug_region(MachineState *ms, MemoryRegion *mr,
- uint64_t addr);
-void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr);
+void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
+ const uint64_t *legacy_align, Error **errp);
+void memory_device_plug(MemoryDeviceState *md, MachineState *ms);
+void memory_device_unplug(MemoryDeviceState *md, MachineState *ms);
+uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
+ Error **errp);
#endif
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index b382eb4303..01436b9f50 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -61,9 +61,6 @@ typedef struct PCDIMMDevice {
* PCDIMMDeviceClass:
* @realize: called after common dimm is realized so that the dimm based
* devices get the chance to do specified operations.
- * @get_memory_region: returns #MemoryRegion associated with @dimm which
- * is directly mapped into the physical address space of guest. Will not
- * fail after the device was realized.
* @get_vmstate_memory_region: returns #MemoryRegion which indicates the
* memory of @dimm should be kept during live migration. Will not fail
* after the device was realized.
@@ -74,13 +71,12 @@ typedef struct PCDIMMDeviceClass {
/* public */
void (*realize)(PCDIMMDevice *dimm, Error **errp);
- MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm, Error **errp);
MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm,
Error **errp);
} PCDIMMDeviceClass;
-void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine,
+void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
const uint64_t *legacy_align, Error **errp);
-void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp);
-void pc_dimm_unplug(DeviceState *dev, MachineState *machine);
+void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp);
+void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine);
#endif
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index e46a28910a..1b434d02f6 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -31,8 +31,7 @@
#include <linux/vfio.h>
#endif
-#define ERR_PREFIX "vfio error: %s: "
-#define WARN_PREFIX "vfio warning: %s: "
+#define VFIO_MSG_PREFIX "vfio %s: "
enum {
VFIO_DEVICE_TYPE_PCI = 0,
diff --git a/include/qapi/error.h b/include/qapi/error.h
index bcb86a79f5..51b63dd4b5 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -52,8 +52,12 @@
* where Error **errp is a parameter, by convention the last one.
*
* Pass an existing error to the caller with the message modified:
+ * error_propagate_prepend(errp, err);
+ *
+ * Avoid
* error_propagate(errp, err);
* error_prepend(errp, "Could not frobnicate '%s': ", name);
+ * because this fails to prepend when @errp is &error_fatal.
*
* Create a new error and pass it to the caller:
* error_setg(errp, "situation normal, all fouled up");
@@ -215,6 +219,16 @@ void error_setg_win32_internal(Error **errp,
*/
void error_propagate(Error **dst_errp, Error *local_err);
+
+/*
+ * Propagate error object (if any) with some text prepended.
+ * Behaves like
+ * error_prepend(&local_err, fmt, ...);
+ * error_propagate(dst_errp, local_err);
+ */
+void error_propagate_prepend(Error **dst_errp, Error *local_err,
+ const char *fmt, ...);
+
/*
* Prepend some text to @errp's human-readable error message.
* The text is made by formatting @fmt, @ap like vprintf().
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 145571f618..7c76e24aa7 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -79,6 +79,9 @@
#define QERR_QGA_COMMAND_FAILED \
"Guest agent command failed, error was '%s'"
+#define QERR_REPLAY_NOT_SUPPORTED \
+ "Record/replay feature is not supported for '%s'"
+
#define QERR_SET_PASSWD_FAILED \
"Could not set password"
@@ -88,7 +91,4 @@
#define QERR_UNSUPPORTED \
"this feature or command is not currently supported"
-#define QERR_REPLAY_NOT_SUPPORTED \
- "Record/replay feature is not supported for '%s'"
-
#endif /* QERROR_H */
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 4f8559e550..3bf48bcdec 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -123,6 +123,18 @@ extern int daemon(int, int);
#include "qemu/typedefs.h"
/*
+ * For mingw, as of v6.0.0, the function implementing the assert macro is
+ * not marked as noreturn, so the compiler cannot delete code following an
+ * assert(false) as unused. We rely on this within the code base to delete
+ * code that is unreachable when features are disabled.
+ * All supported versions of Glib's g_assert() satisfy this requirement.
+ */
+#ifdef __MINGW32__
+#undef assert
+#define assert(x) g_assert(x)
+#endif
+
+/*
* According to waitpid man page:
* WCOREDUMP
* This macro is not specified in POSIX.1-2001 and is not
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 24954b94e0..d34c4920dc 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -54,7 +54,8 @@ DriveInfo *drive_get_next(BlockInterfaceType type);
QemuOpts *drive_def(const char *optstr);
QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
const char *optstr);
-DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
+DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
+ Error **errp);
/* device-hotplug */
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 7a0ae751aa..21713b7e2f 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -22,7 +22,6 @@ struct NumaNodeMem {
};
extern NodeInfo numa_info[MAX_NODES];
-int parse_numa(void *opaque, QemuOpts *opts, Error **errp);
void parse_numa_opts(MachineState *ms);
void numa_complete_configuration(MachineState *ms);
void query_numa_node_mem(NumaNodeMem node_mem[]);
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 9ae1ab6da3..17a97ed77a 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -16,7 +16,7 @@
#include "qom/object.h"
int tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
-int tpm_init(void);
+void tpm_init(void);
void tpm_cleanup(void);
typedef enum TPMVersion {
diff --git a/include/ui/console.h b/include/ui/console.h
index fb969caf70..c17803c530 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -453,7 +453,7 @@ void qemu_display_early_init(DisplayOptions *opts);
void qemu_display_init(DisplayState *ds, DisplayOptions *opts);
/* vnc.c */
-void vnc_display_init(const char *id);
+void vnc_display_init(const char *id, Error **errp);
void vnc_display_open(const char *id, Error **errp);
void vnc_display_add_client(const char *id, int csock, bool skipauth);
int vnc_display_password(const char *id, const char *password);
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 07fedfc33c..f84a9cf28a 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -314,7 +314,7 @@ static int target_restore_sigframe(CPUARMState *env,
break;
case TARGET_SVE_MAGIC:
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
if (!sve && size == sve_size) {
@@ -433,7 +433,7 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
&layout);
/* SVE state needs saving only if it exists. */
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(env))) {
vq = (env->vfp.zcr_el[1] & 0xf) + 1;
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
sve_ofs = alloc_sigframe_space(sve_size, &layout);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 10bca65b99..055f6a95ab 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -458,6 +458,10 @@ static uint32_t get_elf_hwcap(void)
/* probe for the extra features */
#define GET_FEATURE(feat, hwcap) \
do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+
+#define GET_FEATURE_ID(feat, hwcap) \
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
/* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
@@ -467,8 +471,8 @@ static uint32_t get_elf_hwcap(void)
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
- GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
- GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
+ GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
+ GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
/* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
* Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
* ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
@@ -485,15 +489,16 @@ static uint32_t get_elf_hwcap2(void)
ARMCPU *cpu = ARM_CPU(thread_cpu);
uint32_t hwcaps = 0;
- GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES);
- GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP2_ARM_PMULL);
- GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP2_ARM_SHA1);
- GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP2_ARM_SHA2);
- GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32);
+ GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
+ GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
+ GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
+ GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
+ GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
return hwcaps;
}
#undef GET_FEATURE
+#undef GET_FEATURE_ID
#else
/* 64 bit ARM definitions */
@@ -568,25 +573,26 @@ static uint32_t get_elf_hwcap(void)
hwcaps |= ARM_HWCAP_A64_ASIMD;
/* probe for the extra features */
-#define GET_FEATURE(feat, hwcap) \
- do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
- GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_AES);
- GET_FEATURE(ARM_FEATURE_V8_PMULL, ARM_HWCAP_A64_PMULL);
- GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1);
- GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2);
- GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32);
- GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3);
- GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
- GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
- GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
- GET_FEATURE(ARM_FEATURE_V8_FP16,
- ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
- GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
- GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
- GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
- GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
- GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
-#undef GET_FEATURE
+#define GET_FEATURE_ID(feat, hwcap) \
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
+ GET_FEATURE_ID(aa64_aes, ARM_HWCAP_A64_AES);
+ GET_FEATURE_ID(aa64_pmull, ARM_HWCAP_A64_PMULL);
+ GET_FEATURE_ID(aa64_sha1, ARM_HWCAP_A64_SHA1);
+ GET_FEATURE_ID(aa64_sha256, ARM_HWCAP_A64_SHA2);
+ GET_FEATURE_ID(aa64_sha512, ARM_HWCAP_A64_SHA512);
+ GET_FEATURE_ID(aa64_crc32, ARM_HWCAP_A64_CRC32);
+ GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
+ GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
+ GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
+ GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
+ GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
+ GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
+ GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
+ GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
+ GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
+
+#undef GET_FEATURE_ID
return hwcaps;
}
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 586c794639..ae8951625f 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -131,6 +131,52 @@
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT))
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT))
+#ifdef CONFIG_USBFS
+ /* USB ioctls */
+ IOCTL(USBDEVFS_CONTROL, IOC_RW,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ctrltransfer)))
+ IOCTL(USBDEVFS_BULK, IOC_RW,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_bulktransfer)))
+ IOCTL(USBDEVFS_RESETEP, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_SETINTERFACE, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_setinterface)))
+ IOCTL(USBDEVFS_SETCONFIGURATION, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_GETDRIVER, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_getdriver)))
+ IOCTL_SPECIAL(USBDEVFS_SUBMITURB, IOC_W, do_ioctl_usbdevfs_submiturb,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb)))
+ IOCTL_SPECIAL(USBDEVFS_DISCARDURB, IOC_RW, do_ioctl_usbdevfs_discardurb,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_urb)))
+ IOCTL_SPECIAL(USBDEVFS_REAPURB, IOC_R, do_ioctl_usbdevfs_reapurb,
+ MK_PTR(TYPE_PTRVOID))
+ IOCTL_SPECIAL(USBDEVFS_REAPURBNDELAY, IOC_R, do_ioctl_usbdevfs_reapurb,
+ MK_PTR(TYPE_PTRVOID))
+ IOCTL(USBDEVFS_DISCSIGNAL, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnectsignal)))
+ IOCTL(USBDEVFS_CLAIMINTERFACE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_RELEASEINTERFACE, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_CONNECTINFO, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_connectinfo)))
+ IOCTL(USBDEVFS_IOCTL, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_usbdevfs_ioctl)))
+ IOCTL(USBDEVFS_HUB_PORTINFO, IOC_R,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_hub_portinfo)))
+ IOCTL(USBDEVFS_RESET, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CLEAR_HALT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_DISCONNECT, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CONNECT, 0, TYPE_NULL)
+ IOCTL(USBDEVFS_CLAIM_PORT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_RELEASE_PORT, IOC_W, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_GET_CAPABILITIES, IOC_R, MK_PTR(TYPE_INT))
+ IOCTL(USBDEVFS_DISCONNECT_CLAIM, IOC_W,
+ MK_PTR(MK_STRUCT(STRUCT_usbdevfs_disconnect_claim)))
+#ifdef USBDEVFS_DROP_PRIVILEGES
+ IOCTL(USBDEVFS_DROP_PRIVILEGES, IOC_W, MK_PTR(TYPE_INT))
+#endif
+#ifdef USBDEVFS_GET_SPEED
+ IOCTL(USBDEVFS_GET_SPEED, 0, TYPE_NULL)
+#endif
+#endif /* CONFIG_USBFS */
+
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFFLAGS, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_short_ifreq)))
diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h
index fa5d30bf99..a98c9bd6ad 100644
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
return "mips32r6-generic";
}
+ if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
+ return "R5900";
+ }
return "24Kf";
}
#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d2cc971143..15b03e17b9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -94,6 +94,10 @@
#include <linux/fiemap.h>
#endif
#include <linux/fb.h>
+#if defined(CONFIG_USBFS)
+#include <linux/usbdevice_fs.h>
+#include <linux/usb/ch9.h>
+#endif
#include <linux/vt.h>
#include <linux/dm-ioctl.h>
#include <linux/reboot.h>
@@ -4196,6 +4200,182 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
return ret;
}
+#if defined(CONFIG_USBFS)
+#if HOST_LONG_BITS > 64
+#error USBDEVFS thunks do not support >64 bit hosts yet.
+#endif
+struct live_urb {
+ uint64_t target_urb_adr;
+ uint64_t target_buf_adr;
+ char *target_buf_ptr;
+ struct usbdevfs_urb host_urb;
+};
+
+static GHashTable *usbdevfs_urb_hashtable(void)
+{
+ static GHashTable *urb_hashtable;
+
+ if (!urb_hashtable) {
+ urb_hashtable = g_hash_table_new(g_int64_hash, g_int64_equal);
+ }
+ return urb_hashtable;
+}
+
+static void urb_hashtable_insert(struct live_urb *urb)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ g_hash_table_insert(urb_hashtable, urb, urb);
+}
+
+static struct live_urb *urb_hashtable_lookup(uint64_t target_urb_adr)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ return g_hash_table_lookup(urb_hashtable, &target_urb_adr);
+}
+
+static void urb_hashtable_remove(struct live_urb *urb)
+{
+ GHashTable *urb_hashtable = usbdevfs_urb_hashtable();
+ g_hash_table_remove(urb_hashtable, urb);
+}
+
+static abi_long
+do_ioctl_usbdevfs_reapurb(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ const argtype usbfsurb_arg_type[] = { MK_STRUCT(STRUCT_usbdevfs_urb) };
+ const argtype ptrvoid_arg_type[] = { TYPE_PTRVOID, 0, 0 };
+ struct live_urb *lurb;
+ void *argptr;
+ uint64_t hurb;
+ int target_size;
+ uintptr_t target_urb_adr;
+ abi_long ret;
+
+ target_size = thunk_type_size(usbfsurb_arg_type, THUNK_TARGET);
+
+ memset(buf_temp, 0, sizeof(uint64_t));
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
+ if (is_error(ret)) {
+ return ret;
+ }
+
+ memcpy(&hurb, buf_temp, sizeof(uint64_t));
+ lurb = (void *)((uintptr_t)hurb - offsetof(struct live_urb, host_urb));
+ if (!lurb->target_urb_adr) {
+ return -TARGET_EFAULT;
+ }
+ urb_hashtable_remove(lurb);
+ unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr,
+ lurb->host_urb.buffer_length);
+ lurb->target_buf_ptr = NULL;
+
+ /* restore the guest buffer pointer */
+ lurb->host_urb.buffer = (void *)(uintptr_t)lurb->target_buf_adr;
+
+ /* update the guest urb struct */
+ argptr = lock_user(VERIFY_WRITE, lurb->target_urb_adr, target_size, 0);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(argptr, &lurb->host_urb, usbfsurb_arg_type, THUNK_TARGET);
+ unlock_user(argptr, lurb->target_urb_adr, target_size);
+
+ target_size = thunk_type_size(ptrvoid_arg_type, THUNK_TARGET);
+ /* write back the urb handle */
+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+
+ /* GHashTable uses 64-bit keys but thunk_convert expects uintptr_t */
+ target_urb_adr = lurb->target_urb_adr;
+ thunk_convert(argptr, &target_urb_adr, ptrvoid_arg_type, THUNK_TARGET);
+ unlock_user(argptr, arg, target_size);
+
+ g_free(lurb);
+ return ret;
+}
+
+static abi_long
+do_ioctl_usbdevfs_discardurb(const IOCTLEntry *ie,
+ uint8_t *buf_temp __attribute__((unused)),
+ int fd, int cmd, abi_long arg)
+{
+ struct live_urb *lurb;
+
+ /* map target address back to host URB with metadata. */
+ lurb = urb_hashtable_lookup(arg);
+ if (!lurb) {
+ return -TARGET_EFAULT;
+ }
+ return get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
+}
+
+static abi_long
+do_ioctl_usbdevfs_submiturb(const IOCTLEntry *ie, uint8_t *buf_temp,
+ int fd, int cmd, abi_long arg)
+{
+ const argtype *arg_type = ie->arg_type;
+ int target_size;
+ abi_long ret;
+ void *argptr;
+ int rw_dir;
+ struct live_urb *lurb;
+
+ /*
+ * each submitted URB needs to map to a unique ID for the
+ * kernel, and that unique ID needs to be a pointer to
+ * host memory. hence, we need to malloc for each URB.
+ * isochronous transfers have a variable length struct.
+ */
+ arg_type++;
+ target_size = thunk_type_size(arg_type, THUNK_TARGET);
+
+ /* construct host copy of urb and metadata */
+ lurb = g_try_malloc0(sizeof(struct live_urb));
+ if (!lurb) {
+ return -TARGET_ENOMEM;
+ }
+
+ argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+ if (!argptr) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+ thunk_convert(&lurb->host_urb, argptr, arg_type, THUNK_HOST);
+ unlock_user(argptr, arg, 0);
+
+ lurb->target_urb_adr = arg;
+ lurb->target_buf_adr = (uintptr_t)lurb->host_urb.buffer;
+
+ /* buffer space used depends on endpoint type so lock the entire buffer */
+ /* control type urbs should check the buffer contents for true direction */
+ rw_dir = lurb->host_urb.endpoint & USB_DIR_IN ? VERIFY_WRITE : VERIFY_READ;
+ lurb->target_buf_ptr = lock_user(rw_dir, lurb->target_buf_adr,
+ lurb->host_urb.buffer_length, 1);
+ if (lurb->target_buf_ptr == NULL) {
+ g_free(lurb);
+ return -TARGET_EFAULT;
+ }
+
+ /* update buffer pointer in host copy */
+ lurb->host_urb.buffer = lurb->target_buf_ptr;
+
+ ret = get_errno(safe_ioctl(fd, ie->host_cmd, &lurb->host_urb));
+ if (is_error(ret)) {
+ unlock_user(lurb->target_buf_ptr, lurb->target_buf_adr, 0);
+ g_free(lurb);
+ } else {
+ urb_hashtable_insert(lurb);
+ }
+
+ return ret;
+}
+#endif /* CONFIG_USBFS */
+
static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
int cmd, abi_long arg)
{
@@ -9364,7 +9544,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
* even though the current architectural maximum is VQ=16.
*/
ret = -TARGET_EINVAL;
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)
+ if (cpu_isar_feature(aa64_sve, arm_env_get_cpu(cpu_env))
&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
CPUARMState *env = cpu_env;
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -9383,9 +9563,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
return ret;
case TARGET_PR_SVE_GET_VL:
ret = -TARGET_EINVAL;
- if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
- CPUARMState *env = cpu_env;
- ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
+ {
+ ARMCPU *cpu = arm_env_get_cpu(cpu_env);
+ if (cpu_isar_feature(aa64_sve, cpu)) {
+ ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16;
+ }
}
return ret;
#endif /* AARCH64 */
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 18d434d6dc..99bbce083c 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -863,6 +863,34 @@ struct target_pollfd {
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
+/* usb ioctls */
+#define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0)
+#define TARGET_USBDEVFS_BULK TARGET_IOWRU('U', 2)
+#define TARGET_USBDEVFS_RESETEP TARGET_IORU('U', 3)
+#define TARGET_USBDEVFS_SETINTERFACE TARGET_IORU('U', 4)
+#define TARGET_USBDEVFS_SETCONFIGURATION TARGET_IORU('U', 5)
+#define TARGET_USBDEVFS_GETDRIVER TARGET_IOWU('U', 8)
+#define TARGET_USBDEVFS_SUBMITURB TARGET_IORU('U', 10)
+#define TARGET_USBDEVFS_DISCARDURB TARGET_IO('U', 11)
+#define TARGET_USBDEVFS_REAPURB TARGET_IOWU('U', 12)
+#define TARGET_USBDEVFS_REAPURBNDELAY TARGET_IOWU('U', 13)
+#define TARGET_USBDEVFS_DISCSIGNAL TARGET_IORU('U', 14)
+#define TARGET_USBDEVFS_CLAIMINTERFACE TARGET_IORU('U', 15)
+#define TARGET_USBDEVFS_RELEASEINTERFACE TARGET_IORU('U', 16)
+#define TARGET_USBDEVFS_CONNECTINFO TARGET_IOWU('U', 17)
+#define TARGET_USBDEVFS_IOCTL TARGET_IOWRU('U', 18)
+#define TARGET_USBDEVFS_HUB_PORTINFO TARGET_IORU('U', 19)
+#define TARGET_USBDEVFS_RESET TARGET_IO('U', 20)
+#define TARGET_USBDEVFS_CLEAR_HALT TARGET_IORU('U', 21)
+#define TARGET_USBDEVFS_DISCONNECT TARGET_IO('U', 22)
+#define TARGET_USBDEVFS_CONNECT TARGET_IO('U', 23)
+#define TARGET_USBDEVFS_CLAIM_PORT TARGET_IORU('U', 24)
+#define TARGET_USBDEVFS_RELEASE_PORT TARGET_IORU('U', 25)
+#define TARGET_USBDEVFS_GET_CAPABILITIES TARGET_IORU('U', 26)
+#define TARGET_USBDEVFS_DISCONNECT_CLAIM TARGET_IORU('U', 27)
+#define TARGET_USBDEVFS_DROP_PRIVILEGES TARGET_IOWU('U', 30)
+#define TARGET_USBDEVFS_GET_SPEED TARGET_IO('U', 31)
+
/* cdrom commands */
#define TARGET_CDROMPAUSE 0x5301 /* Pause Audio Operation */
#define TARGET_CDROMRESUME 0x5302 /* Resume paused Audio Operation */
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index 24631b09be..b98a23b0f1 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -266,3 +266,71 @@ STRUCT(blkpg_ioctl_arg,
TYPE_INT, /* flags */
TYPE_INT, /* datalen */
TYPE_PTRVOID) /* data */
+
+#if defined(CONFIG_USBFS)
+/* usb device ioctls */
+STRUCT(usbdevfs_ctrltransfer,
+ TYPE_CHAR, /* bRequestType */
+ TYPE_CHAR, /* bRequest */
+ TYPE_SHORT, /* wValue */
+ TYPE_SHORT, /* wIndex */
+ TYPE_SHORT, /* wLength */
+ TYPE_INT, /* timeout */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_bulktransfer,
+ TYPE_INT, /* ep */
+ TYPE_INT, /* len */
+ TYPE_INT, /* timeout */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_setinterface,
+ TYPE_INT, /* interface */
+ TYPE_INT) /* altsetting */
+
+STRUCT(usbdevfs_disconnectsignal,
+ TYPE_INT, /* signr */
+ TYPE_PTRVOID) /* context */
+
+STRUCT(usbdevfs_getdriver,
+ TYPE_INT, /* interface */
+ MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */
+
+STRUCT(usbdevfs_connectinfo,
+ TYPE_INT, /* devnum */
+ TYPE_CHAR) /* slow */
+
+STRUCT(usbdevfs_iso_packet_desc,
+ TYPE_INT, /* length */
+ TYPE_INT, /* actual_length */
+ TYPE_INT) /* status */
+
+STRUCT(usbdevfs_urb,
+ TYPE_CHAR, /* type */
+ TYPE_CHAR, /* endpoint */
+ TYPE_INT, /* status */
+ TYPE_INT, /* flags */
+ TYPE_PTRVOID, /* buffer */
+ TYPE_INT, /* buffer_length */
+ TYPE_INT, /* actual_length */
+ TYPE_INT, /* start_frame */
+ TYPE_INT, /* union number_of_packets stream_id */
+ TYPE_INT, /* error_count */
+ TYPE_INT, /* signr */
+ TYPE_PTRVOID, /* usercontext */
+ MK_ARRAY(MK_STRUCT(STRUCT_usbdevfs_iso_packet_desc), 0)) /* desc */
+
+STRUCT(usbdevfs_ioctl,
+ TYPE_INT, /* ifno */
+ TYPE_INT, /* ioctl_code */
+ TYPE_PTRVOID) /* data */
+
+STRUCT(usbdevfs_hub_portinfo,
+ TYPE_CHAR, /* nports */
+ MK_ARRAY(TYPE_CHAR, 127)) /* port */
+
+STRUCT(usbdevfs_disconnect_claim,
+ TYPE_INT, /* interface */
+ TYPE_INT, /* flags */
+ MK_ARRAY(TYPE_CHAR, USBDEVFS_MAXDRIVERNAME + 1)) /* driver */
+#endif /* CONFIG_USBFS */
diff --git a/migration/migration.c b/migration/migration.c
index 7696729340..8b36e7f184 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1577,9 +1577,9 @@ static GSList *migration_blockers;
int migrate_add_blocker(Error *reason, Error **errp)
{
if (migrate_get_current()->only_migratable) {
- error_propagate(errp, error_copy(reason));
- error_prepend(errp, "disallowing migration blocker "
- "(--only_migratable) for: ");
+ error_propagate_prepend(errp, error_copy(reason),
+ "disallowing migration blocker "
+ "(--only_migratable) for: ");
return -EACCES;
}
@@ -1588,9 +1588,9 @@ int migrate_add_blocker(Error *reason, Error **errp)
return 0;
}
- error_propagate(errp, error_copy(reason));
- error_prepend(errp, "disallowing migration blocker (migration in "
- "progress) for: ");
+ error_propagate_prepend(errp, error_copy(reason),
+ "disallowing migration blocker "
+ "(migration in progress) for: ");
return -EBUSY;
}
diff --git a/migration/savevm.c b/migration/savevm.c
index e4caff9a6a..9992af4db4 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2453,8 +2453,8 @@ int save_snapshot(const char *name, Error **errp)
AioContext *aio_context;
if (!replay_can_snapshot()) {
- error_report("Record/replay does not allow making snapshot "
- "right now. Try once more later.");
+ error_setg(errp, "Record/replay does not allow making snapshot "
+ "right now. Try once more later.");
return ret;
}
@@ -2650,8 +2650,8 @@ int load_snapshot(const char *name, Error **errp)
MigrationIncomingState *mis = migration_incoming_get_current();
if (!replay_can_snapshot()) {
- error_report("Record/replay does not allow loading snapshot "
- "right now. Try once more later.");
+ error_setg(errp, "Record/replay does not allow loading snapshot "
+ "right now. Try once more later.");
return -EINVAL;
}
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 6745b78990..81db24dc8c 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -28,6 +28,7 @@
#include <netdb.h>
#include "net/net.h"
#include "clients.h"
+#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
@@ -528,7 +529,6 @@ int net_init_l2tpv3(const Netdev *netdev,
const char *name,
NetClientState *peer, Error **errp)
{
- /* FIXME error_setg(errp, ...) on failure */
const NetdevL2TPv3Options *l2tpv3;
NetL2TPV3State *s;
NetClientState *nc;
@@ -555,7 +555,7 @@ int net_init_l2tpv3(const Netdev *netdev,
}
if ((l2tpv3->has_offset) && (l2tpv3->offset > 256)) {
- error_report("l2tpv3_open : offset must be less than 256 bytes");
+ error_setg(errp, "offset must be less than 256 bytes");
goto outerr;
}
@@ -563,6 +563,8 @@ int net_init_l2tpv3(const Netdev *netdev,
if (l2tpv3->has_rxcookie && l2tpv3->has_txcookie) {
s->cookie = true;
} else {
+ error_setg(errp,
+ "require both 'rxcookie' and 'txcookie' or neither");
goto outerr;
}
} else {
@@ -578,7 +580,7 @@ int net_init_l2tpv3(const Netdev *netdev,
if (l2tpv3->has_udp && l2tpv3->udp) {
s->udp = true;
if (!(l2tpv3->has_srcport && l2tpv3->has_dstport)) {
- error_report("l2tpv3_open : need both src and dst port for udp");
+ error_setg(errp, "need both src and dst port for udp");
goto outerr;
} else {
srcport = l2tpv3->srcport;
@@ -639,20 +641,19 @@ int net_init_l2tpv3(const Netdev *netdev,
gairet = getaddrinfo(l2tpv3->src, srcport, &hints, &result);
if ((gairet != 0) || (result == NULL)) {
- error_report(
- "l2tpv3_open : could not resolve src, errno = %s",
- gai_strerror(gairet)
- );
+ error_setg(errp, "could not resolve src, errno = %s",
+ gai_strerror(gairet));
goto outerr;
}
fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (fd == -1) {
fd = -errno;
- error_report("l2tpv3_open : socket creation failed, errno = %d", -fd);
+ error_setg(errp, "socket creation failed, errno = %d",
+ -fd);
goto outerr;
}
if (bind(fd, (struct sockaddr *) result->ai_addr, result->ai_addrlen)) {
- error_report("l2tpv3_open : could not bind socket err=%i", errno);
+ error_setg(errp, "could not bind socket err=%i", errno);
goto outerr;
}
if (result) {
@@ -677,10 +678,8 @@ int net_init_l2tpv3(const Netdev *netdev,
result = NULL;
gairet = getaddrinfo(l2tpv3->dst, dstport, &hints, &result);
if ((gairet != 0) || (result == NULL)) {
- error_report(
- "l2tpv3_open : could not resolve dst, error = %s",
- gai_strerror(gairet)
- );
+ error_setg(errp, "could not resolve dst, error = %s",
+ gai_strerror(gairet));
goto outerr;
}
diff --git a/net/slirp.c b/net/slirp.c
index 99884de204..f6dc03963a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -150,6 +150,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
const char *vnameserver, const char *vnameserver6,
const char *smb_export, const char *vsmbserver,
const char **dnssearch, const char *vdomainname,
+ const char *tftp_server_name,
Error **errp)
{
/* default settings according to historic slirp */
@@ -350,6 +351,20 @@ static int net_slirp_init(NetClientState *peer, const char *model,
return -1;
}
+ if (vdomainname && strlen(vdomainname) > 255) {
+ error_setg(errp, "'domainname' parameter cannot exceed 255 bytes");
+ return -1;
+ }
+
+ if (vhostname && strlen(vhostname) > 255) {
+ error_setg(errp, "'vhostname' parameter cannot exceed 255 bytes");
+ return -1;
+ }
+
+ if (tftp_server_name && strlen(tftp_server_name) > 255) {
+ error_setg(errp, "'tftp-server-name' parameter cannot exceed 255 bytes");
+ return -1;
+ }
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
@@ -361,7 +376,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
s->slirp = slirp_init(restricted, ipv4, net, mask, host,
ipv6, ip6_prefix, vprefix6_len, ip6_host,
- vhostname, tftp_export, bootfile, dhcp,
+ vhostname, tftp_server_name,
+ tftp_export, bootfile, dhcp,
dns, ip6_dns, dnssearch, vdomainname, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
@@ -898,7 +914,8 @@ int net_init_slirp(const Netdev *netdev, const char *name,
user->ipv6_host, user->hostname, user->tftp,
user->bootfile, user->dhcpstart,
user->dns, user->ipv6_dns, user->smb,
- user->smbserver, dnssearch, user->domainname, errp);
+ user->smbserver, dnssearch, user->domainname,
+ user->tftp_server_name, errp);
while (slirp_configs) {
config = slirp_configs;
diff --git a/net/socket.c b/net/socket.c
index 6917fbcbf5..90ef3517be 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -453,8 +453,8 @@ static NetSocketState *net_socket_fd_init(NetClientState *peer,
case SOCK_STREAM:
return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
default:
- error_report("socket type=%d for fd=%d must be either"
- " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
+ error_setg(errp, "socket type=%d for fd=%d must be either"
+ " SOCK_DGRAM or SOCK_STREAM", so_type, fd);
closesocket(fd);
}
return NULL;
diff --git a/numa.c b/numa.c
index 81542d4ebb..50ec016013 100644
--- a/numa.c
+++ b/numa.c
@@ -60,6 +60,7 @@ NodeInfo numa_info[MAX_NODES];
static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
Error **errp)
{
+ Error *err = NULL;
uint16_t nodenr;
uint16List *cpus = NULL;
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -82,8 +83,8 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
}
if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
- error_report("NUMA is not supported by this machine-type");
- exit(1);
+ error_setg(errp, "NUMA is not supported by this machine-type");
+ return;
}
for (cpus = node->cpus; cpus; cpus = cpus->next) {
CpuInstanceProperties props;
@@ -97,7 +98,11 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
props = mc->cpu_index_to_instance_props(ms, cpus->value);
props.node_id = nodenr;
props.has_node_id = true;
- machine_set_cpu_numa_node(ms, &props, &error_fatal);
+ machine_set_cpu_numa_node(ms, &props, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
}
if (node->has_mem && node->has_memdev) {
@@ -210,7 +215,7 @@ end:
error_propagate(errp, err);
}
-int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
+static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
{
NumaOptions *object = NULL;
MachineState *ms = MACHINE(opaque);
@@ -234,7 +239,7 @@ int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
end:
qapi_free_NumaOptions(object);
if (err) {
- error_report_err(err);
+ error_propagate(errp, err);
return -1;
}
@@ -367,7 +372,7 @@ void numa_complete_configuration(MachineState *ms)
if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
mc->auto_enable_numa_with_memhp) {
NumaNodeOptions node = { };
- parse_numa_node(ms, &node, NULL);
+ parse_numa_node(ms, &node, &error_abort);
}
assert(max_numa_nodeid <= MAX_NODES);
@@ -439,9 +444,7 @@ void numa_complete_configuration(MachineState *ms)
void parse_numa_opts(MachineState *ms)
{
- if (qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal);
}
void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
diff --git a/po/Makefile b/po/Makefile
index e47e262ee6..c041f4c858 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -36,7 +36,7 @@ clean:
install: $(OBJS)
for obj in $(OBJS); do \
- base=`basename $$obj .mo`; \
+ base=$$(basename $$obj .mo); \
$(INSTALL) -d $(DESTDIR)$(prefix)/share/locale/$$base/LC_MESSAGES; \
$(INSTALL) -m644 $$obj $(DESTDIR)$(prefix)/share/locale/$$base/LC_MESSAGES/qemu.mo; \
done
diff --git a/qapi/misc.json b/qapi/misc.json
index c85c6c8ca3..6c1c5c0a37 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2066,7 +2066,7 @@
#
# @plugged-memory: size of memory that can be hot-unplugged. This field
# is omitted if target doesn't support memory hotplug
-# (i.e. CONFIG_MEM_HOTPLUG not defined on build time).
+# (i.e. CONFIG_MEM_DEVICE not defined at build time).
#
# Since: 2.11.0
##
diff --git a/qapi/net.json b/qapi/net.json
index c86f351161..8f99fd911d 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -174,6 +174,8 @@
#
# @guestfwd: forward guest TCP connections
#
+# @tftp-server-name: RFC2132 "TFTP server name" string (Since 3.1)
+#
# Since: 1.2
##
{ 'struct': 'NetdevUserOptions',
@@ -198,7 +200,8 @@
'*smb': 'str',
'*smbserver': 'str',
'*hostfwd': ['String'],
- '*guestfwd': ['String'] } }
+ '*guestfwd': ['String'],
+ '*tftp-server-name': 'str' } }
##
# @NetdevTapOptions:
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 11b870c5c1..5d2d7a3588 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -86,6 +86,18 @@ for these file types is 'host_cdrom' or 'host_device' as appropriate.
The @option{name} parameter of the @option{-net} option is a synonym
for the @option{id} parameter, which should now be used instead.
+@subsection -smp (invalid topologies) (since 3.1)
+
+CPU topology properties should describe whole machine topology including
+possible CPUs.
+
+However, historically it was possible to start QEMU with an incorrect topology
+where @math{@var{n} <= @var{sockets} * @var{cores} * @var{threads} < @var{maxcpus}},
+which could lead to an incorrect topology enumeration by the guest.
+Support for invalid topologies will be removed, the user must ensure
+topologies described with -smp include all possible cpus, i.e.
+ @math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
+
@section QEMU Machine Protocol (QMP) commands
@subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)
diff --git a/qemu-io.c b/qemu-io.c
index 13829f5e21..6df7731af4 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -620,11 +620,9 @@ int main(int argc, char **argv)
exit(1);
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(&qemu_object_opts,
+ user_creatable_add_opts_foreach,
+ NULL, &error_fatal);
if (!trace_init_backends()) {
exit(1);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e76fe3082a..ca7109652e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -766,11 +766,9 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE);
}
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- NULL, NULL)) {
- exit(EXIT_FAILURE);
- }
+ qemu_opts_foreach(&qemu_object_opts,
+ user_creatable_add_opts_foreach,
+ NULL, &error_fatal);
if (!trace_init_backends()) {
exit(1);
@@ -1002,11 +1000,7 @@ int main(int argc, char **argv)
}
exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed,
- writethrough, NULL, &local_err);
- if (!exp) {
- error_report_err(local_err);
- exit(EXIT_FAILURE);
- }
+ writethrough, NULL, &error_fatal);
nbd_export_set_name(exp, export_name);
nbd_export_set_description(exp, export_description);
diff --git a/qemu-options.hx b/qemu-options.hx
index 214ce396f9..08f8516a9a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1823,7 +1823,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
" [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
" [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
- " [,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
+ " [,tftp=dir][,tftp-server-name=name][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
#ifndef _WIN32
"[,smb=dir[,smbserver=addr]]\n"
#endif
@@ -2060,6 +2060,11 @@ server. The files in @var{dir} will be exposed as the root of a TFTP server.
The TFTP client on the guest must be configured in binary mode (use the command
@code{bin} of the Unix TFTP client).
+@item tftp-server-name=@var{name}
+In BOOTP reply, broadcast @var{name} as the "TFTP server name" (RFC2132 option
+66). This can be used to advise the guest to load boot files or configurations
+from a different server than the host address.
+
@item bootfile=@var{file}
When using the user mode network stack, broadcast @var{file} as the BOOTP
filename. In conjunction with @option{tftp}, this can be used to network boot
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index 1baa5c69ed..5c73e6ad05 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -12,11 +12,12 @@
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/
+
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/module.h"
-#include "qemu/error-report.h"
#include <sys/prctl.h>
#include <seccomp.h>
#include "sysemu/seccomp.h"
@@ -190,7 +191,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
* to provide a little bit of consistency for
* the command line */
} else {
- error_report("invalid argument for obsolete");
+ error_setg(errp, "invalid argument for obsolete");
return -1;
}
}
@@ -205,14 +206,13 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
/* calling prctl directly because we're
* not sure if host has CAP_SYS_ADMIN set*/
if (prctl(PR_SET_NO_NEW_PRIVS, 1)) {
- error_report("failed to set no_new_privs "
- "aborting");
+ error_setg(errp, "failed to set no_new_privs aborting");
return -1;
}
} else if (g_str_equal(value, "allow")) {
/* default value */
} else {
- error_report("invalid argument for elevateprivileges");
+ error_setg(errp, "invalid argument for elevateprivileges");
return -1;
}
}
@@ -224,7 +224,7 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
} else if (g_str_equal(value, "allow")) {
/* default value */
} else {
- error_report("invalid argument for spawn");
+ error_setg(errp, "invalid argument for spawn");
return -1;
}
}
@@ -236,14 +236,14 @@ int parse_sandbox(void *opaque, QemuOpts *opts, Error **errp)
} else if (g_str_equal(value, "allow")) {
/* default value */
} else {
- error_report("invalid argument for resourcecontrol");
+ error_setg(errp, "invalid argument for resourcecontrol");
return -1;
}
}
if (seccomp_start(seccomp_opts) < 0) {
- error_report("failed to install seccomp syscall filter "
- "in the kernel");
+ error_setg(errp, "failed to install seccomp syscall filter "
+ "in the kernel");
return -1;
}
}
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 941fd63afd..97b79b48bb 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -143,7 +143,6 @@ int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
{
bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
Object *obj = NULL;
- Error *err = NULL;
const char *type;
type = qemu_opt_get(opts, "qom-type");
@@ -152,9 +151,8 @@ int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
return 0;
}
- obj = user_creatable_add_opts(opts, &err);
+ obj = user_creatable_add_opts(opts, errp);
if (!obj) {
- error_report_err(err);
return -1;
}
object_unref(obj);
diff --git a/scripts/check-qerror.sh b/scripts/check-qerror.sh
deleted file mode 100755
index af7fbd5249..0000000000
--- a/scripts/check-qerror.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-# This script verifies that qerror definitions and table entries are
-# alphabetically ordered.
-
-check_order() {
- errmsg=$1
- shift
-
- # sort -C verifies order but does not print a message. sort -c does print a
- # message. These options are both in POSIX.
- if ! "$@" | sort -C; then
- echo "$errmsg"
- "$@" | sort -c
- exit 1
- fi
- return 0
-}
-
-check_order 'Definitions in qerror.h must be in alphabetical order:' \
- grep '^#define QERR_' qerror.h
-check_order 'Entries in qerror.c:qerror_table must be in alphabetical order:' \
- sed -n '/^static.*qerror_table\[\]/,/^};/s/QERR_/&/gp' qerror.c
diff --git a/scripts/coccinelle/use-error_fatal.cocci b/scripts/coccinelle/use-error_fatal.cocci
new file mode 100644
index 0000000000..10fff0aec4
--- /dev/null
+++ b/scripts/coccinelle/use-error_fatal.cocci
@@ -0,0 +1,20 @@
+@@
+type T;
+identifier FUN, RET;
+expression list ARGS;
+expression ERR, EC, FAIL;
+@@
+(
+- T RET = FUN(ARGS, &ERR);
++ T RET = FUN(ARGS, &error_fatal);
+|
+- RET = FUN(ARGS, &ERR);
++ RET = FUN(ARGS, &error_fatal);
+|
+- FUN(ARGS, &ERR);
++ FUN(ARGS, &error_fatal);
+)
+- if (FAIL) {
+- error_report_err(ERR);
+- exit(EC);
+- }
diff --git a/scripts/qemu.py b/scripts/qemu.py
index f099ce7278..bcd24aad82 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -26,6 +26,12 @@ import tempfile
LOG = logging.getLogger(__name__)
+def kvm_available(target_arch=None):
+ if target_arch and target_arch != os.uname()[4]:
+ return False
+ return os.access("/dev/kvm", os.R_OK | os.W_OK)
+
+
#: Maps machine types to the preferred console device types
CONSOLE_DEV_TYPES = {
r'^clipper$': 'isa-serial',
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 9e7b53ba94..7b1af73c95 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -159,6 +159,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
struct in_addr preq_addr;
int dhcp_msg_type, val;
uint8_t *q;
+ uint8_t *end;
uint8_t client_ethaddr[ETH_ALEN];
/* extract exact DHCP msg type */
@@ -240,6 +241,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
q = rbp->bp_vend;
+ end = (uint8_t *)&rbp[1];
memcpy(q, rfc1533_cookie, 4);
q += 4;
@@ -292,24 +294,46 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
if (*slirp->client_hostname) {
val = strlen(slirp->client_hostname);
- *q++ = RFC1533_HOSTNAME;
- *q++ = val;
- memcpy(q, slirp->client_hostname, val);
- q += val;
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting host name option.");
+ } else {
+ *q++ = RFC1533_HOSTNAME;
+ *q++ = val;
+ memcpy(q, slirp->client_hostname, val);
+ q += val;
+ }
}
if (slirp->vdomainname) {
val = strlen(slirp->vdomainname);
- *q++ = RFC1533_DOMAINNAME;
- *q++ = val;
- memcpy(q, slirp->vdomainname, val);
- q += val;
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting domain name option.");
+ } else {
+ *q++ = RFC1533_DOMAINNAME;
+ *q++ = val;
+ memcpy(q, slirp->vdomainname, val);
+ q += val;
+ }
+ }
+
+ if (slirp->tftp_server_name) {
+ val = strlen(slirp->tftp_server_name);
+ if (q + val + 2 >= end) {
+ g_warning("DHCP packet size exceeded, "
+ "omitting tftp-server-name option.");
+ } else {
+ *q++ = RFC2132_TFTP_SERVER_NAME;
+ *q++ = val;
+ memcpy(q, slirp->tftp_server_name, val);
+ q += val;
+ }
}
if (slirp->vdnssearch) {
- size_t spaceleft = sizeof(rbp->bp_vend) - (q - rbp->bp_vend);
val = slirp->vdnssearch_len;
- if (val + 1 > spaceleft) {
+ if (q + val >= end) {
g_warning("DHCP packet size exceeded, "
"omitting domain-search option.");
} else {
@@ -331,6 +355,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
memcpy(q, nak_msg, sizeof(nak_msg) - 1);
q += sizeof(nak_msg) - 1;
}
+ assert(q < end);
*q = RFC1533_END;
daddr.sin_addr.s_addr = 0xffffffffu;
diff --git a/slirp/bootp.h b/slirp/bootp.h
index 394525733e..4043489835 100644
--- a/slirp/bootp.h
+++ b/slirp/bootp.h
@@ -70,6 +70,7 @@
#define RFC2132_MAX_SIZE 57
#define RFC2132_RENEWAL_TIME 58
#define RFC2132_REBIND_TIME 59
+#define RFC2132_TFTP_SERVER_NAME 66
#define DHCPDISCOVER 1
#define DHCPOFFER 2
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 740408a96e..42e42e9a2a 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -13,6 +13,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
bool in6_enabled,
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
struct in6_addr vhost6, const char *vhostname,
+ const char *tftp_server_name,
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 5c3bd6163f..51de41fc02 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -283,6 +283,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
bool in6_enabled,
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
struct in6_addr vhost6, const char *vhostname,
+ const char *tftp_server_name,
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
@@ -321,6 +322,7 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
slirp->vdhcp_startaddr = vdhcp_start;
slirp->vnameserver_addr = vnameserver;
slirp->vnameserver_addr6 = vnameserver6;
+ slirp->tftp_server_name = g_strdup(tftp_server_name);
if (vdnssearch) {
translate_dnssearch(slirp, vdnssearch);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 10b410898a..b80725a0d6 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -212,6 +212,7 @@ struct Slirp {
/* tftp states */
char *tftp_prefix;
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
+ char *tftp_server_name;
ArpTable arp_table;
NdpTable ndp_table;
diff --git a/stubs/tpm.c b/stubs/tpm.c
index 6729bc8517..80939cd3db 100644
--- a/stubs/tpm.c
+++ b/stubs/tpm.c
@@ -9,9 +9,8 @@
#include "qapi/qapi-commands-tpm.h"
#include "sysemu/tpm.h"
-int tpm_init(void)
+void tpm_init(void)
{
- return 0;
}
void tpm_cleanup(void)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index cd48ad42d8..8f16e96b6c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -144,9 +144,9 @@ static void arm_cpu_reset(CPUState *s)
g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu);
env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
- env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
- env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
- env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;
+ env->vfp.xregs[ARM_VFP_MVFR0] = cpu->isar.mvfr0;
+ env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1;
+ env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2;
cpu->power_state = cpu->start_powered_off ? PSCI_OFF : PSCI_ON;
s->halted = cpu->start_powered_off;
@@ -814,7 +814,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
/* Some features automatically imply others: */
if (arm_feature(env, ARM_FEATURE_V8)) {
- set_feature(env, ARM_FEATURE_V7VE);
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ set_feature(env, ARM_FEATURE_V7);
+ } else {
+ set_feature(env, ARM_FEATURE_V7VE);
+ }
}
if (arm_feature(env, ARM_FEATURE_V7VE)) {
/* v7 Virtualization Extensions. In real hardware this implies
@@ -825,7 +829,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* Presence of EL2 itself is ARM_FEATURE_EL2, and of the
* Security Extensions is ARM_FEATURE_EL3.
*/
- set_feature(env, ARM_FEATURE_ARM_DIV);
+ assert(cpu_isar_feature(arm_div, cpu));
set_feature(env, ARM_FEATURE_LPAE);
set_feature(env, ARM_FEATURE_V7);
}
@@ -850,20 +854,14 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
if (arm_feature(env, ARM_FEATURE_V6)) {
set_feature(env, ARM_FEATURE_V5);
- set_feature(env, ARM_FEATURE_JAZELLE);
if (!arm_feature(env, ARM_FEATURE_M)) {
+ assert(cpu_isar_feature(jazelle, cpu));
set_feature(env, ARM_FEATURE_AUXCR);
}
}
if (arm_feature(env, ARM_FEATURE_V5)) {
set_feature(env, ARM_FEATURE_V4T);
}
- if (arm_feature(env, ARM_FEATURE_M)) {
- set_feature(env, ARM_FEATURE_THUMB_DIV);
- }
- if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
- set_feature(env, ARM_FEATURE_THUMB_DIV);
- }
if (arm_feature(env, ARM_FEATURE_VFP4)) {
set_feature(env, ARM_FEATURE_VFP3);
set_feature(env, ARM_FEATURE_VFP_FP16);
@@ -938,7 +936,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].
*/
cpu->id_pfr1 &= ~0xf0;
- cpu->id_aa64pfr0 &= ~0xf000;
+ cpu->isar.id_aa64pfr0 &= ~0xf000;
}
if (!cpu->has_el2) {
@@ -955,7 +953,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
* registers if we don't have EL2. These are id_pfr1[15:12] and
* id_aa64pfr0_el1[11:8].
*/
- cpu->id_aa64pfr0 &= ~0xf00;
+ cpu->isar.id_aa64pfr0 &= ~0xf00;
cpu->id_pfr1 &= ~0xf000;
}
@@ -1084,11 +1082,16 @@ static void arm926_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_VFP);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
cpu->midr = 0x41069265;
cpu->reset_fpsid = 0x41011090;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
+
+ /*
+ * ARMv5 does not have the ID_ISAR registers, but we can still
+ * set the field to indicate Jazelle support within QEMU.
+ */
+ cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
}
static void arm946_initfn(Object *obj)
@@ -1114,12 +1117,18 @@ static void arm1026_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
- set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
cpu->midr = 0x4106a262;
cpu->reset_fpsid = 0x410110a0;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00090078;
cpu->reset_auxcr = 1;
+
+ /*
+ * ARMv5 does not have the ID_ISAR registers, but we can still
+ * set the field to indicate Jazelle support within QEMU.
+ */
+ cpu->isar.id_isar1 = FIELD_DP32(cpu->isar.id_isar1, ID_ISAR1, JAZELLE, 1);
+
{
/* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
ARMCPRegInfo ifar = {
@@ -1151,8 +1160,8 @@ static void arm1136_r2_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4107b362;
cpu->reset_fpsid = 0x410120b4;
- cpu->mvfr0 = 0x11111111;
- cpu->mvfr1 = 0x00000000;
+ cpu->isar.mvfr0 = 0x11111111;
+ cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
@@ -1162,11 +1171,11 @@ static void arm1136_r2_initfn(Object *obj)
cpu->id_mmfr0 = 0x01130003;
cpu->id_mmfr1 = 0x10030302;
cpu->id_mmfr2 = 0x01222110;
- cpu->id_isar0 = 0x00140011;
- cpu->id_isar1 = 0x12002111;
- cpu->id_isar2 = 0x11231111;
- cpu->id_isar3 = 0x01102131;
- cpu->id_isar4 = 0x141;
+ cpu->isar.id_isar0 = 0x00140011;
+ cpu->isar.id_isar1 = 0x12002111;
+ cpu->isar.id_isar2 = 0x11231111;
+ cpu->isar.id_isar3 = 0x01102131;
+ cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
@@ -1183,8 +1192,8 @@ static void arm1136_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
cpu->midr = 0x4117b363;
cpu->reset_fpsid = 0x410120b4;
- cpu->mvfr0 = 0x11111111;
- cpu->mvfr1 = 0x00000000;
+ cpu->isar.mvfr0 = 0x11111111;
+ cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
@@ -1194,11 +1203,11 @@ static void arm1136_initfn(Object *obj)
cpu->id_mmfr0 = 0x01130003;
cpu->id_mmfr1 = 0x10030302;
cpu->id_mmfr2 = 0x01222110;
- cpu->id_isar0 = 0x00140011;
- cpu->id_isar1 = 0x12002111;
- cpu->id_isar2 = 0x11231111;
- cpu->id_isar3 = 0x01102131;
- cpu->id_isar4 = 0x141;
+ cpu->isar.id_isar0 = 0x00140011;
+ cpu->isar.id_isar1 = 0x12002111;
+ cpu->isar.id_isar2 = 0x11231111;
+ cpu->isar.id_isar3 = 0x01102131;
+ cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 7;
}
@@ -1216,8 +1225,8 @@ static void arm1176_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->midr = 0x410fb767;
cpu->reset_fpsid = 0x410120b5;
- cpu->mvfr0 = 0x11111111;
- cpu->mvfr1 = 0x00000000;
+ cpu->isar.mvfr0 = 0x11111111;
+ cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1dd20d2;
cpu->reset_sctlr = 0x00050078;
cpu->id_pfr0 = 0x111;
@@ -1227,11 +1236,11 @@ static void arm1176_initfn(Object *obj)
cpu->id_mmfr0 = 0x01130003;
cpu->id_mmfr1 = 0x10030302;
cpu->id_mmfr2 = 0x01222100;
- cpu->id_isar0 = 0x0140011;
- cpu->id_isar1 = 0x12002111;
- cpu->id_isar2 = 0x11231121;
- cpu->id_isar3 = 0x01102131;
- cpu->id_isar4 = 0x01141;
+ cpu->isar.id_isar0 = 0x0140011;
+ cpu->isar.id_isar1 = 0x12002111;
+ cpu->isar.id_isar2 = 0x11231121;
+ cpu->isar.id_isar3 = 0x01102131;
+ cpu->isar.id_isar4 = 0x01141;
cpu->reset_auxcr = 7;
}
@@ -1247,8 +1256,8 @@ static void arm11mpcore_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
cpu->midr = 0x410fb022;
cpu->reset_fpsid = 0x410120b4;
- cpu->mvfr0 = 0x11111111;
- cpu->mvfr1 = 0x00000000;
+ cpu->isar.mvfr0 = 0x11111111;
+ cpu->isar.mvfr1 = 0x00000000;
cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
cpu->id_pfr0 = 0x111;
cpu->id_pfr1 = 0x1;
@@ -1257,11 +1266,11 @@ static void arm11mpcore_initfn(Object *obj)
cpu->id_mmfr0 = 0x01100103;
cpu->id_mmfr1 = 0x10020302;
cpu->id_mmfr2 = 0x01222000;
- cpu->id_isar0 = 0x00100011;
- cpu->id_isar1 = 0x12002111;
- cpu->id_isar2 = 0x11221011;
- cpu->id_isar3 = 0x01102131;
- cpu->id_isar4 = 0x141;
+ cpu->isar.id_isar0 = 0x00100011;
+ cpu->isar.id_isar1 = 0x12002111;
+ cpu->isar.id_isar2 = 0x11221011;
+ cpu->isar.id_isar3 = 0x01102131;
+ cpu->isar.id_isar4 = 0x141;
cpu->reset_auxcr = 1;
}
@@ -1290,13 +1299,13 @@ static void cortex_m3_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x00000000;
cpu->id_mmfr3 = 0x00000000;
- cpu->id_isar0 = 0x01141110;
- cpu->id_isar1 = 0x02111000;
- cpu->id_isar2 = 0x21112231;
- cpu->id_isar3 = 0x01111110;
- cpu->id_isar4 = 0x01310102;
- cpu->id_isar5 = 0x00000000;
- cpu->id_isar6 = 0x00000000;
+ cpu->isar.id_isar0 = 0x01141110;
+ cpu->isar.id_isar1 = 0x02111000;
+ cpu->isar.id_isar2 = 0x21112231;
+ cpu->isar.id_isar3 = 0x01111110;
+ cpu->isar.id_isar4 = 0x01310102;
+ cpu->isar.id_isar5 = 0x00000000;
+ cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m4_initfn(Object *obj)
@@ -1317,13 +1326,13 @@ static void cortex_m4_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x00000000;
cpu->id_mmfr3 = 0x00000000;
- cpu->id_isar0 = 0x01141110;
- cpu->id_isar1 = 0x02111000;
- cpu->id_isar2 = 0x21112231;
- cpu->id_isar3 = 0x01111110;
- cpu->id_isar4 = 0x01310102;
- cpu->id_isar5 = 0x00000000;
- cpu->id_isar6 = 0x00000000;
+ cpu->isar.id_isar0 = 0x01141110;
+ cpu->isar.id_isar1 = 0x02111000;
+ cpu->isar.id_isar2 = 0x21112231;
+ cpu->isar.id_isar3 = 0x01111110;
+ cpu->isar.id_isar4 = 0x01310102;
+ cpu->isar.id_isar5 = 0x00000000;
+ cpu->isar.id_isar6 = 0x00000000;
}
static void cortex_m33_initfn(Object *obj)
@@ -1346,13 +1355,13 @@ static void cortex_m33_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x01000000;
cpu->id_mmfr3 = 0x00000000;
- cpu->id_isar0 = 0x01101110;
- cpu->id_isar1 = 0x02212000;
- cpu->id_isar2 = 0x20232232;
- cpu->id_isar3 = 0x01111131;
- cpu->id_isar4 = 0x01310132;
- cpu->id_isar5 = 0x00000000;
- cpu->id_isar6 = 0x00000000;
+ cpu->isar.id_isar0 = 0x01101110;
+ cpu->isar.id_isar1 = 0x02212000;
+ cpu->isar.id_isar2 = 0x20232232;
+ cpu->isar.id_isar3 = 0x01111131;
+ cpu->isar.id_isar4 = 0x01310132;
+ cpu->isar.id_isar5 = 0x00000000;
+ cpu->isar.id_isar6 = 0x00000000;
cpu->clidr = 0x00000000;
cpu->ctr = 0x8000c000;
}
@@ -1384,8 +1393,6 @@ static void cortex_r5_initfn(Object *obj)
ARMCPU *cpu = ARM_CPU(obj);
set_feature(&cpu->env, ARM_FEATURE_V7);
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
set_feature(&cpu->env, ARM_FEATURE_V7MP);
set_feature(&cpu->env, ARM_FEATURE_PMSA);
cpu->midr = 0x411fc153; /* r1p3 */
@@ -1397,13 +1404,13 @@ static void cortex_r5_initfn(Object *obj)
cpu->id_mmfr1 = 0x00000000;
cpu->id_mmfr2 = 0x01200000;
cpu->id_mmfr3 = 0x0211;
- cpu->id_isar0 = 0x02101111;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232141;
- cpu->id_isar3 = 0x01112131;
- cpu->id_isar4 = 0x0010142;
- cpu->id_isar5 = 0x0;
- cpu->id_isar6 = 0x0;
+ cpu->isar.id_isar0 = 0x02101111;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232141;
+ cpu->isar.id_isar3 = 0x01112131;
+ cpu->isar.id_isar4 = 0x0010142;
+ cpu->isar.id_isar5 = 0x0;
+ cpu->isar.id_isar6 = 0x0;
cpu->mp_is_up = true;
cpu->pmsav7_dregion = 16;
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
@@ -1438,8 +1445,8 @@ static void cortex_a8_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL3);
cpu->midr = 0x410fc080;
cpu->reset_fpsid = 0x410330c0;
- cpu->mvfr0 = 0x11110222;
- cpu->mvfr1 = 0x00011111;
+ cpu->isar.mvfr0 = 0x11110222;
+ cpu->isar.mvfr1 = 0x00011111;
cpu->ctr = 0x82048004;
cpu->reset_sctlr = 0x00c50078;
cpu->id_pfr0 = 0x1031;
@@ -1450,11 +1457,11 @@ static void cortex_a8_initfn(Object *obj)
cpu->id_mmfr1 = 0x20000000;
cpu->id_mmfr2 = 0x01202000;
cpu->id_mmfr3 = 0x11;
- cpu->id_isar0 = 0x00101111;
- cpu->id_isar1 = 0x12112111;
- cpu->id_isar2 = 0x21232031;
- cpu->id_isar3 = 0x11112131;
- cpu->id_isar4 = 0x00111142;
+ cpu->isar.id_isar0 = 0x00101111;
+ cpu->isar.id_isar1 = 0x12112111;
+ cpu->isar.id_isar2 = 0x21232031;
+ cpu->isar.id_isar3 = 0x11112131;
+ cpu->isar.id_isar4 = 0x00111142;
cpu->dbgdidr = 0x15141000;
cpu->clidr = (1 << 27) | (2 << 24) | 3;
cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
@@ -1512,8 +1519,8 @@ static void cortex_a9_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_CBAR);
cpu->midr = 0x410fc090;
cpu->reset_fpsid = 0x41033090;
- cpu->mvfr0 = 0x11110222;
- cpu->mvfr1 = 0x01111111;
+ cpu->isar.mvfr0 = 0x11110222;
+ cpu->isar.mvfr1 = 0x01111111;
cpu->ctr = 0x80038003;
cpu->reset_sctlr = 0x00c50078;
cpu->id_pfr0 = 0x1031;
@@ -1524,11 +1531,11 @@ static void cortex_a9_initfn(Object *obj)
cpu->id_mmfr1 = 0x20000000;
cpu->id_mmfr2 = 0x01230000;
cpu->id_mmfr3 = 0x00002111;
- cpu->id_isar0 = 0x00101111;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232041;
- cpu->id_isar3 = 0x11112131;
- cpu->id_isar4 = 0x00111142;
+ cpu->isar.id_isar0 = 0x00101111;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232041;
+ cpu->isar.id_isar3 = 0x11112131;
+ cpu->isar.id_isar4 = 0x00111142;
cpu->dbgdidr = 0x35141000;
cpu->clidr = (1 << 27) | (1 << 24) | 3;
cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
@@ -1573,8 +1580,8 @@ static void cortex_a7_initfn(Object *obj)
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075;
cpu->reset_fpsid = 0x41023075;
- cpu->mvfr0 = 0x10110222;
- cpu->mvfr1 = 0x11111111;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x84448003;
cpu->reset_sctlr = 0x00c50078;
cpu->id_pfr0 = 0x00001131;
@@ -1590,11 +1597,11 @@ static void cortex_a7_initfn(Object *obj)
/* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
* table 4-41 gives 0x02101110, which includes the arm div insns.
*/
- cpu->id_isar0 = 0x02101110;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232041;
- cpu->id_isar3 = 0x11112131;
- cpu->id_isar4 = 0x10011142;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232041;
+ cpu->isar.id_isar3 = 0x11112131;
+ cpu->isar.id_isar4 = 0x10011142;
cpu->dbgdidr = 0x3515f005;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
@@ -1619,8 +1626,8 @@ static void cortex_a15_initfn(Object *obj)
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
cpu->midr = 0x412fc0f1;
cpu->reset_fpsid = 0x410430f0;
- cpu->mvfr0 = 0x10110222;
- cpu->mvfr1 = 0x11111111;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x11111111;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50078;
cpu->id_pfr0 = 0x00001131;
@@ -1633,11 +1640,11 @@ static void cortex_a15_initfn(Object *obj)
cpu->id_mmfr1 = 0x20000000;
cpu->id_mmfr2 = 0x01240000;
cpu->id_mmfr3 = 0x02102211;
- cpu->id_isar0 = 0x02101110;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232041;
- cpu->id_isar3 = 0x11112131;
- cpu->id_isar4 = 0x10011142;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232041;
+ cpu->isar.id_isar3 = 0x11112131;
+ cpu->isar.id_isar4 = 0x10011142;
cpu->dbgdidr = 0x3515f021;
cpu->clidr = 0x0a200023;
cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
@@ -1830,17 +1837,26 @@ static void arm_max_initfn(Object *obj)
cortex_a15_initfn(obj);
#ifdef CONFIG_USER_ONLY
/* We don't set these in system emulation mode for the moment,
- * since we don't correctly set the ID registers to advertise them,
+ * since we don't correctly set (all of) the ID registers to
+ * advertise them.
*/
set_feature(&cpu->env, ARM_FEATURE_V8);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
- set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
+ {
+ uint32_t t;
+
+ t = cpu->isar.id_isar5;
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
+ cpu->isar.id_isar5 = t;
+
+ t = cpu->isar.id_isar6;
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
+ cpu->isar.id_isar6 = t;
+ }
#endif
}
}
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f00c0444c4..8e6779936e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -531,6 +531,13 @@ typedef struct CPUARMState {
*/
} exception;
+ /* Information associated with an SError */
+ struct {
+ uint8_t pending;
+ uint8_t has_esr;
+ uint64_t esr;
+ } serror;
+
/* Thumb-2 EE state. */
uint32_t teecr;
uint32_t teehbr;
@@ -669,6 +676,8 @@ typedef enum ARMPSCIState {
PSCI_ON_PENDING = 2
} ARMPSCIState;
+typedef struct ARMISARegisters ARMISARegisters;
+
/**
* ARMCPU:
* @env: #CPUARMState
@@ -788,13 +797,28 @@ struct ARMCPU {
* ARMv7AR ARM Architecture Reference Manual. A reset_ prefix
* is used for reset values of non-constant registers; no reset_
* prefix means a constant register.
+ * Some of these registers are split out into a substructure that
+ * is shared with the translators to control the ISA.
*/
+ struct ARMISARegisters {
+ uint32_t id_isar0;
+ uint32_t id_isar1;
+ uint32_t id_isar2;
+ uint32_t id_isar3;
+ uint32_t id_isar4;
+ uint32_t id_isar5;
+ uint32_t id_isar6;
+ uint32_t mvfr0;
+ uint32_t mvfr1;
+ uint32_t mvfr2;
+ uint64_t id_aa64isar0;
+ uint64_t id_aa64isar1;
+ uint64_t id_aa64pfr0;
+ uint64_t id_aa64pfr1;
+ } isar;
uint32_t midr;
uint32_t revidr;
uint32_t reset_fpsid;
- uint32_t mvfr0;
- uint32_t mvfr1;
- uint32_t mvfr2;
uint32_t ctr;
uint32_t reset_sctlr;
uint32_t id_pfr0;
@@ -808,21 +832,10 @@ struct ARMCPU {
uint32_t id_mmfr2;
uint32_t id_mmfr3;
uint32_t id_mmfr4;
- uint32_t id_isar0;
- uint32_t id_isar1;
- uint32_t id_isar2;
- uint32_t id_isar3;
- uint32_t id_isar4;
- uint32_t id_isar5;
- uint32_t id_isar6;
- uint64_t id_aa64pfr0;
- uint64_t id_aa64pfr1;
uint64_t id_aa64dfr0;
uint64_t id_aa64dfr1;
uint64_t id_aa64afr0;
uint64_t id_aa64afr1;
- uint64_t id_aa64isar0;
- uint64_t id_aa64isar1;
uint64_t id_aa64mmfr0;
uint64_t id_aa64mmfr1;
uint32_t dbgdidr;
@@ -1531,6 +1544,16 @@ FIELD(ID_AA64ISAR1, FRINTTS, 32, 4)
FIELD(ID_AA64ISAR1, SB, 36, 4)
FIELD(ID_AA64ISAR1, SPECRES, 40, 4)
+FIELD(ID_AA64PFR0, EL0, 0, 4)
+FIELD(ID_AA64PFR0, EL1, 4, 4)
+FIELD(ID_AA64PFR0, EL2, 8, 4)
+FIELD(ID_AA64PFR0, EL3, 12, 4)
+FIELD(ID_AA64PFR0, FP, 16, 4)
+FIELD(ID_AA64PFR0, ADVSIMD, 20, 4)
+FIELD(ID_AA64PFR0, GIC, 24, 4)
+FIELD(ID_AA64PFR0, RAS, 28, 4)
+FIELD(ID_AA64PFR0, SVE, 32, 4)
+
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
/* If adding a feature bit which corresponds to a Linux ELF
@@ -1550,7 +1573,6 @@ enum arm_features {
ARM_FEATURE_VFP3,
ARM_FEATURE_VFP_FP16,
ARM_FEATURE_NEON,
- ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
ARM_FEATURE_M, /* Microcontroller profile. */
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
ARM_FEATURE_THUMB2EE,
@@ -1560,7 +1582,6 @@ enum arm_features {
ARM_FEATURE_V5,
ARM_FEATURE_STRONGARM,
ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
- ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
ARM_FEATURE_GENERIC_TIMER,
ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
@@ -1573,30 +1594,15 @@ enum arm_features {
ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
ARM_FEATURE_V8,
ARM_FEATURE_AARCH64, /* supports 64 bit mode */
- ARM_FEATURE_V8_AES, /* implements AES part of v8 Crypto Extensions */
ARM_FEATURE_CBAR, /* has cp15 CBAR */
ARM_FEATURE_CRC, /* ARMv8 CRC instructions */
ARM_FEATURE_CBAR_RO, /* has cp15 CBAR and it is read-only */
ARM_FEATURE_EL2, /* has EL2 Virtualization support */
ARM_FEATURE_EL3, /* has EL3 Secure monitor support */
- ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
ARM_FEATURE_PMU, /* has PMU support */
ARM_FEATURE_VBAR, /* has cp15 VBAR */
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
- ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
- ARM_FEATURE_SVE, /* has Scalable Vector Extension */
- ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
- ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
- ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
- ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
- ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
- ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
};
@@ -3148,4 +3154,157 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
/* Shared between translate-sve.c and sve_helper.c. */
extern const uint64_t pred_esz_masks[4];
+/*
+ * 32-bit feature tests via id registers.
+ */
+static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
+}
+
+static inline bool isar_feature_arm_div(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
+}
+
+static inline bool isar_feature_jazelle(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
+}
+
+static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
+}
+
+static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
+}
+
+static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
+}
+
+static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
+}
+
+static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
+}
+
+static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
+}
+
+static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
+}
+
+static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
+}
+
+static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
+{
+ /*
+ * This is a placeholder for use by VCMA until the rest of
+ * the ARMv8.2-FP16 extension is implemented for aa32 mode.
+ * At which point we can properly set and check MVFR1.FPHP.
+ */
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
+}
+
+/*
+ * 64-bit feature tests via id registers.
+ */
+static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
+}
+
+static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
+}
+
+static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
+}
+
+static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
+}
+
+static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
+}
+
+static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
+}
+
+static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
+}
+
+static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
+}
+
+static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
+}
+
+static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
+}
+
+static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
+}
+
+static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
+}
+
+static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
+}
+
+static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
+{
+ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
+}
+
+static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
+}
+
+/*
+ * Forward to the above feature tests given an ARMCPU pointer.
+ */
+#define cpu_isar_feature(name, cpu) \
+ ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
+
#endif
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 44fdf0f6fa..873f059bf2 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -109,11 +109,6 @@ static void aarch64_a57_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
@@ -121,9 +116,9 @@ static void aarch64_a57_initfn(Object *obj)
cpu->midr = 0x411fd070;
cpu->revidr = 0x00000000;
cpu->reset_fpsid = 0x41034070;
- cpu->mvfr0 = 0x10110222;
- cpu->mvfr1 = 0x12111111;
- cpu->mvfr2 = 0x00000043;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x12111111;
+ cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
cpu->id_pfr0 = 0x00000131;
@@ -134,18 +129,18 @@ static void aarch64_a57_initfn(Object *obj)
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01260000;
cpu->id_mmfr3 = 0x02102211;
- cpu->id_isar0 = 0x02101110;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232042;
- cpu->id_isar3 = 0x01112131;
- cpu->id_isar4 = 0x00011142;
- cpu->id_isar5 = 0x00011121;
- cpu->id_isar6 = 0;
- cpu->id_aa64pfr0 = 0x00002222;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232042;
+ cpu->isar.id_isar3 = 0x01112131;
+ cpu->isar.id_isar4 = 0x00011142;
+ cpu->isar.id_isar5 = 0x00011121;
+ cpu->isar.id_isar6 = 0;
+ cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->id_aa64dfr0 = 0x10305106;
cpu->pmceid0 = 0x00000000;
cpu->pmceid1 = 0x00000000;
- cpu->id_aa64isar0 = 0x00011120;
+ cpu->isar.id_aa64isar0 = 0x00011120;
cpu->id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
@@ -170,11 +165,6 @@ static void aarch64_a53_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
@@ -182,9 +172,9 @@ static void aarch64_a53_initfn(Object *obj)
cpu->midr = 0x410fd034;
cpu->revidr = 0x00000000;
cpu->reset_fpsid = 0x41034070;
- cpu->mvfr0 = 0x10110222;
- cpu->mvfr1 = 0x12111111;
- cpu->mvfr2 = 0x00000043;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x12111111;
+ cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x84448004; /* L1Ip = VIPT */
cpu->reset_sctlr = 0x00c50838;
cpu->id_pfr0 = 0x00000131;
@@ -195,16 +185,16 @@ static void aarch64_a53_initfn(Object *obj)
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01260000;
cpu->id_mmfr3 = 0x02102211;
- cpu->id_isar0 = 0x02101110;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232042;
- cpu->id_isar3 = 0x01112131;
- cpu->id_isar4 = 0x00011142;
- cpu->id_isar5 = 0x00011121;
- cpu->id_isar6 = 0;
- cpu->id_aa64pfr0 = 0x00002222;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232042;
+ cpu->isar.id_isar3 = 0x01112131;
+ cpu->isar.id_isar4 = 0x00011142;
+ cpu->isar.id_isar5 = 0x00011121;
+ cpu->isar.id_isar6 = 0;
+ cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->id_aa64dfr0 = 0x10305106;
- cpu->id_aa64isar0 = 0x00011120;
+ cpu->isar.id_aa64isar0 = 0x00011120;
cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
@@ -229,20 +219,15 @@ static void aarch64_a72_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
- set_feature(&cpu->env, ARM_FEATURE_CRC);
set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->midr = 0x410fd083;
cpu->revidr = 0x00000000;
cpu->reset_fpsid = 0x41034080;
- cpu->mvfr0 = 0x10110222;
- cpu->mvfr1 = 0x12111111;
- cpu->mvfr2 = 0x00000043;
+ cpu->isar.mvfr0 = 0x10110222;
+ cpu->isar.mvfr1 = 0x12111111;
+ cpu->isar.mvfr2 = 0x00000043;
cpu->ctr = 0x8444c004;
cpu->reset_sctlr = 0x00c50838;
cpu->id_pfr0 = 0x00000131;
@@ -253,17 +238,17 @@ static void aarch64_a72_initfn(Object *obj)
cpu->id_mmfr1 = 0x40000000;
cpu->id_mmfr2 = 0x01260000;
cpu->id_mmfr3 = 0x02102211;
- cpu->id_isar0 = 0x02101110;
- cpu->id_isar1 = 0x13112111;
- cpu->id_isar2 = 0x21232042;
- cpu->id_isar3 = 0x01112131;
- cpu->id_isar4 = 0x00011142;
- cpu->id_isar5 = 0x00011121;
- cpu->id_aa64pfr0 = 0x00002222;
+ cpu->isar.id_isar0 = 0x02101110;
+ cpu->isar.id_isar1 = 0x13112111;
+ cpu->isar.id_isar2 = 0x21232042;
+ cpu->isar.id_isar3 = 0x01112131;
+ cpu->isar.id_isar4 = 0x00011142;
+ cpu->isar.id_isar5 = 0x00011121;
+ cpu->isar.id_aa64pfr0 = 0x00002222;
cpu->id_aa64dfr0 = 0x10305106;
cpu->pmceid0 = 0x00000000;
cpu->pmceid1 = 0x00000000;
- cpu->id_aa64isar0 = 0x00011120;
+ cpu->isar.id_aa64isar0 = 0x00011120;
cpu->id_aa64mmfr0 = 0x00001124;
cpu->dbgdidr = 0x3516d000;
cpu->clidr = 0x0a200023;
@@ -312,24 +297,55 @@ static void aarch64_max_initfn(Object *obj)
if (kvm_enabled()) {
kvm_arm_set_cpu_features_from_host(cpu);
} else {
+ uint64_t t;
+ uint32_t u;
aarch64_a57_initfn(obj);
-#ifdef CONFIG_USER_ONLY
- /* We don't set these in system emulation mode for the moment,
- * since we don't correctly set the ID registers to advertise them,
- * and in some cases they're only available in AArch64 and not AArch32,
- * whereas the architecture requires them to be present in both if
- * present in either.
+
+ t = cpu->isar.id_aa64isar0;
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
+ t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
+ cpu->isar.id_aa64isar0 = t;
+
+ t = cpu->isar.id_aa64isar1;
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
+ cpu->isar.id_aa64isar1 = t;
+
+ t = cpu->isar.id_aa64pfr0;
+ t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
+ cpu->isar.id_aa64pfr0 = t;
+
+ /* Replicate the same data to the 32-bit id registers. */
+ u = cpu->isar.id_isar5;
+ u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
+ u = FIELD_DP32(u, ID_ISAR5, SHA1, 1);
+ u = FIELD_DP32(u, ID_ISAR5, SHA2, 1);
+ u = FIELD_DP32(u, ID_ISAR5, CRC32, 1);
+ u = FIELD_DP32(u, ID_ISAR5, RDM, 1);
+ u = FIELD_DP32(u, ID_ISAR5, VCMA, 1);
+ cpu->isar.id_isar5 = u;
+
+ u = cpu->isar.id_isar6;
+ u = FIELD_DP32(u, ID_ISAR6, DP, 1);
+ cpu->isar.id_isar6 = u;
+
+ /*
+ * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
+ * so do not set MVFR1.FPHP. Strictly speaking this is not legal,
+ * but it is also not legal to enable SVE without support for FP16,
+ * and enabling SVE in system mode is more useful in the short term.
*/
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
- set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
- set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
- set_feature(&cpu->env, ARM_FEATURE_SVE);
+
+#ifdef CONFIG_USER_ONLY
/* For usermode -cpu max we can use a larger and more efficient DCZ
* blocksize since we don't have to follow what the hardware does.
*/
diff --git a/target/arm/helper.c b/target/arm/helper.c
index e3946562aa..0ea95b0815 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -56,6 +56,8 @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
V8M_SAttributes *sattrs);
#endif
+static void switch_mode(CPUARMState *env, int mode);
+
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
{
int nregs;
@@ -552,12 +554,61 @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
raw_write(env, ri, value);
}
+/* IS variants of TLB operations must affect all cores */
+static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_all_cpus_synced(cs);
+}
+
+static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_all_cpus_synced(cs);
+}
+
+static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
+}
+
+static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
+}
+
+/*
+ * Non-IS variants of TLB operations are upgraded to
+ * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
+ * force broadcast of these operations.
+ */
+static bool tlb_force_broadcast(CPUARMState *env)
+{
+ return (env->cp15.hcr_el2 & HCR_FB) &&
+ arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
+}
+
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
/* Invalidate all (TLBIALL) */
ARMCPU *cpu = arm_env_get_cpu(env);
+ if (tlb_force_broadcast(env)) {
+ tlbiall_is_write(env, NULL, value);
+ return;
+ }
+
tlb_flush(CPU(cpu));
}
@@ -567,6 +618,11 @@ static void tlbimva_write(CPUARMState *env, const ARMCPRegInfo *ri,
/* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
ARMCPU *cpu = arm_env_get_cpu(env);
+ if (tlb_force_broadcast(env)) {
+ tlbimva_is_write(env, NULL, value);
+ return;
+ }
+
tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
}
@@ -576,6 +632,11 @@ static void tlbiasid_write(CPUARMState *env, const ARMCPRegInfo *ri,
/* Invalidate by ASID (TLBIASID) */
ARMCPU *cpu = arm_env_get_cpu(env);
+ if (tlb_force_broadcast(env)) {
+ tlbiasid_is_write(env, NULL, value);
+ return;
+ }
+
tlb_flush(CPU(cpu));
}
@@ -585,40 +646,12 @@ static void tlbimvaa_write(CPUARMState *env, const ARMCPRegInfo *ri,
/* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
ARMCPU *cpu = arm_env_get_cpu(env);
- tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
-}
-
-/* IS variants of TLB operations must affect all cores */
-static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- CPUState *cs = ENV_GET_CPU(env);
-
- tlb_flush_all_cpus_synced(cs);
-}
-
-static void tlbiasid_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- CPUState *cs = ENV_GET_CPU(env);
-
- tlb_flush_all_cpus_synced(cs);
-}
-
-static void tlbimva_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- CPUState *cs = ENV_GET_CPU(env);
-
- tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
-}
-
-static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- CPUState *cs = ENV_GET_CPU(env);
+ if (tlb_force_broadcast(env)) {
+ tlbimvaa_is_write(env, NULL, value);
+ return;
+ }
- tlb_flush_page_all_cpus_synced(cs, value & TARGET_PAGE_MASK);
+ tlb_flush_page(CPU(cpu), value & TARGET_PAGE_MASK);
}
static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1296,12 +1329,26 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
CPUState *cs = ENV_GET_CPU(env);
uint64_t ret = 0;
- if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
- ret |= CPSR_I;
+ if (arm_hcr_el2_imo(env)) {
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
+ ret |= CPSR_I;
+ }
+ } else {
+ if (cs->interrupt_request & CPU_INTERRUPT_HARD) {
+ ret |= CPSR_I;
+ }
}
- if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
- ret |= CPSR_F;
+
+ if (arm_hcr_el2_fmo(env)) {
+ if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
+ ret |= CPSR_F;
+ }
+ } else {
+ if (cs->interrupt_request & CPU_INTERRUPT_FIQ) {
+ ret |= CPSR_F;
+ }
}
+
/* External aborts are not possible in QEMU so A bit is always clear */
return ret;
}
@@ -2270,13 +2317,15 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
* * The Non-secure TTBCR.EAE bit is set to 1
* * The implementation includes EL2, and the value of HCR.VM is 1
*
+ * (Note that HCR.DC makes HCR.VM behave as if it is 1.)
+ *
* ATS1Hx always uses the 64bit format (not supported yet).
*/
format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
if (arm_feature(env, ARM_FEATURE_EL2)) {
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
- format64 |= env->cp15.hcr_el2 & HCR_VM;
+ format64 |= env->cp15.hcr_el2 & (HCR_VM | HCR_DC);
} else {
format64 |= arm_current_el(env) == 2;
}
@@ -2709,12 +2758,10 @@ static void vmsa_tcr_el1_write(CPUARMState *env, const ARMCPRegInfo *ri,
static void vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
- /* 64 bit accesses to the TTBRs can change the ASID and so we
- * must flush the TLB.
- */
- if (cpreg_field_is_64bit(ri)) {
+ /* If the ASID changes (with a 64-bit write), we must flush the TLB. */
+ if (cpreg_field_is_64bit(ri) &&
+ extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
ARMCPU *cpu = arm_env_get_cpu(env);
-
tlb_flush(CPU(cpu));
}
raw_write(env, ri, value);
@@ -3083,22 +3130,6 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
* Page D4-1736 (DDI0487A.b)
*/
-static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- CPUState *cs = ENV_GET_CPU(env);
-
- if (arm_is_secure_below_el3(env)) {
- tlb_flush_by_mmuidx(cs,
- ARMMMUIdxBit_S1SE1 |
- ARMMMUIdxBit_S1SE0);
- } else {
- tlb_flush_by_mmuidx(cs,
- ARMMMUIdxBit_S12NSE1 |
- ARMMMUIdxBit_S12NSE0);
- }
-}
-
static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -3116,6 +3147,27 @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
+static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ CPUState *cs = ENV_GET_CPU(env);
+
+ if (tlb_force_broadcast(env)) {
+ tlbi_aa64_vmalle1_write(env, NULL, value);
+ return;
+ }
+
+ if (arm_is_secure_below_el3(env)) {
+ tlb_flush_by_mmuidx(cs,
+ ARMMMUIdxBit_S1SE1 |
+ ARMMMUIdxBit_S1SE0);
+ } else {
+ tlb_flush_by_mmuidx(cs,
+ ARMMMUIdxBit_S12NSE1 |
+ ARMMMUIdxBit_S12NSE0);
+ }
+}
+
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -3205,29 +3257,6 @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
}
-static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /* Invalidate by VA, EL1&0 (AArch64 version).
- * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
- * since we don't support flush-for-specific-ASID-only or
- * flush-last-level-only.
- */
- ARMCPU *cpu = arm_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
- uint64_t pageaddr = sextract64(value << 12, 0, 56);
-
- if (arm_is_secure_below_el3(env)) {
- tlb_flush_page_by_mmuidx(cs, pageaddr,
- ARMMMUIdxBit_S1SE1 |
- ARMMMUIdxBit_S1SE0);
- } else {
- tlb_flush_page_by_mmuidx(cs, pageaddr,
- ARMMMUIdxBit_S12NSE1 |
- ARMMMUIdxBit_S12NSE0);
- }
-}
-
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -3275,6 +3304,34 @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
}
}
+static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /* Invalidate by VA, EL1&0 (AArch64 version).
+ * Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
+ * since we don't support flush-for-specific-ASID-only or
+ * flush-last-level-only.
+ */
+ ARMCPU *cpu = arm_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
+ uint64_t pageaddr = sextract64(value << 12, 0, 56);
+
+ if (tlb_force_broadcast(env)) {
+ tlbi_aa64_vae1is_write(env, NULL, value);
+ return;
+ }
+
+ if (arm_is_secure_below_el3(env)) {
+ tlb_flush_page_by_mmuidx(cs, pageaddr,
+ ARMMMUIdxBit_S1SE1 |
+ ARMMMUIdxBit_S1SE0);
+ } else {
+ tlb_flush_page_by_mmuidx(cs, pageaddr,
+ ARMMMUIdxBit_S12NSE1 |
+ ARMMMUIdxBit_S12NSE0);
+ }
+}
+
static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
@@ -3872,6 +3929,7 @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
{
ARMCPU *cpu = arm_env_get_cpu(env);
+ CPUState *cs = ENV_GET_CPU(env);
uint64_t valid_mask = HCR_MASK;
if (arm_feature(env, ARM_FEATURE_EL3)) {
@@ -3890,6 +3948,28 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
/* Clear RES0 bits. */
value &= valid_mask;
+ /*
+ * VI and VF are kept in cs->interrupt_request. Modifying that
+ * requires that we have the iothread lock, which is done by
+ * marking the reginfo structs as ARM_CP_IO.
+ * Note that if a write to HCR pends a VIRQ or VFIQ it is never
+ * possible for it to be taken immediately, because VIRQ and
+ * VFIQ are masked unless running at EL0 or EL1, and HCR
+ * can only be written at EL2.
+ */
+ g_assert(qemu_mutex_iothread_locked());
+ if (value & HCR_VI) {
+ cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
+ } else {
+ cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+ }
+ if (value & HCR_VF) {
+ cs->interrupt_request |= CPU_INTERRUPT_VFIQ;
+ } else {
+ cs->interrupt_request &= ~CPU_INTERRUPT_VFIQ;
+ }
+ value &= ~(HCR_VI | HCR_VF);
+
/* These bits change the MMU setup:
* HCR_VM enables stage 2 translation
* HCR_PTW forbids certain page-table setups
@@ -3917,16 +3997,32 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
hcr_write(env, NULL, value);
}
+static uint64_t hcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+ /* The VI and VF bits live in cs->interrupt_request */
+ uint64_t ret = env->cp15.hcr_el2 & ~(HCR_VI | HCR_VF);
+ CPUState *cs = ENV_GET_CPU(env);
+
+ if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
+ ret |= HCR_VI;
+ }
+ if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
+ ret |= HCR_VF;
+ }
+ return ret;
+}
+
static const ARMCPRegInfo el2_cp_reginfo[] = {
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_IO,
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
- .writefn = hcr_write },
+ .writefn = hcr_write, .readfn = hcr_read },
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
- .type = ARM_CP_ALIAS,
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
- .writefn = hcr_writelow },
+ .writefn = hcr_writelow, .readfn = hcr_read },
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
@@ -4163,7 +4259,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
{ .name = "HCR2", .state = ARM_CP_STATE_AA32,
- .type = ARM_CP_ALIAS,
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
.access = PL2_RW,
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
@@ -4214,7 +4310,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
.fieldoffset = offsetof(CPUARMState, cp15.mvbar) },
{ .name = "TTBR0_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 0,
- .access = PL3_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
+ .access = PL3_RW, .resetvalue = 0,
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[3]) },
{ .name = "TCR_EL3", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 6, .crn = 2, .crm = 0, .opc2 = 2,
@@ -4873,7 +4969,7 @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
{
ARMCPU *cpu = arm_env_get_cpu(env);
- uint64_t pfr0 = cpu->id_aa64pfr0;
+ uint64_t pfr0 = cpu->isar.id_aa64pfr0;
if (env->gicv3state) {
pfr0 |= 1 << 24;
@@ -4940,27 +5036,27 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar0 },
+ .resetvalue = cpu->isar.id_isar0 },
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar1 },
+ .resetvalue = cpu->isar.id_isar1 },
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar2 },
+ .resetvalue = cpu->isar.id_isar2 },
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar3 },
+ .resetvalue = cpu->isar.id_isar3 },
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar4 },
+ .resetvalue = cpu->isar.id_isar4 },
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar5 },
+ .resetvalue = cpu->isar.id_isar5 },
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -4968,7 +5064,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_isar6 },
+ .resetvalue = cpu->isar.id_isar6 },
REGINFO_SENTINEL
};
define_arm_cp_regs(cpu, v6_idregs);
@@ -5039,7 +5135,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_aa64pfr1},
+ .resetvalue = cpu->isar.id_aa64pfr1},
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -5100,11 +5196,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_aa64isar0 },
+ .resetvalue = cpu->isar.id_aa64isar0 },
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->id_aa64isar1 },
+ .resetvalue = cpu->isar.id_aa64isar1 },
{ .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -5164,15 +5260,15 @@ void register_cp_regs_for_features(ARMCPU *cpu)
{ .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->mvfr0 },
+ .resetvalue = cpu->isar.mvfr0 },
{ .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->mvfr1 },
+ .resetvalue = cpu->isar.mvfr1 },
{ .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
.access = PL1_R, .type = ARM_CP_CONST,
- .resetvalue = cpu->mvfr2 },
+ .resetvalue = cpu->isar.mvfr2 },
{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
.access = PL1_R, .type = ARM_CP_CONST,
@@ -5618,7 +5714,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_one_arm_cp_reg(cpu, &sctlr);
}
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (cpu_isar_feature(aa64_sve, cpu)) {
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
if (arm_feature(env, ARM_FEATURE_EL2)) {
define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
@@ -6208,7 +6304,17 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
mask |= CPSR_IL;
val |= CPSR_IL;
}
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Illegal AArch32 mode switch attempt from %s to %s\n",
+ aarch32_mode_name(env->uncached_cpsr),
+ aarch32_mode_name(val));
} else {
+ qemu_log_mask(CPU_LOG_INT, "%s %s to %s PC 0x%" PRIx32 "\n",
+ write_type == CPSRWriteExceptionReturn ?
+ "Exception return from AArch32" :
+ "AArch32 mode switch from",
+ aarch32_mode_name(env->uncached_cpsr),
+ aarch32_mode_name(val), env->regs[15]);
switch_mode(env, val & CPSR_M);
}
}
@@ -6306,7 +6412,7 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
return 0;
}
-void switch_mode(CPUARMState *env, int mode)
+static void switch_mode(CPUARMState *env, int mode)
{
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -6328,7 +6434,7 @@ void aarch64_sync_64_to_32(CPUARMState *env)
#else
-void switch_mode(CPUARMState *env, int mode)
+static void switch_mode(CPUARMState *env, int mode)
{
int old_mode;
int i;
@@ -8194,6 +8300,19 @@ static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
}
if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
+ if (!arm_feature(env, ARM_FEATURE_V8)) {
+ /*
+ * QEMU syndrome values are v8-style. v7 has the IL bit
+ * UNK/SBZP for "field not valid" cases, where v8 uses RES1.
+ * If this is a v7 CPU, squash the IL bit in those cases.
+ */
+ if (cs->exception_index == EXCP_PREFETCH_ABORT ||
+ (cs->exception_index == EXCP_DATA_ABORT &&
+ !(env->exception.syndrome & ARM_EL_ISV)) ||
+ syn_get_ec(env->exception.syndrome) == EC_UNCATEGORIZED) {
+ env->exception.syndrome &= ~ARM_EL_IL;
+ }
+ }
env->cp15.esr_el[2] = env->exception.syndrome;
}
@@ -8228,7 +8347,7 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
uint32_t moe;
/* If this is a debug exception we must update the DBGDSCR.MOE bits */
- switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) {
+ switch (syn_get_ec(env->exception.syndrome)) {
case EC_BREAKPOINT:
case EC_BREAKPOINT_SAME_EL:
moe = 1;
@@ -8425,6 +8544,15 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
case EXCP_HVC:
case EXCP_HYP_TRAP:
case EXCP_SMC:
+ if (syn_get_ec(env->exception.syndrome) == EC_ADVSIMDFPACCESSTRAP) {
+ /*
+ * QEMU internal FP/SIMD syndromes from AArch32 include the
+ * TA and coproc fields which are only exposed if the exception
+ * is taken to AArch32 Hyp mode. Mask them out to get a valid
+ * AArch64 format syndrome.
+ */
+ env->exception.syndrome &= ~MAKE_64BIT_MASK(0, 20);
+ }
env->cp15.esr_el[new_el] = env->exception.syndrome;
break;
case EXCP_IRQ:
@@ -8568,7 +8696,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
if (qemu_loglevel_mask(CPU_LOG_INT)
&& !excp_is_internal(cs->exception_index)) {
qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
- env->exception.syndrome >> ARM_EL_EC_SHIFT,
+ syn_get_ec(env->exception.syndrome),
env->exception.syndrome);
}
@@ -8665,7 +8793,8 @@ static inline bool regime_translation_disabled(CPUARMState *env,
}
if (mmu_idx == ARMMMUIdx_S2NS) {
- return (env->cp15.hcr_el2 & HCR_VM) == 0;
+ /* HCR.DC means HCR.VM behaves as 1 */
+ return (env->cp15.hcr_el2 & (HCR_DC | HCR_VM)) == 0;
}
if (env->cp15.hcr_el2 & HCR_TGE) {
@@ -8675,6 +8804,12 @@ static inline bool regime_translation_disabled(CPUARMState *env,
}
}
+ if ((env->cp15.hcr_el2 & HCR_DC) &&
+ (mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1)) {
+ /* HCR.DC means SCTLR_EL1.M behaves as 0 */
+ return true;
+ }
+
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
}
@@ -9026,9 +9161,20 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
hwaddr s2pa;
int s2prot;
int ret;
+ ARMCacheAttrs cacheattrs = {};
+ ARMCacheAttrs *pcacheattrs = NULL;
+
+ if (env->cp15.hcr_el2 & HCR_PTW) {
+ /*
+ * PTW means we must fault if this S1 walk touches S2 Device
+ * memory; otherwise we don't care about the attributes and can
+ * save the S2 translation the effort of computing them.
+ */
+ pcacheattrs = &cacheattrs;
+ }
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
- &txattrs, &s2prot, &s2size, fi, NULL);
+ &txattrs, &s2prot, &s2size, fi, pcacheattrs);
if (ret) {
assert(fi->type != ARMFault_None);
fi->s2addr = addr;
@@ -9036,6 +9182,14 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
fi->s1ptw = true;
return ~0;
}
+ if (pcacheattrs && (pcacheattrs->attrs & 0xf0) == 0) {
+ /* Access was to Device memory: generate Permission fault */
+ fi->type = ARMFault_Permission;
+ fi->s2addr = addr;
+ fi->stage2 = true;
+ fi->s1ptw = true;
+ return ~0;
+ }
addr = s2pa;
}
return addr;
@@ -10655,6 +10809,16 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
/* Combine the S1 and S2 cache attributes, if needed */
if (!ret && cacheattrs != NULL) {
+ if (env->cp15.hcr_el2 & HCR_DC) {
+ /*
+ * HCR.DC forces the first stage attributes to
+ * Normal Non-Shareable,
+ * Inner Write-Back Read-Allocate Write-Allocate,
+ * Outer Write-Back Read-Allocate Write-Allocate.
+ */
+ cacheattrs->attrs = 0xff;
+ cacheattrs->shareability = 0;
+ }
*cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
}
@@ -11612,7 +11776,7 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
uint32_t changed;
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
- if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
+ if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
val &= ~FPCR_FZ16;
}
@@ -12671,13 +12835,15 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
uint32_t flags;
if (is_a64(env)) {
+ ARMCPU *cpu = arm_env_get_cpu(env);
+
*pc = env->pc;
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
/* Get control bits for tagged addresses */
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
- if (arm_feature(env, ARM_FEATURE_SVE)) {
+ if (cpu_isar_feature(aa64_sve, cpu)) {
int sve_el = sve_exception_el(env, current_el);
uint32_t zcr_len;
@@ -12801,11 +12967,12 @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
void aarch64_sve_change_el(CPUARMState *env, int old_el,
int new_el, bool el0_a64)
{
+ ARMCPU *cpu = arm_env_get_cpu(env);
int old_len, new_len;
bool old_a64, new_a64;
/* Nothing to do if no SVE. */
- if (!arm_feature(env, ARM_FEATURE_SVE)) {
+ if (!cpu_isar_feature(aa64_sve, cpu)) {
return;
}
diff --git a/target/arm/internals.h b/target/arm/internals.h
index a4fc709bcc..6c2bb2deeb 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -145,7 +145,6 @@ static inline int bank_number(int mode)
g_assert_not_reached();
}
-void switch_mode(CPUARMState *, int);
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
void arm_translate_init(void);
@@ -279,14 +278,19 @@ enum arm_exception_class {
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
+static inline uint32_t syn_get_ec(uint32_t syn)
+{
+ return syn >> ARM_EL_EC_SHIFT;
+}
+
/* Utility functions for constructing various kinds of syndrome value.
* Note that in general we follow the AArch64 syndrome values; in a
* few cases the value in HSR for exceptions taken to AArch32 Hyp
- * mode differs slightly, so if we ever implemented Hyp mode then the
- * syndrome value would need some massaging on exception entry.
- * (One example of this is that AArch64 defaults to IL bit set for
- * exceptions which don't specifically indicate information about the
- * trapping instruction, whereas AArch32 defaults to IL bit clear.)
+ * mode differs slightly, and we fix this up when populating HSR in
+ * arm_cpu_do_interrupt_aarch32_hyp().
+ * The exception is FP/SIMD access traps -- these report extra information
+ * when taking an exception to AArch32. For those we include the extra coproc
+ * and TA fields, and mask them out when taking the exception to AArch64.
*/
static inline uint32_t syn_uncategorized(void)
{
@@ -386,9 +390,18 @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit)
{
+ /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 coproc == 0xa */
+ return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
+ | (is_16bit ? 0 : ARM_EL_IL)
+ | (cv << 24) | (cond << 20) | 0xa;
+}
+
+static inline uint32_t syn_simd_access_trap(int cv, int cond, bool is_16bit)
+{
+ /* AArch32 SIMD trap: TA == 1 coproc == 0 */
return (EC_ADVSIMDFPACCESSTRAP << ARM_EL_EC_SHIFT)
| (is_16bit ? 0 : ARM_EL_IL)
- | (cv << 24) | (cond << 20);
+ | (cv << 24) | (cond << 20) | (1 << 5);
}
static inline uint32_t syn_sve_access_trap(void)
@@ -840,4 +853,22 @@ static inline uint32_t v7m_sp_limit(CPUARMState *env)
}
}
+/**
+ * aarch32_mode_name(): Return name of the AArch32 CPU mode
+ * @psr: Program Status Register indicating CPU mode
+ *
+ * Returns, for debug logging purposes, a printable representation
+ * of the AArch32 CPU mode ("svc", "usr", etc) as indicated by
+ * the low bits of the specified PSR.
+ */
+static inline const char *aarch32_mode_name(uint32_t psr)
+{
+ static const char cpu_mode_names[16][4] = {
+ "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
+ "???", "???", "hyp", "und", "???", "???", "???", "sys"
+ };
+
+ return cpu_mode_names[psr & 0xf];
+}
+
#endif
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 54ef5f711b..09a86e2820 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -34,6 +34,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
};
static bool cap_has_mp_state;
+static bool cap_has_inject_serror_esr;
static ARMHostCPUFeatures arm_host_cpu_features;
@@ -48,6 +49,12 @@ int kvm_arm_vcpu_init(CPUState *cs)
return kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
}
+void kvm_arm_init_serror_injection(CPUState *cs)
+{
+ cap_has_inject_serror_esr = kvm_check_extension(cs->kvm_state,
+ KVM_CAP_ARM_INJECT_SERROR_ESR);
+}
+
bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
int *fdarray,
struct kvm_vcpu_init *init)
@@ -522,6 +529,59 @@ int kvm_arm_sync_mpstate_to_qemu(ARMCPU *cpu)
return 0;
}
+int kvm_put_vcpu_events(ARMCPU *cpu)
+{
+ CPUARMState *env = &cpu->env;
+ struct kvm_vcpu_events events;
+ int ret;
+
+ if (!kvm_has_vcpu_events()) {
+ return 0;
+ }
+
+ memset(&events, 0, sizeof(events));
+ events.exception.serror_pending = env->serror.pending;
+
+ /* Inject SError to guest with specified syndrome if host kernel
+ * supports it, otherwise inject SError without syndrome.
+ */
+ if (cap_has_inject_serror_esr) {
+ events.exception.serror_has_esr = env->serror.has_esr;
+ events.exception.serror_esr = env->serror.esr;
+ }
+
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events);
+ if (ret) {
+ error_report("failed to put vcpu events");
+ }
+
+ return ret;
+}
+
+int kvm_get_vcpu_events(ARMCPU *cpu)
+{
+ CPUARMState *env = &cpu->env;
+ struct kvm_vcpu_events events;
+ int ret;
+
+ if (!kvm_has_vcpu_events()) {
+ return 0;
+ }
+
+ memset(&events, 0, sizeof(events));
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_VCPU_EVENTS, &events);
+ if (ret) {
+ error_report("failed to get vcpu events");
+ return ret;
+ }
+
+ env->serror.pending = events.exception.serror_pending;
+ env->serror.has_esr = events.exception.serror_has_esr;
+ env->serror.esr = events.exception.serror_esr;
+
+ return 0;
+}
+
void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
{
}
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
index 4e91c11796..0f1e94c7b5 100644
--- a/target/arm/kvm32.c
+++ b/target/arm/kvm32.c
@@ -217,6 +217,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
cpu->mp_affinity = mpidr & ARM32_AFFINITY_MASK;
+ /* Check whether userspace can specify guest syndrome value */
+ kvm_arm_init_serror_injection(cs);
+
return kvm_arm_init_cpreg_list(cpu);
}
@@ -358,6 +361,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
+ ret = kvm_put_vcpu_events(cpu);
+ if (ret) {
+ return ret;
+ }
+
/* Note that we do not call write_cpustate_to_list()
* here, so we are only writing the tuple list back to
* KVM. This is safe because nothing can change the
@@ -445,6 +453,11 @@ int kvm_arch_get_registers(CPUState *cs)
}
vfp_set_fpscr(env, fpscr);
+ ret = kvm_get_vcpu_events(cpu);
+ if (ret) {
+ return ret;
+ }
+
if (!write_kvmstate_to_list(cpu)) {
return EINVAL;
}
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index e0b8246283..5de8ff0ac5 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -546,6 +546,9 @@ int kvm_arch_init_vcpu(CPUState *cs)
kvm_arm_init_debug(cs);
+ /* Check whether user space can specify guest syndrome value */
+ kvm_arm_init_serror_injection(cs);
+
return kvm_arm_init_cpreg_list(cpu);
}
@@ -727,6 +730,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
return ret;
}
+ ret = kvm_put_vcpu_events(cpu);
+ if (ret) {
+ return ret;
+ }
+
if (!write_list_to_kvmstate(cpu, level)) {
return EINVAL;
}
@@ -863,6 +871,11 @@ int kvm_arch_get_registers(CPUState *cs)
}
vfp_set_fpcr(env, fpr);
+ ret = kvm_get_vcpu_events(cpu);
+ if (ret) {
+ return ret;
+ }
+
if (!write_kvmstate_to_list(cpu)) {
return EINVAL;
}
@@ -920,7 +933,7 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
{
- int hsr_ec = debug_exit->hsr >> ARM_EL_EC_SHIFT;
+ int hsr_ec = syn_get_ec(debug_exit->hsr);
ARMCPU *cpu = ARM_CPU(cs);
CPUClass *cc = CPU_GET_CLASS(cs);
CPUARMState *env = &cpu->env;
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 5948e8b560..21c0129da2 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -121,6 +121,30 @@ bool write_kvmstate_to_list(ARMCPU *cpu);
*/
void kvm_arm_reset_vcpu(ARMCPU *cpu);
+/**
+ * kvm_arm_init_serror_injection:
+ * @cs: CPUState
+ *
+ * Check whether KVM can set guest SError syndrome.
+ */
+void kvm_arm_init_serror_injection(CPUState *cs);
+
+/**
+ * kvm_get_vcpu_events:
+ * @cpu: ARMCPU
+ *
+ * Get VCPU related state from kvm.
+ */
+int kvm_get_vcpu_events(ARMCPU *cpu);
+
+/**
+ * kvm_put_vcpu_events:
+ * @cpu: ARMCPU
+ *
+ * Put VCPU related state to kvm.
+ */
+int kvm_put_vcpu_events(ARMCPU *cpu);
+
#ifdef CONFIG_KVM
/**
* kvm_arm_create_scratch_host_vcpu:
diff --git a/target/arm/machine.c b/target/arm/machine.c
index ff4ec22bf7..239fe4e84d 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -131,9 +131,8 @@ static const VMStateDescription vmstate_iwmmxt = {
static bool sve_needed(void *opaque)
{
ARMCPU *cpu = opaque;
- CPUARMState *env = &cpu->env;
- return arm_feature(env, ARM_FEATURE_SVE);
+ return cpu_isar_feature(aa64_sve, cpu);
}
/* The first two words of each Zreg is stored in VFP state. */
@@ -172,6 +171,27 @@ static const VMStateDescription vmstate_sve = {
};
#endif /* AARCH64 */
+static bool serror_needed(void *opaque)
+{
+ ARMCPU *cpu = opaque;
+ CPUARMState *env = &cpu->env;
+
+ return env->serror.pending != 0;
+}
+
+static const VMStateDescription vmstate_serror = {
+ .name = "cpu/serror",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = serror_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(env.serror.pending, ARMCPU),
+ VMSTATE_UINT8(env.serror.has_esr, ARMCPU),
+ VMSTATE_UINT64(env.serror.esr, ARMCPU),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static bool m_needed(void *opaque)
{
ARMCPU *cpu = opaque;
@@ -726,6 +746,7 @@ const VMStateDescription vmstate_arm_cpu = {
#ifdef TARGET_AARCH64
&vmstate_sve,
#endif
+ &vmstate_serror,
NULL
}
};
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index d915579712..90741f6331 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -42,7 +42,7 @@ void raise_exception(CPUARMState *env, uint32_t excp,
* (see DDI0478C.a D1.10.4)
*/
target_el = 2;
- if (syndrome >> ARM_EL_EC_SHIFT == EC_ADVSIMDFPACCESSTRAP) {
+ if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
syndrome = syn_uncategorized();
}
}
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bb9c4d8ac7..88195ab949 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -174,7 +174,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
vfp_get_fpcr(env), vfp_get_fpsr(env));
- if (arm_feature(env, ARM_FEATURE_SVE) && sve_exception_el(env, el) == 0) {
+ if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
int j, zcr_len = sve_zcr_len_for_el(env, el);
for (i = 0; i <= FFR_PRED_NUM; i++) {
@@ -1201,25 +1201,23 @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
/* Store from vector register to memory */
static void do_vec_st(DisasContext *s, int srcidx, int element,
- TCGv_i64 tcg_addr, int size)
+ TCGv_i64 tcg_addr, int size, TCGMemOp endian)
{
- TCGMemOp memop = s->be_data + size;
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
read_vec_element(s, tcg_tmp, srcidx, element, size);
- tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
+ tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
tcg_temp_free_i64(tcg_tmp);
}
/* Load from memory to vector register */
static void do_vec_ld(DisasContext *s, int destidx, int element,
- TCGv_i64 tcg_addr, int size)
+ TCGv_i64 tcg_addr, int size, TCGMemOp endian)
{
- TCGMemOp memop = s->be_data + size;
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
write_vec_element(s, tcg_tmp, destidx, element, size);
tcg_temp_free_i64(tcg_tmp);
@@ -2328,7 +2326,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
}
if (rt2 == 31
&& ((rt | rs) & 1) == 0
- && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
+ && dc_isar_feature(aa64_atomics, s)) {
/* CASP / CASPL */
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
return;
@@ -2350,7 +2348,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
}
if (rt2 == 31
&& ((rt | rs) & 1) == 0
- && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
+ && dc_isar_feature(aa64_atomics, s)) {
/* CASPA / CASPAL */
gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
return;
@@ -2361,7 +2359,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
case 0xb: /* CASL */
case 0xe: /* CASA */
case 0xf: /* CASAL */
- if (rt2 == 31 && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
+ if (rt2 == 31 && dc_isar_feature(aa64_atomics, s)) {
gen_compare_and_swap(s, rs, rt, rn, size);
return;
}
@@ -2900,11 +2898,10 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
int rs = extract32(insn, 16, 5);
int rn = extract32(insn, 5, 5);
int o3_opc = extract32(insn, 12, 4);
- int feature = ARM_FEATURE_V8_ATOMICS;
TCGv_i64 tcg_rn, tcg_rs;
AtomicThreeOpFn *fn;
- if (is_vector) {
+ if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
unallocated_encoding(s);
return;
}
@@ -2940,10 +2937,6 @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
unallocated_encoding(s);
return;
}
- if (!arm_dc_feature(s, feature)) {
- unallocated_encoding(s);
- return;
- }
if (rn == 31) {
gen_check_sp_alignment(s);
@@ -3023,10 +3016,11 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
bool is_store = !extract32(insn, 22, 1);
bool is_postidx = extract32(insn, 23, 1);
bool is_q = extract32(insn, 30, 1);
- TCGv_i64 tcg_addr, tcg_rn;
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
+ TCGMemOp endian = s->be_data;
- int ebytes = 1 << size;
- int elements = (is_q ? 128 : 64) / (8 << size);
+ int ebytes; /* bytes per element */
+ int elements; /* elements per vector */
int rpt; /* num iterations */
int selem; /* structure elements */
int r;
@@ -3085,39 +3079,55 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
gen_check_sp_alignment(s);
}
+ /* For our purposes, bytes are always little-endian. */
+ if (size == 0) {
+ endian = MO_LE;
+ }
+
+ /* Consecutive little-endian elements from a single register
+ * can be promoted to a larger little-endian operation.
+ */
+ if (selem == 1 && endian == MO_LE) {
+ size = 3;
+ }
+ ebytes = 1 << size;
+ elements = (is_q ? 16 : 8) / ebytes;
+
tcg_rn = cpu_reg_sp(s, rn);
tcg_addr = tcg_temp_new_i64();
tcg_gen_mov_i64(tcg_addr, tcg_rn);
+ tcg_ebytes = tcg_const_i64(ebytes);
for (r = 0; r < rpt; r++) {
int e;
for (e = 0; e < elements; e++) {
- int tt = (rt + r) % 32;
int xs;
for (xs = 0; xs < selem; xs++) {
+ int tt = (rt + r + xs) % 32;
if (is_store) {
- do_vec_st(s, tt, e, tcg_addr, size);
+ do_vec_st(s, tt, e, tcg_addr, size, endian);
} else {
- do_vec_ld(s, tt, e, tcg_addr, size);
-
- /* For non-quad operations, setting a slice of the low
- * 64 bits of the register clears the high 64 bits (in
- * the ARM ARM pseudocode this is implicit in the fact
- * that 'rval' is a 64 bit wide variable).
- * For quad operations, we might still need to zero the
- * high bits of SVE. We optimize by noticing that we only
- * need to do this the first time we touch a register.
- */
- if (e == 0 && (r == 0 || xs == selem - 1)) {
- clear_vec_high(s, is_q, tt);
- }
+ do_vec_ld(s, tt, e, tcg_addr, size, endian);
}
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
- tt = (tt + 1) % 32;
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
}
}
}
+ if (!is_store) {
+ /* For non-quad operations, setting a slice of the low
+ * 64 bits of the register clears the high 64 bits (in
+ * the ARM ARM pseudocode this is implicit in the fact
+ * that 'rval' is a 64 bit wide variable).
+ * For quad operations, we might still need to zero the
+ * high bits of SVE.
+ */
+ for (r = 0; r < rpt * selem; r++) {
+ int tt = (rt + r) % 32;
+ clear_vec_high(s, is_q, tt);
+ }
+ }
+
if (is_postidx) {
int rm = extract32(insn, 16, 5);
if (rm == 31) {
@@ -3126,6 +3136,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
}
}
+ tcg_temp_free_i64(tcg_ebytes);
tcg_temp_free_i64(tcg_addr);
}
@@ -3168,7 +3179,7 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
bool replicate = false;
int index = is_q << 3 | S << 2 | size;
int ebytes, xs;
- TCGv_i64 tcg_addr, tcg_rn;
+ TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
switch (scale) {
case 3:
@@ -3221,49 +3232,28 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
tcg_rn = cpu_reg_sp(s, rn);
tcg_addr = tcg_temp_new_i64();
tcg_gen_mov_i64(tcg_addr, tcg_rn);
+ tcg_ebytes = tcg_const_i64(ebytes);
for (xs = 0; xs < selem; xs++) {
if (replicate) {
/* Load and replicate to all elements */
- uint64_t mulconst;
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
get_mem_index(s), s->be_data + scale);
- switch (scale) {
- case 0:
- mulconst = 0x0101010101010101ULL;
- break;
- case 1:
- mulconst = 0x0001000100010001ULL;
- break;
- case 2:
- mulconst = 0x0000000100000001ULL;
- break;
- case 3:
- mulconst = 0;
- break;
- default:
- g_assert_not_reached();
- }
- if (mulconst) {
- tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
- }
- write_vec_element(s, tcg_tmp, rt, 0, MO_64);
- if (is_q) {
- write_vec_element(s, tcg_tmp, rt, 1, MO_64);
- }
+ tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
+ (is_q + 1) * 8, vec_full_reg_size(s),
+ tcg_tmp);
tcg_temp_free_i64(tcg_tmp);
- clear_vec_high(s, is_q, rt);
} else {
/* Load/store one element per register */
if (is_load) {
- do_vec_ld(s, rt, index, tcg_addr, scale);
+ do_vec_ld(s, rt, index, tcg_addr, scale, s->be_data);
} else {
- do_vec_st(s, rt, index, tcg_addr, scale);
+ do_vec_st(s, rt, index, tcg_addr, scale, s->be_data);
}
}
- tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
rt = (rt + 1) % 32;
}
@@ -3275,6 +3265,7 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
}
}
+ tcg_temp_free_i64(tcg_ebytes);
tcg_temp_free_i64(tcg_addr);
}
@@ -4574,7 +4565,7 @@ static void handle_crc32(DisasContext *s,
TCGv_i64 tcg_acc, tcg_val;
TCGv_i32 tcg_bytes;
- if (!arm_dc_feature(s, ARM_FEATURE_CRC)
+ if (!dc_isar_feature(aa64_crc32, s)
|| (sf == 1 && sz != 3)
|| (sf == 0 && sz == 3)) {
unallocated_encoding(s);
@@ -4816,7 +4807,7 @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
break;
case 3:
size = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -4867,7 +4858,7 @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
break;
case 3:
size = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -4933,7 +4924,7 @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
break;
case 3:
sz = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -5266,7 +5257,7 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
handle_fp_1src_double(s, opcode, rd, rn);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -5481,7 +5472,7 @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
handle_fp_2src_double(s, opcode, rd, rn, rm);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -5639,7 +5630,7 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
break;
case 3:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -5709,7 +5700,7 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
break;
case 3:
sz = MO_16;
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -5934,7 +5925,7 @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
case 1: /* float64 */
break;
case 3: /* float16 */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -6064,7 +6055,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
break;
case 0x6: /* 16-bit float, 32-bit int */
case 0xe: /* 16-bit float, 64-bit int */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -6091,7 +6082,7 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
case 1: /* float64 */
break;
case 3: /* float16 */
- if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (dc_isar_feature(aa64_fp16, s)) {
break;
}
/* fallthru */
@@ -6528,7 +6519,7 @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
*/
is_min = extract32(size, 1, 1);
is_fp = true;
- if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!is_u && dc_isar_feature(aa64_fp16, s)) {
size = 1;
} else if (!is_u || !is_q || extract32(size, 0, 1)) {
unallocated_encoding(s);
@@ -6924,7 +6915,7 @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
/* Check for FMOV (vector, immediate) - half-precision */
- if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
+ if (!(dc_isar_feature(aa64_fp16, s) && o2 && cmode == 0xf)) {
unallocated_encoding(s);
return;
}
@@ -7091,7 +7082,7 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
case 0x2f: /* FMINP */
/* FP op, size[0] is 32 or 64 bit*/
if (!u) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
} else {
@@ -7736,7 +7727,7 @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
size = MO_32;
} else if (immh & 2) {
size = MO_16;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -7781,7 +7772,7 @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
size = MO_32;
} else if (immh & 0x2) {
size = MO_16;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -8046,28 +8037,6 @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
}
}
-/* CMTST : test is "if (X & Y != 0)". */
-static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- tcg_gen_and_i32(d, a, b);
- tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
- tcg_gen_neg_i32(d, d);
-}
-
-static void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
- tcg_gen_and_i64(d, a, b);
- tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
- tcg_gen_neg_i64(d, d);
-}
-
-static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
- tcg_gen_and_vec(vece, d, a, b);
- tcg_gen_dupi_vec(vece, a, 0);
- tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
-}
-
static void handle_3same_64(DisasContext *s, int opcode, bool u,
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
{
@@ -8545,7 +8514,7 @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
return;
}
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
}
@@ -8618,7 +8587,7 @@ static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
bool u = extract32(insn, 29, 1);
TCGv_i32 ele1, ele2, ele3;
TCGv_i64 res;
- int feature;
+ bool feature;
switch (u * 16 + opcode) {
case 0x10: /* SQRDMLAH (vector) */
@@ -8627,13 +8596,13 @@ static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
unallocated_encoding(s);
return;
}
- feature = ARM_FEATURE_V8_RDM;
+ feature = dc_isar_feature(aa64_rdm, s);
break;
default:
unallocated_encoding(s);
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -9407,191 +9376,10 @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
}
}
-static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_vec_sar8i_i64(a, a, shift);
- tcg_gen_vec_add8_i64(d, d, a);
-}
-
-static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_vec_sar16i_i64(a, a, shift);
- tcg_gen_vec_add16_i64(d, d, a);
-}
-
-static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
- tcg_gen_sari_i32(a, a, shift);
- tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_sari_i64(a, a, shift);
- tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
- tcg_gen_sari_vec(vece, a, a, sh);
- tcg_gen_add_vec(vece, d, d, a);
-}
-
-static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_vec_shr8i_i64(a, a, shift);
- tcg_gen_vec_add8_i64(d, d, a);
-}
-
-static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_vec_shr16i_i64(a, a, shift);
- tcg_gen_vec_add16_i64(d, d, a);
-}
-
-static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
- tcg_gen_shri_i32(a, a, shift);
- tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_shri_i64(a, a, shift);
- tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
- tcg_gen_shri_vec(vece, a, a, sh);
- tcg_gen_add_vec(vece, d, d, a);
-}
-
-static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- uint64_t mask = dup_const(MO_8, 0xff >> shift);
- TCGv_i64 t = tcg_temp_new_i64();
-
- tcg_gen_shri_i64(t, a, shift);
- tcg_gen_andi_i64(t, t, mask);
- tcg_gen_andi_i64(d, d, ~mask);
- tcg_gen_or_i64(d, d, t);
- tcg_temp_free_i64(t);
-}
-
-static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- uint64_t mask = dup_const(MO_16, 0xffff >> shift);
- TCGv_i64 t = tcg_temp_new_i64();
-
- tcg_gen_shri_i64(t, a, shift);
- tcg_gen_andi_i64(t, t, mask);
- tcg_gen_andi_i64(d, d, ~mask);
- tcg_gen_or_i64(d, d, t);
- tcg_temp_free_i64(t);
-}
-
-static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
- tcg_gen_shri_i32(a, a, shift);
- tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
-}
-
-static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_shri_i64(a, a, shift);
- tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
-}
-
-static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
- uint64_t mask = (2ull << ((8 << vece) - 1)) - 1;
- TCGv_vec t = tcg_temp_new_vec_matching(d);
- TCGv_vec m = tcg_temp_new_vec_matching(d);
-
- tcg_gen_dupi_vec(vece, m, mask ^ (mask >> sh));
- tcg_gen_shri_vec(vece, t, a, sh);
- tcg_gen_and_vec(vece, d, d, m);
- tcg_gen_or_vec(vece, d, d, t);
-
- tcg_temp_free_vec(t);
- tcg_temp_free_vec(m);
-}
-
/* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
int immh, int immb, int opcode, int rn, int rd)
{
- static const GVecGen2i ssra_op[4] = {
- { .fni8 = gen_ssra8_i64,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opc = INDEX_op_sari_vec,
- .vece = MO_8 },
- { .fni8 = gen_ssra16_i64,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opc = INDEX_op_sari_vec,
- .vece = MO_16 },
- { .fni4 = gen_ssra32_i32,
- .fniv = gen_ssra_vec,
- .load_dest = true,
- .opc = INDEX_op_sari_vec,
- .vece = MO_32 },
- { .fni8 = gen_ssra64_i64,
- .fniv = gen_ssra_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opc = INDEX_op_sari_vec,
- .vece = MO_64 },
- };
- static const GVecGen2i usra_op[4] = {
- { .fni8 = gen_usra8_i64,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_8, },
- { .fni8 = gen_usra16_i64,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_16, },
- { .fni4 = gen_usra32_i32,
- .fniv = gen_usra_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_32, },
- { .fni8 = gen_usra64_i64,
- .fniv = gen_usra_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_64, },
- };
- static const GVecGen2i sri_op[4] = {
- { .fni8 = gen_shr8_ins_i64,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_8 },
- { .fni8 = gen_shr16_ins_i64,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_16 },
- { .fni4 = gen_shr32_ins_i32,
- .fniv = gen_shr_ins_vec,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_32 },
- { .fni8 = gen_shr64_ins_i64,
- .fniv = gen_shr_ins_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .opc = INDEX_op_shri_vec,
- .vece = MO_64 },
- };
-
int size = 32 - clz32(immh) - 1;
int immhb = immh << 3 | immb;
int shift = 2 * (8 << size) - immhb;
@@ -9687,85 +9475,10 @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
clear_vec_high(s, is_q, rd);
}
-static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- uint64_t mask = dup_const(MO_8, 0xff << shift);
- TCGv_i64 t = tcg_temp_new_i64();
-
- tcg_gen_shli_i64(t, a, shift);
- tcg_gen_andi_i64(t, t, mask);
- tcg_gen_andi_i64(d, d, ~mask);
- tcg_gen_or_i64(d, d, t);
- tcg_temp_free_i64(t);
-}
-
-static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- uint64_t mask = dup_const(MO_16, 0xffff << shift);
- TCGv_i64 t = tcg_temp_new_i64();
-
- tcg_gen_shli_i64(t, a, shift);
- tcg_gen_andi_i64(t, t, mask);
- tcg_gen_andi_i64(d, d, ~mask);
- tcg_gen_or_i64(d, d, t);
- tcg_temp_free_i64(t);
-}
-
-static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
- tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
-}
-
-static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
- tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
-}
-
-static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
- uint64_t mask = (1ull << sh) - 1;
- TCGv_vec t = tcg_temp_new_vec_matching(d);
- TCGv_vec m = tcg_temp_new_vec_matching(d);
-
- tcg_gen_dupi_vec(vece, m, mask);
- tcg_gen_shli_vec(vece, t, a, sh);
- tcg_gen_and_vec(vece, d, d, m);
- tcg_gen_or_vec(vece, d, d, t);
-
- tcg_temp_free_vec(t);
- tcg_temp_free_vec(m);
-}
-
/* SHL/SLI - Vector shift left */
static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
int immh, int immb, int opcode, int rn, int rd)
{
- static const GVecGen2i shi_op[4] = {
- { .fni8 = gen_shl8_ins_i64,
- .fniv = gen_shl_ins_vec,
- .opc = INDEX_op_shli_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_8 },
- { .fni8 = gen_shl16_ins_i64,
- .fniv = gen_shl_ins_vec,
- .opc = INDEX_op_shli_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_16 },
- { .fni4 = gen_shl32_ins_i32,
- .fniv = gen_shl_ins_vec,
- .opc = INDEX_op_shli_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_32 },
- { .fni8 = gen_shl64_ins_i64,
- .fniv = gen_shl_ins_vec,
- .opc = INDEX_op_shli_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_64 },
- };
int size = 32 - clz32(immh) - 1;
int immhb = immh << 3 | immb;
int shift = immhb - (8 << size);
@@ -9785,7 +9498,7 @@ static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
}
if (insert) {
- gen_gvec_op2i(s, is_q, rd, rn, shift, &shi_op[size]);
+ gen_gvec_op2i(s, is_q, rd, rn, shift, &sli_op[size]);
} else {
gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shli, size);
}
@@ -10362,7 +10075,7 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
return;
}
if (size == 3) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
+ if (!dc_isar_feature(aa64_pmull, s)) {
unallocated_encoding(s);
return;
}
@@ -10407,70 +10120,9 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
}
}
-static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
- tcg_gen_xor_i64(rn, rn, rm);
- tcg_gen_and_i64(rn, rn, rd);
- tcg_gen_xor_i64(rd, rm, rn);
-}
-
-static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
- tcg_gen_xor_i64(rn, rn, rd);
- tcg_gen_and_i64(rn, rn, rm);
- tcg_gen_xor_i64(rd, rd, rn);
-}
-
-static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
- tcg_gen_xor_i64(rn, rn, rd);
- tcg_gen_andc_i64(rn, rn, rm);
- tcg_gen_xor_i64(rd, rd, rn);
-}
-
-static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
- tcg_gen_xor_vec(vece, rn, rn, rm);
- tcg_gen_and_vec(vece, rn, rn, rd);
- tcg_gen_xor_vec(vece, rd, rm, rn);
-}
-
-static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
- tcg_gen_xor_vec(vece, rn, rn, rd);
- tcg_gen_and_vec(vece, rn, rn, rm);
- tcg_gen_xor_vec(vece, rd, rd, rn);
-}
-
-static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
- tcg_gen_xor_vec(vece, rn, rn, rd);
- tcg_gen_andc_vec(vece, rn, rn, rm);
- tcg_gen_xor_vec(vece, rd, rd, rn);
-}
-
/* Logic op (opcode == 3) subgroup of C3.6.16. */
static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
{
- static const GVecGen3 bsl_op = {
- .fni8 = gen_bsl_i64,
- .fniv = gen_bsl_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true
- };
- static const GVecGen3 bit_op = {
- .fni8 = gen_bit_i64,
- .fniv = gen_bit_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true
- };
- static const GVecGen3 bif_op = {
- .fni8 = gen_bif_i64,
- .fniv = gen_bif_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true
- };
-
int rd = extract32(insn, 0, 5);
int rn = extract32(insn, 5, 5);
int rm = extract32(insn, 16, 5);
@@ -10742,131 +10394,9 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
}
}
-static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- gen_helper_neon_mul_u8(a, a, b);
- gen_helper_neon_add_u8(d, d, a);
-}
-
-static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- gen_helper_neon_mul_u16(a, a, b);
- gen_helper_neon_add_u16(d, d, a);
-}
-
-static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- tcg_gen_mul_i32(a, a, b);
- tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
- tcg_gen_mul_i64(a, a, b);
- tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
- tcg_gen_mul_vec(vece, a, a, b);
- tcg_gen_add_vec(vece, d, d, a);
-}
-
-static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- gen_helper_neon_mul_u8(a, a, b);
- gen_helper_neon_sub_u8(d, d, a);
-}
-
-static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- gen_helper_neon_mul_u16(a, a, b);
- gen_helper_neon_sub_u16(d, d, a);
-}
-
-static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
- tcg_gen_mul_i32(a, a, b);
- tcg_gen_sub_i32(d, d, a);
-}
-
-static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
- tcg_gen_mul_i64(a, a, b);
- tcg_gen_sub_i64(d, d, a);
-}
-
-static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
- tcg_gen_mul_vec(vece, a, a, b);
- tcg_gen_sub_vec(vece, d, d, a);
-}
-
/* Integer op subgroup of C3.6.16. */
static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
{
- static const GVecGen3 cmtst_op[4] = {
- { .fni4 = gen_helper_neon_tst_u8,
- .fniv = gen_cmtst_vec,
- .vece = MO_8 },
- { .fni4 = gen_helper_neon_tst_u16,
- .fniv = gen_cmtst_vec,
- .vece = MO_16 },
- { .fni4 = gen_cmtst_i32,
- .fniv = gen_cmtst_vec,
- .vece = MO_32 },
- { .fni8 = gen_cmtst_i64,
- .fniv = gen_cmtst_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .vece = MO_64 },
- };
- static const GVecGen3 mla_op[4] = {
- { .fni4 = gen_mla8_i32,
- .fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_8 },
- { .fni4 = gen_mla16_i32,
- .fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_16 },
- { .fni4 = gen_mla32_i32,
- .fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_32 },
- { .fni8 = gen_mla64_i64,
- .fniv = gen_mla_vec,
- .opc = INDEX_op_mul_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_64 },
- };
- static const GVecGen3 mls_op[4] = {
- { .fni4 = gen_mls8_i32,
- .fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_8 },
- { .fni4 = gen_mls16_i32,
- .fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_16 },
- { .fni4 = gen_mls32_i32,
- .fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
- .load_dest = true,
- .vece = MO_32 },
- { .fni8 = gen_mls64_i64,
- .fniv = gen_mls_vec,
- .opc = INDEX_op_mul_vec,
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
- .load_dest = true,
- .vece = MO_64 },
- };
-
int is_q = extract32(insn, 30, 1);
int u = extract32(insn, 29, 1);
int size = extract32(insn, 22, 2);
@@ -11226,7 +10756,7 @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
TCGv_ptr fpst;
bool pairwise = false;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -11414,7 +10944,8 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
int size = extract32(insn, 22, 2);
bool u = extract32(insn, 29, 1);
bool is_q = extract32(insn, 30, 1);
- int feature, rot;
+ bool feature;
+ int rot;
switch (u * 16 + opcode) {
case 0x10: /* SQRDMLAH (vector) */
@@ -11423,7 +10954,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
- feature = ARM_FEATURE_V8_RDM;
+ feature = dc_isar_feature(aa64_rdm, s);
break;
case 0x02: /* SDOT (vector) */
case 0x12: /* UDOT (vector) */
@@ -11431,7 +10962,7 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
return;
}
- feature = ARM_FEATURE_V8_DOTPROD;
+ feature = dc_isar_feature(aa64_dp, s);
break;
case 0x18: /* FCMLA, #0 */
case 0x19: /* FCMLA, #90 */
@@ -11440,18 +10971,18 @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
case 0x1c: /* FCADD, #90 */
case 0x1e: /* FCADD, #270 */
if (size == 0
- || (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
+ || (size == 1 && !dc_isar_feature(aa64_fp16, s))
|| (size == 3 && !is_q)) {
unallocated_encoding(s);
return;
}
- feature = ARM_FEATURE_V8_FCMA;
+ feature = dc_isar_feature(aa64_fcma, s);
break;
default:
unallocated_encoding(s);
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -12320,7 +11851,7 @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
bool need_fpst = true;
int rmode;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -12665,14 +12196,14 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
break;
case 0x1d: /* SQRDMLAH */
case 0x1f: /* SQRDMLSH */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
+ if (!dc_isar_feature(aa64_rdm, s)) {
unallocated_encoding(s);
return;
}
break;
case 0x0e: /* SDOT */
case 0x1e: /* UDOT */
- if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
+ if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
unallocated_encoding(s);
return;
}
@@ -12681,7 +12212,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
case 0x13: /* FCMLA #90 */
case 0x15: /* FCMLA #180 */
case 0x17: /* FCMLA #270 */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
+ if (!dc_isar_feature(aa64_fcma, s)) {
unallocated_encoding(s);
return;
}
@@ -12737,7 +12268,7 @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
}
break;
}
- if (is_fp16 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
unallocated_encoding(s);
return;
}
@@ -13208,8 +12739,7 @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
TCGv_i32 tcg_decrypt;
CryptoThreeOpIntFn *genfn;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
- || size != 0) {
+ if (!dc_isar_feature(aa64_aes, s) || size != 0) {
unallocated_encoding(s);
return;
}
@@ -13266,7 +12796,7 @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
int rd = extract32(insn, 0, 5);
CryptoThreeOpFn *genfn;
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
- int feature = ARM_FEATURE_V8_SHA256;
+ bool feature;
if (size != 0) {
unallocated_encoding(s);
@@ -13279,23 +12809,26 @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
case 2: /* SHA1M */
case 3: /* SHA1SU0 */
genfn = NULL;
- feature = ARM_FEATURE_V8_SHA1;
+ feature = dc_isar_feature(aa64_sha1, s);
break;
case 4: /* SHA256H */
genfn = gen_helper_crypto_sha256h;
+ feature = dc_isar_feature(aa64_sha256, s);
break;
case 5: /* SHA256H2 */
genfn = gen_helper_crypto_sha256h2;
+ feature = dc_isar_feature(aa64_sha256, s);
break;
case 6: /* SHA256SU1 */
genfn = gen_helper_crypto_sha256su1;
+ feature = dc_isar_feature(aa64_sha256, s);
break;
default:
unallocated_encoding(s);
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -13336,7 +12869,7 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
CryptoTwoOpFn *genfn;
- int feature;
+ bool feature;
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
if (size != 0) {
@@ -13346,15 +12879,15 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
switch (opcode) {
case 0: /* SHA1H */
- feature = ARM_FEATURE_V8_SHA1;
+ feature = dc_isar_feature(aa64_sha1, s);
genfn = gen_helper_crypto_sha1h;
break;
case 1: /* SHA1SU1 */
- feature = ARM_FEATURE_V8_SHA1;
+ feature = dc_isar_feature(aa64_sha1, s);
genfn = gen_helper_crypto_sha1su1;
break;
case 2: /* SHA256SU0 */
- feature = ARM_FEATURE_V8_SHA256;
+ feature = dc_isar_feature(aa64_sha256, s);
genfn = gen_helper_crypto_sha256su0;
break;
default:
@@ -13362,7 +12895,7 @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -13393,40 +12926,40 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
int rm = extract32(insn, 16, 5);
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
- int feature;
+ bool feature;
CryptoThreeOpFn *genfn;
if (o == 0) {
switch (opcode) {
case 0: /* SHA512H */
- feature = ARM_FEATURE_V8_SHA512;
+ feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512h;
break;
case 1: /* SHA512H2 */
- feature = ARM_FEATURE_V8_SHA512;
+ feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512h2;
break;
case 2: /* SHA512SU1 */
- feature = ARM_FEATURE_V8_SHA512;
+ feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512su1;
break;
case 3: /* RAX1 */
- feature = ARM_FEATURE_V8_SHA3;
+ feature = dc_isar_feature(aa64_sha3, s);
genfn = NULL;
break;
}
} else {
switch (opcode) {
case 0: /* SM3PARTW1 */
- feature = ARM_FEATURE_V8_SM3;
+ feature = dc_isar_feature(aa64_sm3, s);
genfn = gen_helper_crypto_sm3partw1;
break;
case 1: /* SM3PARTW2 */
- feature = ARM_FEATURE_V8_SM3;
+ feature = dc_isar_feature(aa64_sm3, s);
genfn = gen_helper_crypto_sm3partw2;
break;
case 2: /* SM4EKEY */
- feature = ARM_FEATURE_V8_SM4;
+ feature = dc_isar_feature(aa64_sm4, s);
genfn = gen_helper_crypto_sm4ekey;
break;
default:
@@ -13435,7 +12968,7 @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
}
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -13494,16 +13027,16 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
- int feature;
+ bool feature;
CryptoTwoOpFn *genfn;
switch (opcode) {
case 0: /* SHA512SU0 */
- feature = ARM_FEATURE_V8_SHA512;
+ feature = dc_isar_feature(aa64_sha512, s);
genfn = gen_helper_crypto_sha512su0;
break;
case 1: /* SM4E */
- feature = ARM_FEATURE_V8_SM4;
+ feature = dc_isar_feature(aa64_sm4, s);
genfn = gen_helper_crypto_sm4e;
break;
default:
@@ -13511,7 +13044,7 @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -13542,22 +13075,22 @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
int ra = extract32(insn, 10, 5);
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
- int feature;
+ bool feature;
switch (op0) {
case 0: /* EOR3 */
case 1: /* BCAX */
- feature = ARM_FEATURE_V8_SHA3;
+ feature = dc_isar_feature(aa64_sha3, s);
break;
case 2: /* SM3SS1 */
- feature = ARM_FEATURE_V8_SM3;
+ feature = dc_isar_feature(aa64_sm3, s);
break;
default:
unallocated_encoding(s);
return;
}
- if (!arm_dc_feature(s, feature)) {
+ if (!feature) {
unallocated_encoding(s);
return;
}
@@ -13644,7 +13177,7 @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
int pass;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) {
+ if (!dc_isar_feature(aa64_sha3, s)) {
unallocated_encoding(s);
return;
}
@@ -13690,7 +13223,7 @@ static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
TCGv_i32 tcg_imm2, tcg_opcode;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) {
+ if (!dc_isar_feature(aa64_sm3, s)) {
unallocated_encoding(s);
return;
}
@@ -13798,7 +13331,7 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
break;
case 0x2:
- if (!arm_dc_feature(s, ARM_FEATURE_SVE) || !disas_sve(s, insn)) {
+ if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
unallocated_encoding(s);
}
break;
@@ -13839,6 +13372,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
ARMCPU *arm_cpu = arm_env_get_cpu(env);
int bound;
+ dc->isar = &arm_cpu->isar;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;
@@ -13902,7 +13436,6 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
{
- tcg_clear_temp_count();
}
static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1b4bacb522..7c4675ffd8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -42,7 +42,7 @@
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
/* currently all emulated v5 cores are also v5TE, so don't bother */
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
-#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
+#define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
@@ -72,7 +72,7 @@ static TCGv_i64 cpu_F0d, cpu_F1d;
#include "exec/gen-icount.h"
-static const char *regnames[] =
+static const char * const regnames[] =
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
@@ -1585,6 +1585,25 @@ neon_reg_offset (int reg, int n)
return vfp_reg_offset(0, sreg);
}
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
+ * where 0 is the least significant end of the register.
+ */
+static inline long
+neon_element_offset(int reg, int element, TCGMemOp size)
+{
+ int element_size = 1 << size;
+ int ofs = element * element_size;
+#ifdef HOST_WORDS_BIGENDIAN
+ /* Calculate the offset assuming fully little-endian,
+ * then XOR to account for the order of the 8-byte units.
+ */
+ if (element_size < 8) {
+ ofs ^= 8 - element_size;
+ }
+#endif
+ return neon_reg_offset(reg, 0) + ofs;
+}
+
static TCGv_i32 neon_load_reg(int reg, int pass)
{
TCGv_i32 tmp = tcg_temp_new_i32();
@@ -1592,12 +1611,94 @@ static TCGv_i32 neon_load_reg(int reg, int pass)
return tmp;
}
+static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
+{
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
+
+ switch (mop) {
+ case MO_UB:
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
+ break;
+ case MO_UW:
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
+ break;
+ case MO_UL:
+ tcg_gen_ld_i32(var, cpu_env, offset);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
+{
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
+
+ switch (mop) {
+ case MO_UB:
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
+ break;
+ case MO_UW:
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
+ break;
+ case MO_UL:
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
+ break;
+ case MO_Q:
+ tcg_gen_ld_i64(var, cpu_env, offset);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
{
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
tcg_temp_free_i32(var);
}
+static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
+{
+ long offset = neon_element_offset(reg, ele, size);
+
+ switch (size) {
+ case MO_8:
+ tcg_gen_st8_i32(var, cpu_env, offset);
+ break;
+ case MO_16:
+ tcg_gen_st16_i32(var, cpu_env, offset);
+ break;
+ case MO_32:
+ tcg_gen_st_i32(var, cpu_env, offset);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
+{
+ long offset = neon_element_offset(reg, ele, size);
+
+ switch (size) {
+ case MO_8:
+ tcg_gen_st8_i64(var, cpu_env, offset);
+ break;
+ case MO_16:
+ tcg_gen_st16_i64(var, cpu_env, offset);
+ break;
+ case MO_32:
+ tcg_gen_st32_i64(var, cpu_env, offset);
+ break;
+ case MO_64:
+ tcg_gen_st_i64(var, cpu_env, offset);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static inline void neon_load_reg64(TCGv_i64 var, int reg)
{
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
@@ -2974,19 +3075,6 @@ static void gen_vfp_msr(TCGv_i32 tmp)
tcg_temp_free_i32(tmp);
}
-static void gen_neon_dup_u8(TCGv_i32 var, int shift)
-{
- TCGv_i32 tmp = tcg_temp_new_i32();
- if (shift)
- tcg_gen_shri_i32(var, var, shift);
- tcg_gen_ext8u_i32(var, var);
- tcg_gen_shli_i32(tmp, var, 8);
- tcg_gen_or_i32(var, var, tmp);
- tcg_gen_shli_i32(tmp, var, 16);
- tcg_gen_or_i32(var, var, tmp);
- tcg_temp_free_i32(tmp);
-}
-
static void gen_neon_dup_low16(TCGv_i32 var)
{
TCGv_i32 tmp = tcg_temp_new_i32();
@@ -3005,28 +3093,6 @@ static void gen_neon_dup_high16(TCGv_i32 var)
tcg_temp_free_i32(tmp);
}
-static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
-{
- /* Load a single Neon element and replicate into a 32 bit TCG reg */
- TCGv_i32 tmp = tcg_temp_new_i32();
- switch (size) {
- case 0:
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
- gen_neon_dup_u8(tmp, 0);
- break;
- case 1:
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
- gen_neon_dup_low16(tmp);
- break;
- case 2:
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
- break;
- default: /* Avoid compiler warnings. */
- abort();
- }
- return tmp;
-}
-
static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
uint32_t dp)
{
@@ -3432,17 +3498,10 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
tmp = load_reg(s, rd);
if (insn & (1 << 23)) {
/* VDUP */
- if (size == 0) {
- gen_neon_dup_u8(tmp, 0);
- } else if (size == 1) {
- gen_neon_dup_low16(tmp);
- }
- for (n = 0; n <= pass * 2; n++) {
- tmp2 = tcg_temp_new_i32();
- tcg_gen_mov_i32(tmp2, tmp);
- neon_store_reg(rn, n, tmp2);
- }
- neon_store_reg(rn, n, tmp);
+ int vec_size = pass ? 16 : 8;
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
+ vec_size, vec_size, tmp);
+ tcg_temp_free_i32(tmp);
} else {
/* VMOV */
switch (size) {
@@ -4907,17 +4966,17 @@ static struct {
int nregs;
int interleave;
int spacing;
-} neon_ls_element_type[11] = {
- {4, 4, 1},
- {4, 4, 2},
+} const neon_ls_element_type[11] = {
+ {1, 4, 1},
+ {1, 4, 2},
{4, 1, 1},
- {4, 2, 1},
- {3, 3, 1},
- {3, 3, 2},
+ {2, 2, 2},
+ {1, 3, 1},
+ {1, 3, 2},
{3, 1, 1},
{1, 1, 1},
- {2, 2, 1},
- {2, 2, 2},
+ {1, 2, 1},
+ {1, 2, 2},
{2, 1, 1}
};
@@ -4933,10 +4992,11 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
int stride;
int size;
int reg;
- int pass;
int load;
- int shift;
int n;
+ int vec_size;
+ int mmu_idx;
+ TCGMemOp endian;
TCGv_i32 addr;
TCGv_i32 tmp;
TCGv_i32 tmp2;
@@ -4948,7 +5008,7 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
*/
if (s->fp_excp_el) {
gen_exception_insn(s, 4, EXCP_UDEF,
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
return 0;
}
@@ -4958,6 +5018,8 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
rn = (insn >> 16) & 0xf;
rm = insn & 0xf;
load = (insn & (1 << 21)) != 0;
+ endian = s->be_data;
+ mmu_idx = get_mem_index(s);
if ((insn & (1 << 23)) == 0) {
/* Load store all elements. */
op = (insn >> 8) & 0xf;
@@ -4982,104 +5044,44 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
nregs = neon_ls_element_type[op].nregs;
interleave = neon_ls_element_type[op].interleave;
spacing = neon_ls_element_type[op].spacing;
- if (size == 3 && (interleave | spacing) != 1)
+ if (size == 3 && (interleave | spacing) != 1) {
return 1;
+ }
+ /* For our purposes, bytes are always little-endian. */
+ if (size == 0) {
+ endian = MO_LE;
+ }
+ /* Consecutive little-endian elements from a single register
+ * can be promoted to a larger little-endian operation.
+ */
+ if (interleave == 1 && endian == MO_LE) {
+ size = 3;
+ }
+ tmp64 = tcg_temp_new_i64();
addr = tcg_temp_new_i32();
+ tmp2 = tcg_const_i32(1 << size);
load_reg_var(s, addr, rn);
- stride = (1 << size) * interleave;
for (reg = 0; reg < nregs; reg++) {
- if (interleave > 2 || (interleave == 2 && nregs == 2)) {
- load_reg_var(s, addr, rn);
- tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
- } else if (interleave == 2 && nregs == 4 && reg == 2) {
- load_reg_var(s, addr, rn);
- tcg_gen_addi_i32(addr, addr, 1 << size);
- }
- if (size == 3) {
- tmp64 = tcg_temp_new_i64();
- if (load) {
- gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
- neon_store_reg64(tmp64, rd);
- } else {
- neon_load_reg64(tmp64, rd);
- gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
- }
- tcg_temp_free_i64(tmp64);
- tcg_gen_addi_i32(addr, addr, stride);
- } else {
- for (pass = 0; pass < 2; pass++) {
- if (size == 2) {
- if (load) {
- tmp = tcg_temp_new_i32();
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
- neon_store_reg(rd, pass, tmp);
- } else {
- tmp = neon_load_reg(rd, pass);
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
- tcg_temp_free_i32(tmp);
- }
- tcg_gen_addi_i32(addr, addr, stride);
- } else if (size == 1) {
- if (load) {
- tmp = tcg_temp_new_i32();
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
- tcg_gen_addi_i32(addr, addr, stride);
- tmp2 = tcg_temp_new_i32();
- gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
- tcg_gen_addi_i32(addr, addr, stride);
- tcg_gen_shli_i32(tmp2, tmp2, 16);
- tcg_gen_or_i32(tmp, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
- neon_store_reg(rd, pass, tmp);
- } else {
- tmp = neon_load_reg(rd, pass);
- tmp2 = tcg_temp_new_i32();
- tcg_gen_shri_i32(tmp2, tmp, 16);
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
- tcg_temp_free_i32(tmp);
- tcg_gen_addi_i32(addr, addr, stride);
- gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
- tcg_temp_free_i32(tmp2);
- tcg_gen_addi_i32(addr, addr, stride);
- }
- } else /* size == 0 */ {
- if (load) {
- tmp2 = NULL;
- for (n = 0; n < 4; n++) {
- tmp = tcg_temp_new_i32();
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
- tcg_gen_addi_i32(addr, addr, stride);
- if (n == 0) {
- tmp2 = tmp;
- } else {
- tcg_gen_shli_i32(tmp, tmp, n * 8);
- tcg_gen_or_i32(tmp2, tmp2, tmp);
- tcg_temp_free_i32(tmp);
- }
- }
- neon_store_reg(rd, pass, tmp2);
- } else {
- tmp2 = neon_load_reg(rd, pass);
- for (n = 0; n < 4; n++) {
- tmp = tcg_temp_new_i32();
- if (n == 0) {
- tcg_gen_mov_i32(tmp, tmp2);
- } else {
- tcg_gen_shri_i32(tmp, tmp2, n * 8);
- }
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
- tcg_temp_free_i32(tmp);
- tcg_gen_addi_i32(addr, addr, stride);
- }
- tcg_temp_free_i32(tmp2);
- }
+ for (n = 0; n < 8 >> size; n++) {
+ int xs;
+ for (xs = 0; xs < interleave; xs++) {
+ int tt = rd + reg + spacing * xs;
+
+ if (load) {
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
+ neon_store_element64(tt, n, size, tmp64);
+ } else {
+ neon_load_element64(tmp64, tt, n, size);
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
}
+ tcg_gen_add_i32(addr, addr, tmp2);
}
}
- rd += spacing;
}
tcg_temp_free_i32(addr);
- stride = nregs * 8;
+ tcg_temp_free_i32(tmp2);
+ tcg_temp_free_i64(tmp64);
+ stride = nregs * interleave * 8;
} else {
size = (insn >> 10) & 3;
if (size == 3) {
@@ -5106,45 +5108,50 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
}
addr = tcg_temp_new_i32();
load_reg_var(s, addr, rn);
- if (nregs == 1) {
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
- tmp = gen_load_and_replicate(s, addr, size);
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
- if (insn & (1 << 5)) {
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
- }
- tcg_temp_free_i32(tmp);
- } else {
- /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
- stride = (insn & (1 << 5)) ? 2 : 1;
- for (reg = 0; reg < nregs; reg++) {
- tmp = gen_load_and_replicate(s, addr, size);
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
- tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
- tcg_temp_free_i32(tmp);
- tcg_gen_addi_i32(addr, addr, 1 << size);
- rd += stride;
+
+ /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
+ * VLD2/3/4 to all lanes: bit 5 indicates register stride.
+ */
+ stride = (insn & (1 << 5)) ? 2 : 1;
+ vec_size = nregs == 1 ? stride * 8 : 8;
+
+ tmp = tcg_temp_new_i32();
+ for (reg = 0; reg < nregs; reg++) {
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
+ s->be_data | size);
+ if ((rd & 1) && vec_size == 16) {
+ /* We cannot write 16 bytes at once because the
+ * destination is unaligned.
+ */
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
+ 8, 8, tmp);
+ tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
+ neon_reg_offset(rd, 0), 8, 8);
+ } else {
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
+ vec_size, vec_size, tmp);
}
+ tcg_gen_addi_i32(addr, addr, 1 << size);
+ rd += stride;
}
+ tcg_temp_free_i32(tmp);
tcg_temp_free_i32(addr);
stride = (1 << size) * nregs;
} else {
/* Single element. */
int idx = (insn >> 4) & 0xf;
- pass = (insn >> 7) & 1;
+ int reg_idx;
switch (size) {
case 0:
- shift = ((insn >> 5) & 3) * 8;
+ reg_idx = (insn >> 5) & 7;
stride = 1;
break;
case 1:
- shift = ((insn >> 6) & 1) * 16;
+ reg_idx = (insn >> 6) & 3;
stride = (insn & (1 << 5)) ? 2 : 1;
break;
case 2:
- shift = 0;
+ reg_idx = (insn >> 7) & 1;
stride = (insn & (1 << 6)) ? 2 : 1;
break;
default:
@@ -5184,52 +5191,24 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
*/
return 1;
}
+ tmp = tcg_temp_new_i32();
addr = tcg_temp_new_i32();
load_reg_var(s, addr, rn);
for (reg = 0; reg < nregs; reg++) {
if (load) {
- tmp = tcg_temp_new_i32();
- switch (size) {
- case 0:
- gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
- break;
- case 1:
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
- break;
- case 2:
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
- break;
- default: /* Avoid compiler warnings. */
- abort();
- }
- if (size != 2) {
- tmp2 = neon_load_reg(rd, pass);
- tcg_gen_deposit_i32(tmp, tmp2, tmp,
- shift, size ? 16 : 8);
- tcg_temp_free_i32(tmp2);
- }
- neon_store_reg(rd, pass, tmp);
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
+ s->be_data | size);
+ neon_store_element(rd, reg_idx, size, tmp);
} else { /* Store */
- tmp = neon_load_reg(rd, pass);
- if (shift)
- tcg_gen_shri_i32(tmp, tmp, shift);
- switch (size) {
- case 0:
- gen_aa32_st8(s, tmp, addr, get_mem_index(s));
- break;
- case 1:
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
- break;
- case 2:
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
- break;
- }
- tcg_temp_free_i32(tmp);
+ neon_load_element(tmp, rd, reg_idx, size);
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
+ s->be_data | size);
}
rd += stride;
tcg_gen_addi_i32(addr, addr, 1 << size);
}
tcg_temp_free_i32(addr);
+ tcg_temp_free_i32(tmp);
stride = nregs * (1 << size);
}
}
@@ -5250,14 +5229,6 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
return 0;
}
-/* Bitwise select. dest = c ? t : f. Clobbers T and F. */
-static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
-{
- tcg_gen_and_i32(t, t, c);
- tcg_gen_andc_i32(f, f, c);
- tcg_gen_or_i32(dest, t, f);
-}
-
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
{
switch (size) {
@@ -5464,7 +5435,7 @@ static void gen_neon_narrow_op(int op, int u, int size,
#define NEON_3R_VABA 15
#define NEON_3R_VADD_VSUB 16
#define NEON_3R_VTST_VCEQ 17
-#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
+#define NEON_3R_VML 18 /* VMLA, VMLS */
#define NEON_3R_VMUL 19
#define NEON_3R_VPMAX 20
#define NEON_3R_VPMIN 21
@@ -5689,7 +5660,7 @@ static const uint8_t neon_2rm_sizes[] = {
static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
int q, int rd, int rn, int rm)
{
- if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
+ if (dc_isar_feature(aa32_rdm, s)) {
int opr_sz = (1 + q) * 8;
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
vfp_reg_offset(1, rn),
@@ -5700,6 +5671,483 @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
return 1;
}
+/*
+ * Expanders for VBitOps_VBIF, VBIT, VBSL.
+ */
+static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ tcg_gen_xor_i64(rn, rn, rm);
+ tcg_gen_and_i64(rn, rn, rd);
+ tcg_gen_xor_i64(rd, rm, rn);
+}
+
+static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ tcg_gen_xor_i64(rn, rn, rd);
+ tcg_gen_and_i64(rn, rn, rm);
+ tcg_gen_xor_i64(rd, rd, rn);
+}
+
+static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+ tcg_gen_xor_i64(rn, rn, rd);
+ tcg_gen_andc_i64(rn, rn, rm);
+ tcg_gen_xor_i64(rd, rd, rn);
+}
+
+static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+ tcg_gen_xor_vec(vece, rn, rn, rm);
+ tcg_gen_and_vec(vece, rn, rn, rd);
+ tcg_gen_xor_vec(vece, rd, rm, rn);
+}
+
+static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+ tcg_gen_xor_vec(vece, rn, rn, rd);
+ tcg_gen_and_vec(vece, rn, rn, rm);
+ tcg_gen_xor_vec(vece, rd, rd, rn);
+}
+
+static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+ tcg_gen_xor_vec(vece, rn, rn, rd);
+ tcg_gen_andc_vec(vece, rn, rn, rm);
+ tcg_gen_xor_vec(vece, rd, rd, rn);
+}
+
+const GVecGen3 bsl_op = {
+ .fni8 = gen_bsl_i64,
+ .fniv = gen_bsl_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true
+};
+
+const GVecGen3 bit_op = {
+ .fni8 = gen_bit_i64,
+ .fniv = gen_bit_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true
+};
+
+const GVecGen3 bif_op = {
+ .fni8 = gen_bif_i64,
+ .fniv = gen_bif_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true
+};
+
+static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_vec_sar8i_i64(a, a, shift);
+ tcg_gen_vec_add8_i64(d, d, a);
+}
+
+static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_vec_sar16i_i64(a, a, shift);
+ tcg_gen_vec_add16_i64(d, d, a);
+}
+
+static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
+{
+ tcg_gen_sari_i32(a, a, shift);
+ tcg_gen_add_i32(d, d, a);
+}
+
+static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_sari_i64(a, a, shift);
+ tcg_gen_add_i64(d, d, a);
+}
+
+static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ tcg_gen_sari_vec(vece, a, a, sh);
+ tcg_gen_add_vec(vece, d, d, a);
+}
+
+const GVecGen2i ssra_op[4] = {
+ { .fni8 = gen_ssra8_i64,
+ .fniv = gen_ssra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_sari_vec,
+ .vece = MO_8 },
+ { .fni8 = gen_ssra16_i64,
+ .fniv = gen_ssra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_sari_vec,
+ .vece = MO_16 },
+ { .fni4 = gen_ssra32_i32,
+ .fniv = gen_ssra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_sari_vec,
+ .vece = MO_32 },
+ { .fni8 = gen_ssra64_i64,
+ .fniv = gen_ssra_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opc = INDEX_op_sari_vec,
+ .vece = MO_64 },
+};
+
+static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_vec_shr8i_i64(a, a, shift);
+ tcg_gen_vec_add8_i64(d, d, a);
+}
+
+static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_vec_shr16i_i64(a, a, shift);
+ tcg_gen_vec_add16_i64(d, d, a);
+}
+
+static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
+{
+ tcg_gen_shri_i32(a, a, shift);
+ tcg_gen_add_i32(d, d, a);
+}
+
+static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_shri_i64(a, a, shift);
+ tcg_gen_add_i64(d, d, a);
+}
+
+static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ tcg_gen_shri_vec(vece, a, a, sh);
+ tcg_gen_add_vec(vece, d, d, a);
+}
+
+const GVecGen2i usra_op[4] = {
+ { .fni8 = gen_usra8_i64,
+ .fniv = gen_usra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_8, },
+ { .fni8 = gen_usra16_i64,
+ .fniv = gen_usra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_16, },
+ { .fni4 = gen_usra32_i32,
+ .fniv = gen_usra_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_32, },
+ { .fni8 = gen_usra64_i64,
+ .fniv = gen_usra_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_64, },
+};
+
+static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ uint64_t mask = dup_const(MO_8, 0xff >> shift);
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, shift);
+ tcg_gen_andi_i64(t, t, mask);
+ tcg_gen_andi_i64(d, d, ~mask);
+ tcg_gen_or_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ uint64_t mask = dup_const(MO_16, 0xffff >> shift);
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shri_i64(t, a, shift);
+ tcg_gen_andi_i64(t, t, mask);
+ tcg_gen_andi_i64(d, d, ~mask);
+ tcg_gen_or_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
+{
+ tcg_gen_shri_i32(a, a, shift);
+ tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
+}
+
+static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_shri_i64(a, a, shift);
+ tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
+}
+
+static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ if (sh == 0) {
+ tcg_gen_mov_vec(d, a);
+ } else {
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
+ tcg_gen_shri_vec(vece, t, a, sh);
+ tcg_gen_and_vec(vece, d, d, m);
+ tcg_gen_or_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(m);
+ }
+}
+
+const GVecGen2i sri_op[4] = {
+ { .fni8 = gen_shr8_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_8 },
+ { .fni8 = gen_shr16_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_16 },
+ { .fni4 = gen_shr32_ins_i32,
+ .fniv = gen_shr_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_32 },
+ { .fni8 = gen_shr64_ins_i64,
+ .fniv = gen_shr_ins_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opc = INDEX_op_shri_vec,
+ .vece = MO_64 },
+};
+
+static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ uint64_t mask = dup_const(MO_8, 0xff << shift);
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shli_i64(t, a, shift);
+ tcg_gen_andi_i64(t, t, mask);
+ tcg_gen_andi_i64(d, d, ~mask);
+ tcg_gen_or_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ uint64_t mask = dup_const(MO_16, 0xffff << shift);
+ TCGv_i64 t = tcg_temp_new_i64();
+
+ tcg_gen_shli_i64(t, a, shift);
+ tcg_gen_andi_i64(t, t, mask);
+ tcg_gen_andi_i64(d, d, ~mask);
+ tcg_gen_or_i64(d, d, t);
+ tcg_temp_free_i64(t);
+}
+
+static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
+{
+ tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
+}
+
+static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+ tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
+}
+
+static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+ if (sh == 0) {
+ tcg_gen_mov_vec(d, a);
+ } else {
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
+
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
+ tcg_gen_shli_vec(vece, t, a, sh);
+ tcg_gen_and_vec(vece, d, d, m);
+ tcg_gen_or_vec(vece, d, d, t);
+
+ tcg_temp_free_vec(t);
+ tcg_temp_free_vec(m);
+ }
+}
+
+const GVecGen2i sli_op[4] = {
+ { .fni8 = gen_shl8_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shli_vec,
+ .vece = MO_8 },
+ { .fni8 = gen_shl16_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shli_vec,
+ .vece = MO_16 },
+ { .fni4 = gen_shl32_ins_i32,
+ .fniv = gen_shl_ins_vec,
+ .load_dest = true,
+ .opc = INDEX_op_shli_vec,
+ .vece = MO_32 },
+ { .fni8 = gen_shl64_ins_i64,
+ .fniv = gen_shl_ins_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .opc = INDEX_op_shli_vec,
+ .vece = MO_64 },
+};
+
+static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ gen_helper_neon_mul_u8(a, a, b);
+ gen_helper_neon_add_u8(d, d, a);
+}
+
+static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ gen_helper_neon_mul_u8(a, a, b);
+ gen_helper_neon_sub_u8(d, d, a);
+}
+
+static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ gen_helper_neon_mul_u16(a, a, b);
+ gen_helper_neon_add_u16(d, d, a);
+}
+
+static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ gen_helper_neon_mul_u16(a, a, b);
+ gen_helper_neon_sub_u16(d, d, a);
+}
+
+static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ tcg_gen_mul_i32(a, a, b);
+ tcg_gen_add_i32(d, d, a);
+}
+
+static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ tcg_gen_mul_i32(a, a, b);
+ tcg_gen_sub_i32(d, d, a);
+}
+
+static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ tcg_gen_mul_i64(a, a, b);
+ tcg_gen_add_i64(d, d, a);
+}
+
+static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ tcg_gen_mul_i64(a, a, b);
+ tcg_gen_sub_i64(d, d, a);
+}
+
+static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ tcg_gen_mul_vec(vece, a, a, b);
+ tcg_gen_add_vec(vece, d, d, a);
+}
+
+static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ tcg_gen_mul_vec(vece, a, a, b);
+ tcg_gen_sub_vec(vece, d, d, a);
+}
+
+/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
+ * these tables are shared with AArch64 which does support them.
+ */
+const GVecGen3 mla_op[4] = {
+ { .fni4 = gen_mla8_i32,
+ .fniv = gen_mla_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fni4 = gen_mla16_i32,
+ .fniv = gen_mla_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_mla32_i32,
+ .fniv = gen_mla_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_mla64_i64,
+ .fniv = gen_mla_vec,
+ .opc = INDEX_op_mul_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .vece = MO_64 },
+};
+
+const GVecGen3 mls_op[4] = {
+ { .fni4 = gen_mls8_i32,
+ .fniv = gen_mls_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_8 },
+ { .fni4 = gen_mls16_i32,
+ .fniv = gen_mls_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_16 },
+ { .fni4 = gen_mls32_i32,
+ .fniv = gen_mls_vec,
+ .opc = INDEX_op_mul_vec,
+ .load_dest = true,
+ .vece = MO_32 },
+ { .fni8 = gen_mls64_i64,
+ .fniv = gen_mls_vec,
+ .opc = INDEX_op_mul_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .load_dest = true,
+ .vece = MO_64 },
+};
+
+/* CMTST : test is "if (X & Y != 0)". */
+static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+ tcg_gen_and_i32(d, a, b);
+ tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
+ tcg_gen_neg_i32(d, d);
+}
+
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+ tcg_gen_and_i64(d, a, b);
+ tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
+ tcg_gen_neg_i64(d, d);
+}
+
+static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+ tcg_gen_and_vec(vece, d, a, b);
+ tcg_gen_dupi_vec(vece, a, 0);
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
+}
+
+const GVecGen3 cmtst_op[4] = {
+ { .fni4 = gen_helper_neon_tst_u8,
+ .fniv = gen_cmtst_vec,
+ .vece = MO_8 },
+ { .fni4 = gen_helper_neon_tst_u16,
+ .fniv = gen_cmtst_vec,
+ .vece = MO_16 },
+ { .fni4 = gen_cmtst_i32,
+ .fniv = gen_cmtst_vec,
+ .vece = MO_32 },
+ { .fni8 = gen_cmtst_i64,
+ .fniv = gen_cmtst_vec,
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+ .vece = MO_64 },
+};
+
/* Translate a NEON data processing instruction. Return nonzero if the
instruction is invalid.
We process data in a mixture of 32-bit and 64-bit chunks.
@@ -5709,14 +6157,15 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{
int op;
int q;
- int rd, rn, rm;
+ int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
int size;
int shift;
int pass;
int count;
int pairwise;
int u;
- uint32_t imm, mask;
+ int vec_size;
+ uint32_t imm;
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
TCGv_ptr ptr1, ptr2, ptr3;
TCGv_i64 tmp64;
@@ -5727,7 +6176,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
*/
if (s->fp_excp_el) {
gen_exception_insn(s, 4, EXCP_UDEF,
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
return 0;
}
@@ -5739,6 +6188,11 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
VFP_DREG_N(rn, insn);
VFP_DREG_M(rm, insn);
size = (insn >> 20) & 3;
+ vec_size = q ? 16 : 8;
+ rd_ofs = neon_reg_offset(rd, 0);
+ rn_ofs = neon_reg_offset(rn, 0);
+ rm_ofs = neon_reg_offset(rm, 0);
+
if ((insn & (1 << 23)) == 0) {
/* Three register same length. */
op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
@@ -5763,7 +6217,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
return 1;
}
if (!u) { /* SHA-1 */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
+ if (!dc_isar_feature(aa32_sha1, s)) {
return 1;
}
ptr1 = vfp_reg_ptr(true, rd);
@@ -5773,7 +6227,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
tcg_temp_free_i32(tmp4);
} else { /* SHA-256 */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
+ if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
return 1;
}
ptr1 = vfp_reg_ptr(true, rd);
@@ -5829,8 +6283,100 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
q, rd, rn, rm);
}
return 1;
+
+ case NEON_3R_LOGIC: /* Logic ops. */
+ switch ((u << 2) | size) {
+ case 0: /* VAND */
+ tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ break;
+ case 1: /* VBIC */
+ tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ break;
+ case 2:
+ if (rn == rm) {
+ /* VMOV */
+ tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
+ } else {
+ /* VORR */
+ tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ }
+ break;
+ case 3: /* VORN */
+ tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ break;
+ case 4: /* VEOR */
+ tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ break;
+ case 5: /* VBSL */
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size, &bsl_op);
+ break;
+ case 6: /* VBIT */
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size, &bit_op);
+ break;
+ case 7: /* VBIF */
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size, &bif_op);
+ break;
+ }
+ return 0;
+
+ case NEON_3R_VADD_VSUB:
+ if (u) {
+ tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ } else {
+ tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ }
+ return 0;
+
+ case NEON_3R_VMUL: /* VMUL */
+ if (u) {
+ /* Polynomial case allows only P8 and is handled below. */
+ if (size != 0) {
+ return 1;
+ }
+ } else {
+ tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ return 0;
+ }
+ break;
+
+ case NEON_3R_VML: /* VMLA, VMLS */
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
+ u ? &mls_op[size] : &mla_op[size]);
+ return 0;
+
+ case NEON_3R_VTST_VCEQ:
+ if (u) { /* VCEQ */
+ tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+ } else { /* VTST */
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size, &cmtst_op[size]);
+ }
+ return 0;
+
+ case NEON_3R_VCGT:
+ tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
+ rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
+ return 0;
+
+ case NEON_3R_VCGE:
+ tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
+ rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
+ return 0;
}
- if (size == 3 && op != NEON_3R_LOGIC) {
+
+ if (size == 3) {
/* 64-bit element instructions. */
for (pass = 0; pass < (q ? 2 : 1); pass++) {
neon_load_reg64(cpu_V0, rn + pass);
@@ -5886,13 +6432,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
cpu_V1, cpu_V0);
}
break;
- case NEON_3R_VADD_VSUB:
- if (u) {
- tcg_gen_sub_i64(CPU_V001);
- } else {
- tcg_gen_add_i64(CPU_V001);
- }
- break;
default:
abort();
}
@@ -5942,12 +6481,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
return 1;
}
break;
- case NEON_3R_VMUL:
- if (u && (size != 0)) {
- /* UNDEF on invalid size for polynomial subcase */
- return 1;
- }
- break;
case NEON_3R_VFM_VQRDMLSH:
if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
return 1;
@@ -5988,52 +6521,12 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_3R_VRHADD:
GEN_NEON_INTEGER_OP(rhadd);
break;
- case NEON_3R_LOGIC: /* Logic ops. */
- switch ((u << 2) | size) {
- case 0: /* VAND */
- tcg_gen_and_i32(tmp, tmp, tmp2);
- break;
- case 1: /* BIC */
- tcg_gen_andc_i32(tmp, tmp, tmp2);
- break;
- case 2: /* VORR */
- tcg_gen_or_i32(tmp, tmp, tmp2);
- break;
- case 3: /* VORN */
- tcg_gen_orc_i32(tmp, tmp, tmp2);
- break;
- case 4: /* VEOR */
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- break;
- case 5: /* VBSL */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp, tmp2, tmp3);
- tcg_temp_free_i32(tmp3);
- break;
- case 6: /* VBIT */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp, tmp3, tmp2);
- tcg_temp_free_i32(tmp3);
- break;
- case 7: /* VBIF */
- tmp3 = neon_load_reg(rd, pass);
- gen_neon_bsl(tmp, tmp3, tmp, tmp2);
- tcg_temp_free_i32(tmp3);
- break;
- }
- break;
case NEON_3R_VHSUB:
GEN_NEON_INTEGER_OP(hsub);
break;
case NEON_3R_VQSUB:
GEN_NEON_INTEGER_OP_ENV(qsub);
break;
- case NEON_3R_VCGT:
- GEN_NEON_INTEGER_OP(cgt);
- break;
- case NEON_3R_VCGE:
- GEN_NEON_INTEGER_OP(cge);
- break;
case NEON_3R_VSHL:
GEN_NEON_INTEGER_OP(shl);
break;
@@ -6061,61 +6554,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tmp2 = neon_load_reg(rd, pass);
gen_neon_add(size, tmp, tmp2);
break;
- case NEON_3R_VADD_VSUB:
- if (!u) { /* VADD */
- gen_neon_add(size, tmp, tmp2);
- } else { /* VSUB */
- switch (size) {
- case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
- default: abort();
- }
- }
- break;
- case NEON_3R_VTST_VCEQ:
- if (!u) { /* VTST */
- switch (size) {
- case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
- case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
- default: abort();
- }
- } else { /* VCEQ */
- switch (size) {
- case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
- case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
- default: abort();
- }
- }
- break;
- case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
- switch (size) {
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
- default: abort();
- }
- tcg_temp_free_i32(tmp2);
- tmp2 = neon_load_reg(rd, pass);
- if (u) { /* VMLS */
- gen_neon_rsb(size, tmp, tmp2);
- } else { /* VMLA */
- gen_neon_add(size, tmp, tmp2);
- }
- break;
case NEON_3R_VMUL:
- if (u) { /* polynomial */
- gen_helper_neon_mul_p8(tmp, tmp, tmp2);
- } else { /* Integer */
- switch (size) {
- case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
- case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
- default: abort();
- }
- }
+ /* VMUL.P8; other cases already eliminated. */
+ gen_helper_neon_mul_p8(tmp, tmp, tmp2);
break;
case NEON_3R_VPMAX:
GEN_NEON_INTEGER_OP(pmax);
@@ -6297,8 +6738,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
size--;
}
shift = (insn >> 16) & ((1 << (3 + size)) - 1);
- /* To avoid excessive duplication of ops we implement shift
- by immediate using the variable shift operations. */
if (op < 8) {
/* Shift by immediate:
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
@@ -6310,43 +6749,99 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
/* Right shifts are encoded as N - shift, where N is the
element size in bits. */
- if (op <= 4)
+ if (op <= 4) {
shift = shift - (1 << (size + 3));
+ }
+
+ switch (op) {
+ case 0: /* VSHR */
+ /* Right shift comes here negative. */
+ shift = -shift;
+ /* Shifts larger than the element size are architecturally
+ * valid. Unsigned results in all zeros; signed results
+ * in all sign bits.
+ */
+ if (!u) {
+ tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
+ MIN(shift, (8 << size) - 1),
+ vec_size, vec_size);
+ } else if (shift >= 8 << size) {
+ tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
+ } else {
+ tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ }
+ return 0;
+
+ case 1: /* VSRA */
+ /* Right shift comes here negative. */
+ shift = -shift;
+ /* Shifts larger than the element size are architecturally
+ * valid. Unsigned results in all zeros; signed results
+ * in all sign bits.
+ */
+ if (!u) {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
+ MIN(shift, (8 << size) - 1),
+ &ssra_op[size]);
+ } else if (shift >= 8 << size) {
+ /* rd += 0 */
+ } else {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
+ shift, &usra_op[size]);
+ }
+ return 0;
+
+ case 4: /* VSRI */
+ if (!u) {
+ return 1;
+ }
+ /* Right shift comes here negative. */
+ shift = -shift;
+ /* Shift out of range leaves destination unchanged. */
+ if (shift < 8 << size) {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
+ shift, &sri_op[size]);
+ }
+ return 0;
+
+ case 5: /* VSHL, VSLI */
+ if (u) { /* VSLI */
+ /* Shift out of range leaves destination unchanged. */
+ if (shift < 8 << size) {
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
+ vec_size, shift, &sli_op[size]);
+ }
+ } else { /* VSHL */
+ /* Shifts larger than the element size are
+ * architecturally valid and results in zero.
+ */
+ if (shift >= 8 << size) {
+ tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
+ } else {
+ tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
+ vec_size, vec_size);
+ }
+ }
+ return 0;
+ }
+
if (size == 3) {
count = q + 1;
} else {
count = q ? 4: 2;
}
- switch (size) {
- case 0:
- imm = (uint8_t) shift;
- imm |= imm << 8;
- imm |= imm << 16;
- break;
- case 1:
- imm = (uint16_t) shift;
- imm |= imm << 16;
- break;
- case 2:
- case 3:
- imm = shift;
- break;
- default:
- abort();
- }
+
+ /* To avoid excessive duplication of ops we implement shift
+ * by immediate using the variable shift operations.
+ */
+ imm = dup_const(size, shift);
for (pass = 0; pass < count; pass++) {
if (size == 3) {
neon_load_reg64(cpu_V0, rm + pass);
tcg_gen_movi_i64(cpu_V1, imm);
switch (op) {
- case 0: /* VSHR */
- case 1: /* VSRA */
- if (u)
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
- else
- gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
- break;
case 2: /* VRSHR */
case 3: /* VRSRA */
if (u)
@@ -6354,10 +6849,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
else
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
break;
- case 4: /* VSRI */
- case 5: /* VSHL, VSLI */
- gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
- break;
case 6: /* VQSHLU */
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
cpu_V0, cpu_V1);
@@ -6371,26 +6862,13 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
cpu_V0, cpu_V1);
}
break;
+ default:
+ g_assert_not_reached();
}
- if (op == 1 || op == 3) {
+ if (op == 3) {
/* Accumulate. */
neon_load_reg64(cpu_V1, rd + pass);
tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
- } else if (op == 4 || (op == 5 && u)) {
- /* Insert */
- neon_load_reg64(cpu_V1, rd + pass);
- uint64_t mask;
- if (shift < -63 || shift > 63) {
- mask = 0;
- } else {
- if (op == 4) {
- mask = 0xffffffffffffffffull >> -shift;
- } else {
- mask = 0xffffffffffffffffull << shift;
- }
- }
- tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
- tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
}
neon_store_reg64(cpu_V0, rd + pass);
} else { /* size < 3 */
@@ -6399,23 +6877,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tmp2 = tcg_temp_new_i32();
tcg_gen_movi_i32(tmp2, imm);
switch (op) {
- case 0: /* VSHR */
- case 1: /* VSRA */
- GEN_NEON_INTEGER_OP(shl);
- break;
case 2: /* VRSHR */
case 3: /* VRSRA */
GEN_NEON_INTEGER_OP(rshl);
break;
- case 4: /* VSRI */
- case 5: /* VSHL, VSLI */
- switch (size) {
- case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
- case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
- case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
- default: abort();
- }
- break;
case 6: /* VQSHLU */
switch (size) {
case 0:
@@ -6437,50 +6902,16 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case 7: /* VQSHL */
GEN_NEON_INTEGER_OP_ENV(qshl);
break;
+ default:
+ g_assert_not_reached();
}
tcg_temp_free_i32(tmp2);
- if (op == 1 || op == 3) {
+ if (op == 3) {
/* Accumulate. */
tmp2 = neon_load_reg(rd, pass);
gen_neon_add(size, tmp, tmp2);
tcg_temp_free_i32(tmp2);
- } else if (op == 4 || (op == 5 && u)) {
- /* Insert */
- switch (size) {
- case 0:
- if (op == 4)
- mask = 0xff >> -shift;
- else
- mask = (uint8_t)(0xff << shift);
- mask |= mask << 8;
- mask |= mask << 16;
- break;
- case 1:
- if (op == 4)
- mask = 0xffff >> -shift;
- else
- mask = (uint16_t)(0xffff << shift);
- mask |= mask << 16;
- break;
- case 2:
- if (shift < -31 || shift > 31) {
- mask = 0;
- } else {
- if (op == 4)
- mask = 0xffffffffu >> -shift;
- else
- mask = 0xffffffffu << shift;
- }
- break;
- default:
- abort();
- }
- tmp2 = neon_load_reg(rd, pass);
- tcg_gen_andi_i32(tmp, tmp, mask);
- tcg_gen_andi_i32(tmp2, tmp2, ~mask);
- tcg_gen_or_i32(tmp, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
}
neon_store_reg(rd, pass, tmp);
}
@@ -6629,7 +7060,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
return 1;
}
} else { /* (insn & 0x00380080) == 0 */
- int invert;
+ int invert, reg_ofs, vec_size;
+
if (q && (rd & 1)) {
return 1;
}
@@ -6669,8 +7101,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
break;
case 14:
imm |= (imm << 8) | (imm << 16) | (imm << 24);
- if (invert)
+ if (invert) {
imm = ~imm;
+ }
break;
case 15:
if (invert) {
@@ -6680,36 +7113,45 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
break;
}
- if (invert)
+ if (invert) {
imm = ~imm;
+ }
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- if (op & 1 && op < 12) {
- tmp = neon_load_reg(rd, pass);
- if (invert) {
- /* The immediate value has already been inverted, so
- BIC becomes AND. */
- tcg_gen_andi_i32(tmp, tmp, imm);
- } else {
- tcg_gen_ori_i32(tmp, tmp, imm);
- }
+ reg_ofs = neon_reg_offset(rd, 0);
+ vec_size = q ? 16 : 8;
+
+ if (op & 1 && op < 12) {
+ if (invert) {
+ /* The immediate value has already been inverted,
+ * so BIC becomes AND.
+ */
+ tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
+ vec_size, vec_size);
} else {
- /* VMOV, VMVN. */
- tmp = tcg_temp_new_i32();
- if (op == 14 && invert) {
+ tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
+ vec_size, vec_size);
+ }
+ } else {
+ /* VMOV, VMVN. */
+ if (op == 14 && invert) {
+ TCGv_i64 t64 = tcg_temp_new_i64();
+
+ for (pass = 0; pass <= q; ++pass) {
+ uint64_t val = 0;
int n;
- uint32_t val;
- val = 0;
- for (n = 0; n < 4; n++) {
- if (imm & (1 << (n + (pass & 1) * 4)))
- val |= 0xff << (n * 8);
+
+ for (n = 0; n < 8; n++) {
+ if (imm & (1 << (n + pass * 8))) {
+ val |= 0xffull << (n * 8);
+ }
}
- tcg_gen_movi_i32(tmp, val);
- } else {
- tcg_gen_movi_i32(tmp, imm);
+ tcg_gen_movi_i64(t64, val);
+ neon_store_reg64(t64, rd + pass);
}
+ tcg_temp_free_i64(t64);
+ } else {
+ tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
}
- neon_store_reg(rd, pass, tmp);
}
}
} else { /* (insn & 0x00800010 == 0x00800000) */
@@ -6768,7 +7210,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
if (op == 14 && size == 2) {
TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
+ if (!dc_isar_feature(aa32_pmull, s)) {
return 1;
}
tcg_rn = tcg_temp_new_i64();
@@ -7085,7 +7527,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
{
NeonGenThreeOpEnvFn *fn;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
+ if (!dc_isar_feature(aa32_rdm, s)) {
return 1;
}
if (u && ((rd | rn) & 1)) {
@@ -7359,8 +7801,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
break;
}
case NEON_2RM_AESE: case NEON_2RM_AESMC:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
- || ((rm | rd) & 1)) {
+ if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
return 1;
}
ptr1 = vfp_reg_ptr(true, rd);
@@ -7381,8 +7822,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tmp3);
break;
case NEON_2RM_SHA1H:
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
- || ((rm | rd) & 1)) {
+ if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
return 1;
}
ptr1 = vfp_reg_ptr(true, rd);
@@ -7399,10 +7839,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
}
/* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
if (q) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
+ if (!dc_isar_feature(aa32_sha2, s)) {
return 1;
}
- } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
+ } else if (!dc_isar_feature(aa32_sha1, s)) {
return 1;
}
ptr1 = vfp_reg_ptr(true, rd);
@@ -7415,6 +7855,14 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_ptr(ptr1);
tcg_temp_free_ptr(ptr2);
break;
+
+ case NEON_2RM_VMVN:
+ tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
+ break;
+ case NEON_2RM_VNEG:
+ tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
+ break;
+
default:
elementwise:
for (pass = 0; pass < (q ? 4 : 2); pass++) {
@@ -7455,9 +7903,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
case NEON_2RM_VCNT:
gen_helper_neon_cnt_u8(tmp, tmp);
break;
- case NEON_2RM_VMVN:
- tcg_gen_not_i32(tmp, tmp);
- break;
case NEON_2RM_VQABS:
switch (size) {
case 0:
@@ -7530,11 +7975,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
default: abort();
}
break;
- case NEON_2RM_VNEG:
- tmp2 = tcg_const_i32(0);
- gen_neon_rsb(size, tmp, tmp2);
- tcg_temp_free_i32(tmp2);
- break;
case NEON_2RM_VCGT0_F:
{
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
@@ -7757,28 +8197,25 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tmp);
} else if ((insn & 0x380) == 0) {
/* VDUP */
+ int element;
+ TCGMemOp size;
+
if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
return 1;
}
- if (insn & (1 << 19)) {
- tmp = neon_load_reg(rm, 1);
- } else {
- tmp = neon_load_reg(rm, 0);
- }
if (insn & (1 << 16)) {
- gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
+ size = MO_8;
+ element = (insn >> 17) & 7;
} else if (insn & (1 << 17)) {
- if ((insn >> 18) & 1)
- gen_neon_dup_high16(tmp);
- else
- gen_neon_dup_low16(tmp);
- }
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
- tmp2 = tcg_temp_new_i32();
- tcg_gen_mov_i32(tmp2, tmp);
- neon_store_reg(rd, pass, tmp2);
+ size = MO_16;
+ element = (insn >> 18) & 3;
+ } else {
+ size = MO_32;
+ element = (insn >> 19) & 1;
}
- tcg_temp_free_i32(tmp);
+ tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
+ neon_element_offset(rm, element, size),
+ q ? 16 : 8, q ? 16 : 8);
} else {
return 1;
}
@@ -7813,8 +8250,8 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
int size = extract32(insn, 20, 1);
data = extract32(insn, 23, 2); /* rot */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
+ if (!dc_isar_feature(aa32_vcma, s)
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
return 1;
}
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
@@ -7822,15 +8259,15 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
int size = extract32(insn, 20, 1);
data = extract32(insn, 24, 1); /* rot */
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
+ if (!dc_isar_feature(aa32_vcma, s)
+ || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
return 1;
}
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
} else if ((insn & 0xfeb00f00) == 0xfc200d00) {
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
bool u = extract32(insn, 4, 1);
- if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
+ if (!dc_isar_feature(aa32_dp, s)) {
return 1;
}
fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
@@ -7840,7 +8277,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
if (s->fp_excp_el) {
gen_exception_insn(s, 4, EXCP_UDEF,
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
return 0;
}
if (!s->vfp_enabled) {
@@ -7892,11 +8329,11 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
int size = extract32(insn, 23, 1);
int index;
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
+ if (!dc_isar_feature(aa32_vcma, s)) {
return 1;
}
if (size == 0) {
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
+ if (!dc_isar_feature(aa32_fp16_arith, s)) {
return 1;
}
/* For fp16, rm is just Vm, and index is M. */
@@ -7913,7 +8350,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
} else if ((insn & 0xffb00f00) == 0xfe200d00) {
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
int u = extract32(insn, 4, 1);
- if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
+ if (!dc_isar_feature(aa32_dp, s)) {
return 1;
}
fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
@@ -7926,7 +8363,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
if (s->fp_excp_el) {
gen_exception_insn(s, 4, EXCP_UDEF,
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
+ syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
return 0;
}
if (!s->vfp_enabled) {
@@ -8889,8 +9326,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
* op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
* Bits 8, 10 and 11 should be zero.
*/
- if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
- (c & 0xd) != 0) {
+ if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
goto illegal_op;
}
@@ -9758,7 +10194,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
case 1:
case 3:
/* SDIV, UDIV */
- if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
+ if (!dc_isar_feature(arm_div, s)) {
goto illegal_op;
}
if (((insn >> 5) & 7) || (rd != 15)) {
@@ -10785,7 +11221,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
case 0x28:
case 0x29:
case 0x2a:
- if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
+ if (!dc_isar_feature(aa32_crc32, s)) {
goto illegal_op;
}
break;
@@ -10966,7 +11402,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
tmp2 = load_reg(s, rm);
if ((op & 0x50) == 0x10) {
/* sdiv, udiv */
- if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
+ if (!dc_isar_feature(thumb_div, s)) {
goto illegal_op;
}
if (op & 0x20)
@@ -12586,6 +13022,7 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
CPUARMState *env = cs->env_ptr;
ARMCPU *cpu = arm_env_get_cpu(env);
+ dc->isar = &cpu->isar;
dc->pc = dc->base.pc_first;
dc->condjmp = 0;
@@ -12703,7 +13140,6 @@ static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
tcg_gen_movi_i32(tmp, 0);
store_cpu_field(tmp, condexec_bits);
}
- tcg_clear_temp_count();
}
static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
@@ -13092,11 +13528,6 @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
translator_loop(ops, &dc.base, cpu, tb);
}
-static const char *cpu_mode_names[16] = {
- "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
- "???", "???", "hyp", "und", "???", "???", "???", "sys"
-};
-
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
int flags)
{
@@ -13162,7 +13593,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
psr & CPSR_V ? 'V' : '-',
psr & CPSR_T ? 'T' : 'A',
ns_status,
- cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
+ aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
}
if (flags & CPU_DUMP_FPU) {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index c1b65f3efb..1550aa8bc7 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -7,6 +7,7 @@
/* internal defines */
typedef struct DisasContext {
DisasContextBase base;
+ const ARMISARegisters *isar;
target_ulong pc;
target_ulong page_start;
@@ -190,4 +191,24 @@ static inline TCGv_i32 get_ahp_flag(void)
return ret;
}
+
+/* Vector operations shared between ARM and AArch64. */
+extern const GVecGen3 bsl_op;
+extern const GVecGen3 bit_op;
+extern const GVecGen3 bif_op;
+extern const GVecGen3 mla_op[4];
+extern const GVecGen3 mls_op[4];
+extern const GVecGen3 cmtst_op[4];
+extern const GVecGen2i ssra_op[4];
+extern const GVecGen2i usra_op[4];
+extern const GVecGen2i sri_op[4];
+extern const GVecGen2i sli_op[4];
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
+
+/*
+ * Forward to the isar_feature_* tests given a DisasContext pointer.
+ */
+#define dc_isar_feature(name, ctx) \
+ ({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
+
#endif /* TARGET_ARM_TRANSLATE_H */
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f0d9f7cf49..1469a1be01 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5123,14 +5123,15 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
* NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
* cs->nr_threads hasn't be populated yet and the checking is incorrect.
*/
- if (IS_AMD_CPU(env) &&
- !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
- cs->nr_threads > 1 && !ht_warned) {
- error_report("This family of AMD CPU doesn't support "
- "hyperthreading(%d). Please configure -smp "
- "options properly or try enabling topoext feature.",
- cs->nr_threads);
- ht_warned = true;
+ if (IS_AMD_CPU(env) &&
+ !(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
+ cs->nr_threads > 1 && !ht_warned) {
+ warn_report("This family of AMD CPU doesn't support "
+ "hyperthreading(%d)",
+ cs->nr_threads);
+ error_printf("Please configure -smp options properly"
+ " or try enabling topoext feature.\n");
+ ht_warned = true;
}
x86_cpu_apic_realize(cpu, &local_err);
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 497706b669..e217fb3e36 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -113,11 +113,20 @@ 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->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 {
+#if defined(CONFIG_NANOMIPS_DIS)
+ info->print_insn = print_insn_nanomips;
+#endif
+ }
}
static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
diff --git a/target/mips/mips-defs.h b/target/mips/mips-defs.h
index 71ea4ef892..5177618615 100644
--- a/target/mips/mips-defs.h
+++ b/target/mips/mips-defs.h
@@ -64,9 +64,11 @@
#define INSN_LOONGSON2E 0x0001000000000000ULL
#define INSN_LOONGSON2F 0x0002000000000000ULL
#define INSN_VR54XX 0x0004000000000000ULL
+#define INSN_R5900 0x0008000000000000ULL
/*
* bits 56-63: vendor-specific ASEs
*/
+#define ASE_MMI 0x0100000000000000ULL
/* MIPS CPU defines. */
#define CPU_MIPS1 (ISA_MIPS1)
@@ -74,6 +76,7 @@
#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3)
#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4)
#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX)
+#define CPU_R5900 (CPU_MIPS3 | INSN_R5900)
#define CPU_LOONGSON2E (CPU_MIPS3 | INSN_LOONGSON2E)
#define CPU_LOONGSON2F (CPU_MIPS3 | INSN_LOONGSON2F)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 3a0bdd55c8..51a5488da4 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1,5 +1,5 @@
/*
- * MIPS32 emulation for qemu: main translation routines.
+ * MIPS emulation for QEMU - main translation routines
*
* Copyright (c) 2004-2005 Jocelyn Mayer
* Copyright (c) 2006 Marius Groeger (FPU operations)
@@ -463,8 +463,10 @@ enum {
OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
OPC_SEB = (0x10 << 6) | OPC_BSHFL,
OPC_SEH = (0x18 << 6) | OPC_BSHFL,
- OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
- OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
+ OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
+ OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
+ OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
+ OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
};
@@ -474,8 +476,14 @@ enum {
enum {
OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
- OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
- OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
+ OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
+ OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
+ OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
+ OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
+ OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
+ OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
+ OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
+ OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
};
@@ -1927,6 +1935,440 @@ enum {
OPC_MXU_Q8MACSU = 0x01,
};
+/*
+ * Overview of the TX79-specific instruction set
+ * =============================================
+ *
+ * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
+ * are only used by the specific quadword (128-bit) LQ/SQ load/store
+ * instructions and certain multimedia instructions (MMIs). These MMIs
+ * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
+ * or sixteen 8-bit paths.
+ *
+ * Reference:
+ *
+ * The Toshiba TX System RISC TX79 Core Architecture manual,
+ * https://wiki.qemu.org/File:C790.pdf
+ *
+ * Three-Operand Multiply and Multiply-Add (4 instructions)
+ * --------------------------------------------------------
+ * MADD [rd,] rs, rt Multiply/Add
+ * MADDU [rd,] rs, rt Multiply/Add Unsigned
+ * MULT [rd,] rs, rt Multiply (3-operand)
+ * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
+ *
+ * Multiply Instructions for Pipeline 1 (10 instructions)
+ * ------------------------------------------------------
+ * MULT1 [rd,] rs, rt Multiply Pipeline 1
+ * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
+ * DIV1 rs, rt Divide Pipeline 1
+ * DIVU1 rs, rt Divide Unsigned Pipeline 1
+ * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
+ * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
+ * MFHI1 rd Move From HI1 Register
+ * MFLO1 rd Move From LO1 Register
+ * MTHI1 rs Move To HI1 Register
+ * MTLO1 rs Move To LO1 Register
+ *
+ * Arithmetic (19 instructions)
+ * ----------------------------
+ * PADDB rd, rs, rt Parallel Add Byte
+ * PSUBB rd, rs, rt Parallel Subtract Byte
+ * PADDH rd, rs, rt Parallel Add Halfword
+ * PSUBH rd, rs, rt Parallel Subtract Halfword
+ * PADDW rd, rs, rt Parallel Add Word
+ * PSUBW rd, rs, rt Parallel Subtract Word
+ * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
+ * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
+ * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
+ * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
+ * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
+ * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
+ * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
+ * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
+ * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
+ * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
+ * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
+ * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
+ * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
+ *
+ * Min/Max (4 instructions)
+ * ------------------------
+ * PMAXH rd, rs, rt Parallel Maximum Halfword
+ * PMINH rd, rs, rt Parallel Minimum Halfword
+ * PMAXW rd, rs, rt Parallel Maximum Word
+ * PMINW rd, rs, rt Parallel Minimum Word
+ *
+ * Absolute (2 instructions)
+ * -------------------------
+ * PABSH rd, rt Parallel Absolute Halfword
+ * PABSW rd, rt Parallel Absolute Word
+ *
+ * Logical (4 instructions)
+ * ------------------------
+ * PAND rd, rs, rt Parallel AND
+ * POR rd, rs, rt Parallel OR
+ * PXOR rd, rs, rt Parallel XOR
+ * PNOR rd, rs, rt Parallel NOR
+ *
+ * Shift (9 instructions)
+ * ----------------------
+ * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
+ * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
+ * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
+ * PSLLW rd, rt, sa Parallel Shift Left Logical Word
+ * PSRLW rd, rt, sa Parallel Shift Right Logical Word
+ * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
+ * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
+ * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
+ * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
+ *
+ * Compare (6 instructions)
+ * ------------------------
+ * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
+ * PCEQB rd, rs, rt Parallel Compare for Equal Byte
+ * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
+ * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
+ * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
+ * PCEQW rd, rs, rt Parallel Compare for Equal Word
+ *
+ * LZC (1 instruction)
+ * -------------------
+ * PLZCW rd, rs Parallel Leading Zero or One Count Word
+ *
+ * Quadword Load and Store (2 instructions)
+ * ----------------------------------------
+ * LQ rt, offset(base) Load Quadword
+ * SQ rt, offset(base) Store Quadword
+ *
+ * Multiply and Divide (19 instructions)
+ * -------------------------------------
+ * PMULTW rd, rs, rt Parallel Multiply Word
+ * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
+ * PDIVW rs, rt Parallel Divide Word
+ * PDIVUW rs, rt Parallel Divide Unsigned Word
+ * PMADDW rd, rs, rt Parallel Multiply-Add Word
+ * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
+ * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
+ * PMULTH rd, rs, rt Parallel Multiply Halfword
+ * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
+ * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
+ * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
+ * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
+ * PDIVBW rs, rt Parallel Divide Broadcast Word
+ * PMFHI rd Parallel Move From HI Register
+ * PMFLO rd Parallel Move From LO Register
+ * PMTHI rs Parallel Move To HI Register
+ * PMTLO rs Parallel Move To LO Register
+ * PMFHL rd Parallel Move From HI/LO Register
+ * PMTHL rs Parallel Move To HI/LO Register
+ *
+ * Pack/Extend (11 instructions)
+ * -----------------------------
+ * PPAC5 rd, rt Parallel Pack to 5 bits
+ * PPACB rd, rs, rt Parallel Pack to Byte
+ * PPACH rd, rs, rt Parallel Pack to Halfword
+ * PPACW rd, rs, rt Parallel Pack to Word
+ * PEXT5 rd, rt Parallel Extend Upper from 5 bits
+ * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
+ * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
+ * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
+ * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
+ * PEXTUW rd, rs, rt Parallel Extend Upper from Word
+ * PEXTLW rd, rs, rt Parallel Extend Lower from Word
+ *
+ * Others (16 instructions)
+ * ------------------------
+ * PCPYH rd, rt Parallel Copy Halfword
+ * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
+ * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
+ * PREVH rd, rt Parallel Reverse Halfword
+ * PINTH rd, rs, rt Parallel Interleave Halfword
+ * PINTEH rd, rs, rt Parallel Interleave Even Halfword
+ * PEXEH rd, rt Parallel Exchange Even Halfword
+ * PEXCH rd, rt Parallel Exchange Center Halfword
+ * PEXEW rd, rt Parallel Exchange Even Word
+ * PEXCW rd, rt Parallel Exchange Center Word
+ * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
+ * MFSA rd Move from Shift Amount Register
+ * MTSA rs Move to Shift Amount Register
+ * MTSAB rs, immediate Move Byte Count to Shift Amount Register
+ * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
+ * PROT3W rd, rt Parallel Rotate 3 Words
+ *
+ * The TX79-specific Multimedia Instruction encodings
+ * ==================================================
+ *
+ * TX79 Multimedia Instruction encoding table keys:
+ *
+ * * This code is reserved for future use. An attempt to execute it
+ * causes a Reserved Instruction exception.
+ * % This code indicates an instruction class. The instruction word
+ * must be further decoded by examining additional tables that show
+ * the values for other instruction fields.
+ * # This code is reserved for the unsupported instructions DMULT,
+ * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
+ * to execute it causes a Reserved Instruction exception.
+ *
+ * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
+ *
+ * 31 26 0
+ * +--------+----------------------------------------+
+ * | opcode | |
+ * +--------+----------------------------------------+
+ *
+ * opcode bits 28..26
+ * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
+ * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
+ * -------+-------+-------+-------+-------+-------+-------+-------+-------
+ * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
+ * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
+ * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
+ * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
+ * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
+ * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
+ * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
+ * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
+ */
+
+enum {
+ TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
+ TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
+ TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
+};
+
+/*
+ * TX79 Multimedia Instructions with opcode field = MMI:
+ *
+ * 31 26 5 0
+ * +--------+-------------------------------+--------+
+ * | MMI | |function|
+ * +--------+-------------------------------+--------+
+ *
+ * function bits 2..0
+ * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
+ * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
+ * -------+-------+-------+-------+-------+-------+-------+-------+-------
+ * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
+ * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
+ * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
+ * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
+ * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
+ * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
+ * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
+ * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
+ */
+
+#define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
+enum {
+ TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
+ TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
+ TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
+ TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
+ TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
+ TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
+ TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
+ TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
+ TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
+ TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
+ TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
+ TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
+ TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
+ TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
+ TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
+ TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
+ TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
+ TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
+ TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
+ TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
+ TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
+ TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
+ TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
+ TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
+ TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
+};
+
+/*
+ * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
+ *
+ * 31 26 10 6 5 0
+ * +--------+----------------------+--------+--------+
+ * | MMI | |function| MMI0 |
+ * +--------+----------------------+--------+--------+
+ *
+ * function bits 7..6
+ * bits | 0 | 1 | 2 | 3
+ * 10..8 | 00 | 01 | 10 | 11
+ * -------+-------+-------+-------+-------
+ * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
+ * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
+ * 2 010 | PADDB | PSUBB | PCGTB | *
+ * 3 011 | * | * | * | *
+ * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
+ * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
+ * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
+ * 7 111 | * | * | PEXT5 | PPAC5
+ */
+
+#define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+enum {
+ TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
+ TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
+};
+
+/*
+ * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
+ *
+ * 31 26 10 6 5 0
+ * +--------+----------------------+--------+--------+
+ * | MMI | |function| MMI1 |
+ * +--------+----------------------+--------+--------+
+ *
+ * function bits 7..6
+ * bits | 0 | 1 | 2 | 3
+ * 10..8 | 00 | 01 | 10 | 11
+ * -------+-------+-------+-------+-------
+ * 0 000 | * | PABSW | PCEQW | PMINW
+ * 1 001 | PADSBH| PABSH | PCEQH | PMINH
+ * 2 010 | * | * | PCEQB | *
+ * 3 011 | * | * | * | *
+ * 4 100 | PADDUW| PSUBUW| PEXTUW| *
+ * 5 101 | PADDUH| PSUBUH| PEXTUH| *
+ * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
+ * 7 111 | * | * | * | *
+ */
+
+#define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+enum {
+ TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
+ TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
+};
+
+/*
+ * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
+ *
+ * 31 26 10 6 5 0
+ * +--------+----------------------+--------+--------+
+ * | MMI | |function| MMI2 |
+ * +--------+----------------------+--------+--------+
+ *
+ * function bits 7..6
+ * bits | 0 | 1 | 2 | 3
+ * 10..8 | 00 | 01 | 10 | 11
+ * -------+-------+-------+-------+-------
+ * 0 000 | PMADDW| * | PSLLVW| PSRLVW
+ * 1 001 | PMSUBW| * | * | *
+ * 2 010 | PMFHI | PMFLO | PINTH | *
+ * 3 011 | PMULTW| PDIVW | PCPYLD| *
+ * 4 100 | PMADDH| PHMADH| PAND | PXOR
+ * 5 101 | PMSUBH| PHMSBH| * | *
+ * 6 110 | * | * | PEXEH | PREVH
+ * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
+ */
+
+#define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+enum {
+ TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
+ TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
+};
+
+/*
+ * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
+ *
+ * 31 26 10 6 5 0
+ * +--------+----------------------+--------+--------+
+ * | MMI | |function| MMI3 |
+ * +--------+----------------------+--------+--------+
+ *
+ * function bits 7..6
+ * bits | 0 | 1 | 2 | 3
+ * 10..8 | 00 | 01 | 10 | 11
+ * -------+-------+-------+-------+-------
+ * 0 000 |PMADDUW| * | * | PSRAVW
+ * 1 001 | * | * | * | *
+ * 2 010 | PMTHI | PMTLO | PINTEH| *
+ * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
+ * 4 100 | * | * | POR | PNOR
+ * 5 101 | * | * | * | *
+ * 6 110 | * | * | PEXCH | PCPYH
+ * 7 111 | * | * | PEXCW | *
+ */
+
+#define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
+enum {
+ TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
+ TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
+};
/* global register indices */
static TCGv cpu_gpr[32], cpu_PC;
@@ -2438,6 +2880,21 @@ static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
}
}
+/*
+ * The Linux kernel traps certain reserved instruction exceptions to
+ * emulate the corresponding instructions. QEMU is the kernel in user
+ * mode, so those traps are emulated by accepting the instructions.
+ *
+ * A reserved instruction exception is generated for flagged CPUs if
+ * QEMU runs in system mode.
+ */
+static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
+{
+#ifndef CONFIG_USER_ONLY
+ check_insn_opc_removed(ctx, flags);
+#endif
+}
+
/* This code generates a "reserved instruction" exception if the
CPU does not support 64-bit paired-single (PS) floating point data type */
static inline void check_ps(DisasContext *ctx)
@@ -2532,6 +2989,35 @@ static inline void check_nms(DisasContext *ctx)
}
}
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
+ * Config2 TL, and Config5 L2C are unset.
+ */
+static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
+{
+ if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
+ !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
+ !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
+ !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
+ !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
+ !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
+ {
+ generate_exception_end(ctx, EXCP_RI);
+ }
+}
+
+/*
+ * This code generates a "reserved instruction" exception if the
+ * Config5 EVA bit is NOT set.
+ */
+static inline void check_eva(DisasContext *ctx)
+{
+ if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
+ 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
@@ -3795,17 +4281,21 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
/* Arithmetic on HI/LO registers */
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
{
- if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
+ if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
+ opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
/* Treat as NOP. */
return;
}
if (acc != 0) {
- check_dsp(ctx);
+ if (!(ctx->insn_flags & INSN_R5900)) {
+ check_dsp(ctx);
+ }
}
switch (opc) {
case OPC_MFHI:
+ case TX79_MMI_MFHI1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
@@ -3816,6 +4306,7 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MFLO:
+ case TX79_MMI_MFLO1:
#if defined(TARGET_MIPS64)
if (acc != 0) {
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
@@ -3826,6 +4317,7 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MTHI:
+ case TX79_MMI_MTHI1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
@@ -3840,6 +4332,7 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
}
break;
case OPC_MTLO:
+ case TX79_MMI_MTLO1:
if (reg != 0) {
#if defined(TARGET_MIPS64)
if (acc != 0) {
@@ -4152,11 +4645,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
gen_load_gpr(t1, rt);
if (acc != 0) {
- check_dsp(ctx);
+ if (!(ctx->insn_flags & INSN_R5900)) {
+ check_dsp(ctx);
+ }
}
switch (opc) {
case OPC_DIV:
+ case TX79_MMI_DIV1:
{
TCGv t2 = tcg_temp_new();
TCGv t3 = tcg_temp_new();
@@ -4178,6 +4674,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
}
break;
case OPC_DIVU:
+ case TX79_MMI_DIVU1:
{
TCGv t2 = tcg_const_tl(0);
TCGv t3 = tcg_const_tl(1);
@@ -4332,6 +4829,84 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
tcg_temp_free(t1);
}
+/*
+ * These MULT and MULTU instructions implemented in for example the
+ * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
+ * architectures are special three-operand variants with the syntax
+ *
+ * MULT[U][1] rd, rs, rt
+ *
+ * such that
+ *
+ * (rd, LO, HI) <- rs * rt
+ *
+ * where the low-order 32-bits of the result is placed into both the
+ * GPR rd and the special register LO. The high-order 32-bits of the
+ * result is placed into the special register HI.
+ *
+ * If the GPR rd is omitted in assembly language, it is taken to be 0,
+ * which is the zero register that always reads as 0.
+ */
+static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
+ int rd, int rs, int rt)
+{
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ int acc = 0;
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ switch (opc) {
+ case TX79_MMI_MULT1:
+ acc = 1;
+ /* Fall through */
+ case OPC_MULT:
+ {
+ TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t3 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t2, t0);
+ tcg_gen_trunc_tl_i32(t3, t1);
+ tcg_gen_muls2_i32(t2, t3, t2, t3);
+ if (rd) {
+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
+ }
+ 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 TX79_MMI_MULTU1:
+ acc = 1;
+ /* Fall through */
+ case OPC_MULTU:
+ {
+ TCGv_i32 t2 = tcg_temp_new_i32();
+ TCGv_i32 t3 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t2, t0);
+ tcg_gen_trunc_tl_i32(t3, t1);
+ tcg_gen_mulu2_i32(t2, t3, t2, t3);
+ if (rd) {
+ tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
+ }
+ 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;
+ default:
+ MIPS_INVAL("mul TXx9");
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ }
+
+ out:
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
int rd, int rs, int rt)
{
@@ -16929,6 +17504,16 @@ enum {
NM_SOV = 0x7a,
};
+/* CRC32 instruction pool */
+enum {
+ NM_CRC32B = 0x00,
+ NM_CRC32H = 0x01,
+ NM_CRC32W = 0x02,
+ NM_CRC32CB = 0x04,
+ NM_CRC32CH = 0x05,
+ NM_CRC32CW = 0x06,
+};
+
/* POOL32A5 instruction pool */
enum {
NM_CMP_EQ_PH = 0x00,
@@ -20662,6 +21247,105 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
break;
}
break;
+ case NM_P_LS_E0:
+ switch (extract32(ctx->opcode, 11, 4)) {
+ case NM_LBE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LBE, rt, rs, s);
+ break;
+ case NM_SBE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_st(ctx, OPC_SBE, rt, rs, s);
+ break;
+ case NM_LBUE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LBUE, rt, rs, s);
+ break;
+ case NM_P_PREFE:
+ if (rt == 31) {
+ /* case NM_SYNCIE */
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ /* Break the TB to be able to sync copied instructions
+ immediately */
+ ctx->base.is_jmp = DISAS_STOP;
+ } else {
+ /* case NM_PREFE */
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ /* Treat as NOP. */
+ }
+ break;
+ case NM_LHE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LHE, rt, rs, s);
+ break;
+ case NM_SHE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_st(ctx, OPC_SHE, rt, rs, s);
+ break;
+ case NM_LHUE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LHUE, rt, rs, s);
+ break;
+ case NM_CACHEE:
+ check_nms_dl_il_sl_tl_l2c(ctx);
+ gen_cache_operation(ctx, rt, rs, s);
+ break;
+ case NM_LWE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LWE, rt, rs, s);
+ break;
+ case NM_SWE:
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_st(ctx, OPC_SWE, rt, rs, s);
+ break;
+ case NM_P_LLE:
+ switch (extract32(ctx->opcode, 2, 2)) {
+ case NM_LLE:
+ check_xnp(ctx);
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_ld(ctx, OPC_LLE, rt, rs, s);
+ break;
+ case NM_LLWPE:
+ check_xnp(ctx);
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ case NM_P_SCE:
+ switch (extract32(ctx->opcode, 2, 2)) {
+ case NM_SCE:
+ check_xnp(ctx);
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_st_cond(ctx, OPC_SCE, rt, rs, s);
+ break;
+ case NM_SCWPE:
+ check_xnp(ctx);
+ check_eva(ctx);
+ check_cp0_enabled(ctx);
+ gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
+ default:
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+ break;
+ }
+ break;
case NM_P_LS_WM:
case NM_P_LS_UAWM:
check_nms(ctx);
@@ -23029,7 +23713,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_MOVN: /* Conditional move */
case OPC_MOVZ:
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
- INSN_LOONGSON2E | INSN_LOONGSON2F);
+ INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
gen_cond_move(ctx, op1, rd, rs, rt);
break;
case OPC_MFHI: /* Move from HI/LO */
@@ -23056,6 +23740,8 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
check_insn(ctx, INSN_VR54XX);
op1 = MASK_MUL_VR54XX(ctx->opcode);
gen_mul_vr54xx(ctx, op1, rd, rs, rt);
+ } else if (ctx->insn_flags & INSN_R5900) {
+ gen_mul_txx9(ctx, op1, rd, rs, rt);
} else {
gen_muldiv(ctx, op1, rd & 3, rs, rt);
}
@@ -23070,6 +23756,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_DDIV:
case OPC_DDIVU:
check_insn(ctx, ISA_MIPS3);
+ check_insn_opc_user_only(ctx, INSN_R5900);
check_mips_64(ctx);
gen_muldiv(ctx, op1, 0, rs, rt);
break;
@@ -23416,7 +24103,9 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
op2 = MASK_BSHFL(ctx->opcode);
switch (op2) {
case OPC_ALIGN:
- case OPC_ALIGN_END:
+ case OPC_ALIGN_1:
+ case OPC_ALIGN_2:
+ case OPC_ALIGN_3:
gen_align(ctx, 32, rd, rs, rt, sa & 3);
break;
case OPC_BITSWAP:
@@ -23442,7 +24131,13 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
op2 = MASK_DBSHFL(ctx->opcode);
switch (op2) {
case OPC_DALIGN:
- case OPC_DALIGN_END:
+ case OPC_DALIGN_1:
+ case OPC_DALIGN_2:
+ case OPC_DALIGN_3:
+ case OPC_DALIGN_4:
+ case OPC_DALIGN_5:
+ case OPC_DALIGN_6:
+ case OPC_DALIGN_7:
gen_align(ctx, 64, rd, rs, rt, sa & 7);
break;
case OPC_DBITSWAP:
@@ -23986,6 +24681,250 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
}
}
+static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
+
+ switch (opc) {
+ case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
+ case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
+ case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
+ case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
+ case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
+ case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
+ case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
+ case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
+ case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
+ case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
+ case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
+ case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
+ case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
+ case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
+ case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
+ case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
+ case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
+ case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
+ case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
+ case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
+ case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
+ case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
+ case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
+ case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
+ case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
+ break;
+ default:
+ MIPS_INVAL("TX79 MMI class MMI0");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
+static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
+
+ switch (opc) {
+ case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
+ case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
+ case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
+ case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
+ case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
+ case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
+ case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
+ case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
+ case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
+ case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
+ case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
+ case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
+ case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
+ case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
+ case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
+ case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
+ case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
+ case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
+ break;
+ default:
+ MIPS_INVAL("TX79 MMI class MMI1");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
+static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
+
+ switch (opc) {
+ case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
+ case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
+ case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
+ case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
+ case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
+ case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
+ case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
+ case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
+ case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
+ case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
+ case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
+ case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
+ case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
+ case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
+ case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
+ case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
+ case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
+ case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
+ case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
+ case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
+ case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
+ case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
+ break;
+ default:
+ MIPS_INVAL("TX79 MMI class MMI2");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
+static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
+
+ switch (opc) {
+ case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
+ case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
+ case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
+ case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
+ case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
+ case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
+ case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
+ case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
+ case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
+ case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
+ case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
+ case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
+ case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
+ break;
+ default:
+ MIPS_INVAL("TX79 MMI class MMI3");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
+static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
+{
+ uint32_t opc = MASK_TX79_MMI(ctx->opcode);
+ int rs = extract32(ctx->opcode, 21, 5);
+ int rt = extract32(ctx->opcode, 16, 5);
+ int rd = extract32(ctx->opcode, 11, 5);
+
+ switch (opc) {
+ case TX79_MMI_CLASS_MMI0:
+ decode_tx79_mmi0(env, ctx);
+ break;
+ case TX79_MMI_CLASS_MMI1:
+ decode_tx79_mmi1(env, ctx);
+ break;
+ case TX79_MMI_CLASS_MMI2:
+ decode_tx79_mmi2(env, ctx);
+ break;
+ case TX79_MMI_CLASS_MMI3:
+ decode_tx79_mmi3(env, ctx);
+ break;
+ case TX79_MMI_MULT1:
+ case TX79_MMI_MULTU1:
+ gen_mul_txx9(ctx, opc, rd, rs, rt);
+ break;
+ case TX79_MMI_DIV1:
+ case TX79_MMI_DIVU1:
+ gen_muldiv(ctx, opc, 1, rs, rt);
+ break;
+ case TX79_MMI_MTLO1:
+ case TX79_MMI_MTHI1:
+ gen_HILO(ctx, opc, 1, rs);
+ break;
+ case TX79_MMI_MFLO1:
+ case TX79_MMI_MFHI1:
+ gen_HILO(ctx, opc, 1, rd);
+ break;
+ case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
+ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
+ case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
+ case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
+ case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
+ case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
+ case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
+ case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
+ case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
+ case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
+ case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
+ case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
+ case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
+ break;
+ default:
+ MIPS_INVAL("TX79 MMI class");
+ generate_exception_end(ctx, EXCP_RI);
+ break;
+ }
+}
+
+static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
+{
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
+}
+
+static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
+{
+ generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
+}
+
+/*
+ * The TX79-specific instruction Store Quadword
+ *
+ * +--------+-------+-------+------------------------+
+ * | 011111 | base | rt | offset | SQ
+ * +--------+-------+-------+------------------------+
+ * 6 5 5 16
+ *
+ * has the same opcode as the Read Hardware Register instruction
+ *
+ * +--------+-------+-------+-------+-------+--------+
+ * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
+ * +--------+-------+-------+-------+-------+--------+
+ * 6 5 5 5 5 6
+ *
+ * that is required, trapped and emulated by the Linux kernel. However, all
+ * RDHWR encodings yield address error exceptions on the TX79 since the SQ
+ * offset is odd. Therefore all valid SQ instructions can execute normally.
+ * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
+ * between SQ and RDHWR, as the Linux kernel does.
+ */
+static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
+{
+ int base = extract32(ctx->opcode, 21, 5);
+ int rt = extract32(ctx->opcode, 16, 5);
+ int offset = extract32(ctx->opcode, 0, 16);
+
+#ifdef CONFIG_USER_ONLY
+ uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
+ uint32_t op2 = extract32(ctx->opcode, 6, 5);
+
+ if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
+ int rd = extract32(ctx->opcode, 11, 5);
+
+ gen_rdhwr(ctx, rt, rd, 0);
+ return;
+ }
+#endif
+
+ gen_tx79_sq(ctx, base, rt, offset);
+}
+
static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
{
int rs, rt, rd, sa;
@@ -24058,7 +24997,9 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
op2 = MASK_BSHFL(ctx->opcode);
switch (op2) {
case OPC_ALIGN:
- case OPC_ALIGN_END:
+ case OPC_ALIGN_1:
+ case OPC_ALIGN_2:
+ case OPC_ALIGN_3:
case OPC_BITSWAP:
check_insn(ctx, ISA_MIPS32R6);
decode_opc_special3_r6(env, ctx);
@@ -24084,7 +25025,13 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
op2 = MASK_DBSHFL(ctx->opcode);
switch (op2) {
case OPC_DALIGN:
- case OPC_DALIGN_END:
+ case OPC_DALIGN_1:
+ case OPC_DALIGN_2:
+ case OPC_DALIGN_3:
+ case OPC_DALIGN_4:
+ case OPC_DALIGN_5:
+ case OPC_DALIGN_6:
+ case OPC_DALIGN_7:
case OPC_DBITSWAP:
check_insn(ctx, ISA_MIPS32R6);
decode_opc_special3_r6(env, ctx);
@@ -25283,10 +26230,18 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
decode_opc_special(env, ctx);
break;
case OPC_SPECIAL2:
- decode_opc_special2_legacy(env, ctx);
+ if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
+ decode_tx79_mmi(env, ctx);
+ } else {
+ decode_opc_special2_legacy(env, ctx);
+ }
break;
case OPC_SPECIAL3:
- decode_opc_special3(env, ctx);
+ if (ctx->insn_flags & INSN_R5900) {
+ decode_tx79_sq(env, ctx); /* TX79_SQ */
+ } else {
+ decode_opc_special3(env, ctx);
+ }
break;
case OPC_REGIMM:
op1 = MASK_REGIMM(ctx->opcode);
@@ -25573,6 +26528,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_LL: /* Load and stores */
check_insn(ctx, ISA_MIPS2);
+ check_insn_opc_user_only(ctx, INSN_R5900);
/* Fallthrough */
case OPC_LWL:
case OPC_LWR:
@@ -25598,6 +26554,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
case OPC_SC:
check_insn(ctx, ISA_MIPS2);
check_insn_opc_removed(ctx, ISA_MIPS32R6);
+ check_insn_opc_user_only(ctx, INSN_R5900);
gen_st_cond(ctx, op, rt, rs, imm);
break;
case OPC_CACHE:
@@ -25611,7 +26568,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_PREF:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
+ check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
+ INSN_R5900);
/* Treat as NOP. */
break;
@@ -25863,9 +26821,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
#if defined(TARGET_MIPS64)
/* MIPS64 opcodes */
+ case OPC_LLD:
+ check_insn_opc_user_only(ctx, INSN_R5900);
+ /* fall through */
case OPC_LDL:
case OPC_LDR:
- case OPC_LLD:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
/* fall through */
case OPC_LWU:
@@ -25886,6 +26846,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
case OPC_SCD:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
check_insn(ctx, ISA_MIPS3);
+ check_insn_opc_user_only(ctx, INSN_R5900);
check_mips_64(ctx);
gen_st_cond(ctx, op, rt, rs, imm);
break;
@@ -25940,8 +26901,12 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
}
break;
case OPC_MSA: /* OPC_MDMX */
- /* MDMX: Not implemented. */
- gen_msa(env, ctx);
+ if (ctx->insn_flags & INSN_R5900) {
+ decode_tx79_lq(env, ctx); /* TX79_LQ */
+ } else {
+ /* MDMX: Not implemented. */
+ gen_msa(env, ctx);
+ }
break;
case OPC_PCREL:
check_insn(ctx, ISA_MIPS32R6);
diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c
index acab097820..85da4a269c 100644
--- a/target/mips/translate_init.inc.c
+++ b/target/mips/translate_init.inc.c
@@ -411,6 +411,65 @@ const mips_def_t mips_defs[] =
.mmu_type = MMU_TYPE_R4000,
},
{
+ /*
+ * The Toshiba TX System RISC TX79 Core Architecture manual
+ *
+ * https://wiki.qemu.org/File:C790.pdf
+ *
+ * describes the C790 processor that is a follow-up to the R5900.
+ * There are a few notable differences in that the R5900 FPU
+ *
+ * - is not IEEE 754-1985 compliant,
+ * - does not implement double format, and
+ * - its machine code is nonstandard.
+ */
+ .name = "R5900",
+ .CP0_PRid = 0x00002E00,
+ /* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */
+ .CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0),
+ .CP0_Status_rw_bitmask = 0xF4C79C1F,
+#ifdef CONFIG_USER_ONLY
+ /*
+ * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC
+ * emulation. For user only, QEMU is the kernel, so we emulate the traps
+ * by simply emulating the instructions directly.
+ *
+ * Note: Config1 is only used internally, the R5900 has only Config0.
+ */
+ .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
+ .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
+ .CP0_LLAddr_shift = 4,
+ .CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV),
+ .CP1_fcr31 = 0,
+ .CP1_fcr31_rw_bitmask = 0x0183FFFF,
+#else
+ /*
+ * The R5900 COP1 FPU implements single-precision floating-point
+ * operations but is not entirely IEEE 754-1985 compatible. In
+ * particular,
+ *
+ * - NaN (not a number) and +/- infinities are not supported;
+ * - exception mechanisms are not fully supported;
+ * - denormalized numbers are not supported;
+ * - rounding towards nearest and +/- infinities are not supported;
+ * - computed results usually differs in the least significant bit;
+ * - saturations can differ more than the least significant bit.
+ *
+ * Since only rounding towards zero is supported, the two least
+ * significant bits of FCR31 are hardwired to 01.
+ *
+ * FPU emulation is disabled here until it is implemented.
+ *
+ * Note: Config1 is only used internally, the R5900 has only Config0.
+ */
+ .CP0_Config1 = (47 << CP0C1_MMU),
+#endif /* !CONFIG_USER_ONLY */
+ .SEGBITS = 32,
+ .PABITS = 32,
+ .insn_flags = CPU_R5900 | ASE_MMI,
+ .mmu_type = MMU_TYPE_R4000,
+ },
+ {
/* A generic CPU supporting MIPS32 Release 6 ISA.
FIXME: Support IEEE 754-2008 FP.
Eventually this should be replaced by a real CPU model. */
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 263e63cb03..ee9432eb15 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -8381,8 +8381,8 @@ static void getset_compat_deprecated(Object *obj, Visitor *v, const char *name,
QNull *null = NULL;
if (!qtest_enabled()) {
- error_report("CPU 'compat' property is deprecated and has no effect; "
- "use max-cpu-compat machine property instead");
+ warn_report("CPU 'compat' property is deprecated and has no effect; "
+ "use max-cpu-compat machine property instead");
}
visit_type_null(v, name, &null, NULL);
qobject_unref(null);
diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index abd0a7cde3..fcc5d34c1f 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d630e8fd6c..a025a0a3ba 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -74,8 +74,10 @@ const char * const riscv_intr_names[] = {
"s_external",
"h_external",
"m_external",
- "coprocessor",
- "host"
+ "reserved",
+ "reserved",
+ "reserved",
+ "reserved"
};
typedef struct RISCVCPUInfo {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d4f36295f0..4ee09b9cff 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -126,13 +126,18 @@ struct CPURISCVState {
target_ulong mhartid;
target_ulong mstatus;
+
/*
* CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads and other vCPUs, so hold the iothread mutex before
- * operating on it. CPU_INTERRUPT_HARD should be in effect iff this is
- * non-zero. Use riscv_cpu_set_local_interrupt.
+ * by I/O threads. It should be read with atomic_read. It should be updated
+ * using riscv_cpu_update_mip with the iothread mutex held. The iothread
+ * mutex must be held because mip must be consistent with the CPU inturrept
+ * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
+ * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
+ * mip is 32-bits to allow atomic_read on 32-bit hosts.
*/
- uint32_t mip; /* allow atomic_read for >= 32-bit hosts */
+ uint32_t mip;
+
target_ulong mie;
target_ulong mideleg;
@@ -247,7 +252,6 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
uintptr_t retaddr);
int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
int rw, int mmu_idx);
-
char *riscv_isa_string(RISCVCPU *cpu);
void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
@@ -255,6 +259,10 @@ void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
#define cpu_list riscv_cpu_list
#define cpu_mmu_index riscv_cpu_mmu_index
+#ifndef CONFIG_USER_ONLY
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
+#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
+#endif
void riscv_set_mode(CPURISCVState *env, target_ulong newpriv);
void riscv_translate_init(void);
@@ -285,10 +293,6 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
target_ulong csrno);
target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno);
-#ifndef CONFIG_USER_ONLY
-void riscv_set_local_interrupt(RISCVCPU *cpu, target_ulong mask, int value);
-#endif
-
#include "exec/cpu-all.h"
#endif /* RISCV_CPU_H */
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 12b4757088..5439f4719e 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -6,242 +6,283 @@
(((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
(target_ulong)(mask)))
-#define PGSHIFT 12
-
-#define FSR_RD_SHIFT 5
-#define FSR_RD (0x7 << FSR_RD_SHIFT)
-
-#define FPEXC_NX 0x01
-#define FPEXC_UF 0x02
-#define FPEXC_OF 0x04
-#define FPEXC_DZ 0x08
-#define FPEXC_NV 0x10
-
-#define FSR_AEXC_SHIFT 0
-#define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT)
-#define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT)
-#define FSR_UFA (FPEXC_UF << FSR_AEXC_SHIFT)
-#define FSR_DZA (FPEXC_DZ << FSR_AEXC_SHIFT)
-#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
-#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
-
-/* CSR numbers */
-#define CSR_FFLAGS 0x1
-#define CSR_FRM 0x2
-#define CSR_FCSR 0x3
-#define CSR_CYCLE 0xc00
-#define CSR_TIME 0xc01
-#define CSR_INSTRET 0xc02
-#define CSR_HPMCOUNTER3 0xc03
-#define CSR_HPMCOUNTER4 0xc04
-#define CSR_HPMCOUNTER5 0xc05
-#define CSR_HPMCOUNTER6 0xc06
-#define CSR_HPMCOUNTER7 0xc07
-#define CSR_HPMCOUNTER8 0xc08
-#define CSR_HPMCOUNTER9 0xc09
-#define CSR_HPMCOUNTER10 0xc0a
-#define CSR_HPMCOUNTER11 0xc0b
-#define CSR_HPMCOUNTER12 0xc0c
-#define CSR_HPMCOUNTER13 0xc0d
-#define CSR_HPMCOUNTER14 0xc0e
-#define CSR_HPMCOUNTER15 0xc0f
-#define CSR_HPMCOUNTER16 0xc10
-#define CSR_HPMCOUNTER17 0xc11
-#define CSR_HPMCOUNTER18 0xc12
-#define CSR_HPMCOUNTER19 0xc13
-#define CSR_HPMCOUNTER20 0xc14
-#define CSR_HPMCOUNTER21 0xc15
-#define CSR_HPMCOUNTER22 0xc16
-#define CSR_HPMCOUNTER23 0xc17
-#define CSR_HPMCOUNTER24 0xc18
-#define CSR_HPMCOUNTER25 0xc19
-#define CSR_HPMCOUNTER26 0xc1a
-#define CSR_HPMCOUNTER27 0xc1b
-#define CSR_HPMCOUNTER28 0xc1c
-#define CSR_HPMCOUNTER29 0xc1d
-#define CSR_HPMCOUNTER30 0xc1e
-#define CSR_HPMCOUNTER31 0xc1f
-#define CSR_SSTATUS 0x100
-#define CSR_SIE 0x104
-#define CSR_STVEC 0x105
-#define CSR_SCOUNTEREN 0x106
-#define CSR_SSCRATCH 0x140
-#define CSR_SEPC 0x141
-#define CSR_SCAUSE 0x142
-#define CSR_SBADADDR 0x143
-#define CSR_SIP 0x144
-#define CSR_SPTBR 0x180
-#define CSR_SATP 0x180
-#define CSR_MSTATUS 0x300
-#define CSR_MISA 0x301
-#define CSR_MEDELEG 0x302
-#define CSR_MIDELEG 0x303
-#define CSR_MIE 0x304
-#define CSR_MTVEC 0x305
-#define CSR_MCOUNTEREN 0x306
-#define CSR_MSCRATCH 0x340
-#define CSR_MEPC 0x341
-#define CSR_MCAUSE 0x342
-#define CSR_MBADADDR 0x343
-#define CSR_MIP 0x344
-#define CSR_PMPCFG0 0x3a0
-#define CSR_PMPCFG1 0x3a1
-#define CSR_PMPCFG2 0x3a2
-#define CSR_PMPCFG3 0x3a3
-#define CSR_PMPADDR0 0x3b0
-#define CSR_PMPADDR1 0x3b1
-#define CSR_PMPADDR2 0x3b2
-#define CSR_PMPADDR3 0x3b3
-#define CSR_PMPADDR4 0x3b4
-#define CSR_PMPADDR5 0x3b5
-#define CSR_PMPADDR6 0x3b6
-#define CSR_PMPADDR7 0x3b7
-#define CSR_PMPADDR8 0x3b8
-#define CSR_PMPADDR9 0x3b9
-#define CSR_PMPADDR10 0x3ba
-#define CSR_PMPADDR11 0x3bb
-#define CSR_PMPADDR12 0x3bc
-#define CSR_PMPADDR13 0x3bd
-#define CSR_PMPADDR14 0x3be
-#define CSR_PMPADDR15 0x3bf
-#define CSR_TSELECT 0x7a0
-#define CSR_TDATA1 0x7a1
-#define CSR_TDATA2 0x7a2
-#define CSR_TDATA3 0x7a3
-#define CSR_DCSR 0x7b0
-#define CSR_DPC 0x7b1
-#define CSR_DSCRATCH 0x7b2
-#define CSR_MCYCLE 0xb00
-#define CSR_MINSTRET 0xb02
-#define CSR_MHPMCOUNTER3 0xb03
-#define CSR_MHPMCOUNTER4 0xb04
-#define CSR_MHPMCOUNTER5 0xb05
-#define CSR_MHPMCOUNTER6 0xb06
-#define CSR_MHPMCOUNTER7 0xb07
-#define CSR_MHPMCOUNTER8 0xb08
-#define CSR_MHPMCOUNTER9 0xb09
-#define CSR_MHPMCOUNTER10 0xb0a
-#define CSR_MHPMCOUNTER11 0xb0b
-#define CSR_MHPMCOUNTER12 0xb0c
-#define CSR_MHPMCOUNTER13 0xb0d
-#define CSR_MHPMCOUNTER14 0xb0e
-#define CSR_MHPMCOUNTER15 0xb0f
-#define CSR_MHPMCOUNTER16 0xb10
-#define CSR_MHPMCOUNTER17 0xb11
-#define CSR_MHPMCOUNTER18 0xb12
-#define CSR_MHPMCOUNTER19 0xb13
-#define CSR_MHPMCOUNTER20 0xb14
-#define CSR_MHPMCOUNTER21 0xb15
-#define CSR_MHPMCOUNTER22 0xb16
-#define CSR_MHPMCOUNTER23 0xb17
-#define CSR_MHPMCOUNTER24 0xb18
-#define CSR_MHPMCOUNTER25 0xb19
-#define CSR_MHPMCOUNTER26 0xb1a
-#define CSR_MHPMCOUNTER27 0xb1b
-#define CSR_MHPMCOUNTER28 0xb1c
-#define CSR_MHPMCOUNTER29 0xb1d
-#define CSR_MHPMCOUNTER30 0xb1e
-#define CSR_MHPMCOUNTER31 0xb1f
-#define CSR_MUCOUNTEREN 0x320
-#define CSR_MSCOUNTEREN 0x321
-#define CSR_MHPMEVENT3 0x323
-#define CSR_MHPMEVENT4 0x324
-#define CSR_MHPMEVENT5 0x325
-#define CSR_MHPMEVENT6 0x326
-#define CSR_MHPMEVENT7 0x327
-#define CSR_MHPMEVENT8 0x328
-#define CSR_MHPMEVENT9 0x329
-#define CSR_MHPMEVENT10 0x32a
-#define CSR_MHPMEVENT11 0x32b
-#define CSR_MHPMEVENT12 0x32c
-#define CSR_MHPMEVENT13 0x32d
-#define CSR_MHPMEVENT14 0x32e
-#define CSR_MHPMEVENT15 0x32f
-#define CSR_MHPMEVENT16 0x330
-#define CSR_MHPMEVENT17 0x331
-#define CSR_MHPMEVENT18 0x332
-#define CSR_MHPMEVENT19 0x333
-#define CSR_MHPMEVENT20 0x334
-#define CSR_MHPMEVENT21 0x335
-#define CSR_MHPMEVENT22 0x336
-#define CSR_MHPMEVENT23 0x337
-#define CSR_MHPMEVENT24 0x338
-#define CSR_MHPMEVENT25 0x339
-#define CSR_MHPMEVENT26 0x33a
-#define CSR_MHPMEVENT27 0x33b
-#define CSR_MHPMEVENT28 0x33c
-#define CSR_MHPMEVENT29 0x33d
-#define CSR_MHPMEVENT30 0x33e
-#define CSR_MHPMEVENT31 0x33f
-#define CSR_MVENDORID 0xf11
-#define CSR_MARCHID 0xf12
-#define CSR_MIMPID 0xf13
-#define CSR_MHARTID 0xf14
-#define CSR_CYCLEH 0xc80
-#define CSR_TIMEH 0xc81
-#define CSR_INSTRETH 0xc82
-#define CSR_HPMCOUNTER3H 0xc83
-#define CSR_HPMCOUNTER4H 0xc84
-#define CSR_HPMCOUNTER5H 0xc85
-#define CSR_HPMCOUNTER6H 0xc86
-#define CSR_HPMCOUNTER7H 0xc87
-#define CSR_HPMCOUNTER8H 0xc88
-#define CSR_HPMCOUNTER9H 0xc89
-#define CSR_HPMCOUNTER10H 0xc8a
-#define CSR_HPMCOUNTER11H 0xc8b
-#define CSR_HPMCOUNTER12H 0xc8c
-#define CSR_HPMCOUNTER13H 0xc8d
-#define CSR_HPMCOUNTER14H 0xc8e
-#define CSR_HPMCOUNTER15H 0xc8f
-#define CSR_HPMCOUNTER16H 0xc90
-#define CSR_HPMCOUNTER17H 0xc91
-#define CSR_HPMCOUNTER18H 0xc92
-#define CSR_HPMCOUNTER19H 0xc93
-#define CSR_HPMCOUNTER20H 0xc94
-#define CSR_HPMCOUNTER21H 0xc95
-#define CSR_HPMCOUNTER22H 0xc96
-#define CSR_HPMCOUNTER23H 0xc97
-#define CSR_HPMCOUNTER24H 0xc98
-#define CSR_HPMCOUNTER25H 0xc99
-#define CSR_HPMCOUNTER26H 0xc9a
-#define CSR_HPMCOUNTER27H 0xc9b
-#define CSR_HPMCOUNTER28H 0xc9c
-#define CSR_HPMCOUNTER29H 0xc9d
-#define CSR_HPMCOUNTER30H 0xc9e
-#define CSR_HPMCOUNTER31H 0xc9f
-#define CSR_MCYCLEH 0xb80
-#define CSR_MINSTRETH 0xb82
-#define CSR_MHPMCOUNTER3H 0xb83
-#define CSR_MHPMCOUNTER4H 0xb84
-#define CSR_MHPMCOUNTER5H 0xb85
-#define CSR_MHPMCOUNTER6H 0xb86
-#define CSR_MHPMCOUNTER7H 0xb87
-#define CSR_MHPMCOUNTER8H 0xb88
-#define CSR_MHPMCOUNTER9H 0xb89
-#define CSR_MHPMCOUNTER10H 0xb8a
-#define CSR_MHPMCOUNTER11H 0xb8b
-#define CSR_MHPMCOUNTER12H 0xb8c
-#define CSR_MHPMCOUNTER13H 0xb8d
-#define CSR_MHPMCOUNTER14H 0xb8e
-#define CSR_MHPMCOUNTER15H 0xb8f
-#define CSR_MHPMCOUNTER16H 0xb90
-#define CSR_MHPMCOUNTER17H 0xb91
-#define CSR_MHPMCOUNTER18H 0xb92
-#define CSR_MHPMCOUNTER19H 0xb93
-#define CSR_MHPMCOUNTER20H 0xb94
-#define CSR_MHPMCOUNTER21H 0xb95
-#define CSR_MHPMCOUNTER22H 0xb96
-#define CSR_MHPMCOUNTER23H 0xb97
-#define CSR_MHPMCOUNTER24H 0xb98
-#define CSR_MHPMCOUNTER25H 0xb99
-#define CSR_MHPMCOUNTER26H 0xb9a
-#define CSR_MHPMCOUNTER27H 0xb9b
-#define CSR_MHPMCOUNTER28H 0xb9c
-#define CSR_MHPMCOUNTER29H 0xb9d
-#define CSR_MHPMCOUNTER30H 0xb9e
-#define CSR_MHPMCOUNTER31H 0xb9f
-
-/* mstatus bits */
+/* Floating point round mode */
+#define FSR_RD_SHIFT 5
+#define FSR_RD (0x7 << FSR_RD_SHIFT)
+
+/* Floating point accrued exception flags */
+#define FPEXC_NX 0x01
+#define FPEXC_UF 0x02
+#define FPEXC_OF 0x04
+#define FPEXC_DZ 0x08
+#define FPEXC_NV 0x10
+
+/* Floating point status register bits */
+#define FSR_AEXC_SHIFT 0
+#define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT)
+#define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT)
+#define FSR_UFA (FPEXC_UF << FSR_AEXC_SHIFT)
+#define FSR_DZA (FPEXC_DZ << FSR_AEXC_SHIFT)
+#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
+#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+
+/* Control and Status Registers */
+
+/* User Trap Setup */
+#define CSR_USTATUS 0x000
+#define CSR_UIE 0x004
+#define CSR_UTVEC 0x005
+
+/* User Trap Handling */
+#define CSR_USCRATCH 0x040
+#define CSR_UEPC 0x041
+#define CSR_UCAUSE 0x042
+#define CSR_UTVAL 0x043
+#define CSR_UIP 0x044
+
+/* User Floating-Point CSRs */
+#define CSR_FFLAGS 0x001
+#define CSR_FRM 0x002
+#define CSR_FCSR 0x003
+
+/* User Timers and Counters */
+#define CSR_CYCLE 0xc00
+#define CSR_TIME 0xc01
+#define CSR_INSTRET 0xc02
+#define CSR_HPMCOUNTER3 0xc03
+#define CSR_HPMCOUNTER4 0xc04
+#define CSR_HPMCOUNTER5 0xc05
+#define CSR_HPMCOUNTER6 0xc06
+#define CSR_HPMCOUNTER7 0xc07
+#define CSR_HPMCOUNTER8 0xc08
+#define CSR_HPMCOUNTER9 0xc09
+#define CSR_HPMCOUNTER10 0xc0a
+#define CSR_HPMCOUNTER11 0xc0b
+#define CSR_HPMCOUNTER12 0xc0c
+#define CSR_HPMCOUNTER13 0xc0d
+#define CSR_HPMCOUNTER14 0xc0e
+#define CSR_HPMCOUNTER15 0xc0f
+#define CSR_HPMCOUNTER16 0xc10
+#define CSR_HPMCOUNTER17 0xc11
+#define CSR_HPMCOUNTER18 0xc12
+#define CSR_HPMCOUNTER19 0xc13
+#define CSR_HPMCOUNTER20 0xc14
+#define CSR_HPMCOUNTER21 0xc15
+#define CSR_HPMCOUNTER22 0xc16
+#define CSR_HPMCOUNTER23 0xc17
+#define CSR_HPMCOUNTER24 0xc18
+#define CSR_HPMCOUNTER25 0xc19
+#define CSR_HPMCOUNTER26 0xc1a
+#define CSR_HPMCOUNTER27 0xc1b
+#define CSR_HPMCOUNTER28 0xc1c
+#define CSR_HPMCOUNTER29 0xc1d
+#define CSR_HPMCOUNTER30 0xc1e
+#define CSR_HPMCOUNTER31 0xc1f
+#define CSR_CYCLEH 0xc80
+#define CSR_TIMEH 0xc81
+#define CSR_INSTRETH 0xc82
+#define CSR_HPMCOUNTER3H 0xc83
+#define CSR_HPMCOUNTER4H 0xc84
+#define CSR_HPMCOUNTER5H 0xc85
+#define CSR_HPMCOUNTER6H 0xc86
+#define CSR_HPMCOUNTER7H 0xc87
+#define CSR_HPMCOUNTER8H 0xc88
+#define CSR_HPMCOUNTER9H 0xc89
+#define CSR_HPMCOUNTER10H 0xc8a
+#define CSR_HPMCOUNTER11H 0xc8b
+#define CSR_HPMCOUNTER12H 0xc8c
+#define CSR_HPMCOUNTER13H 0xc8d
+#define CSR_HPMCOUNTER14H 0xc8e
+#define CSR_HPMCOUNTER15H 0xc8f
+#define CSR_HPMCOUNTER16H 0xc90
+#define CSR_HPMCOUNTER17H 0xc91
+#define CSR_HPMCOUNTER18H 0xc92
+#define CSR_HPMCOUNTER19H 0xc93
+#define CSR_HPMCOUNTER20H 0xc94
+#define CSR_HPMCOUNTER21H 0xc95
+#define CSR_HPMCOUNTER22H 0xc96
+#define CSR_HPMCOUNTER23H 0xc97
+#define CSR_HPMCOUNTER24H 0xc98
+#define CSR_HPMCOUNTER25H 0xc99
+#define CSR_HPMCOUNTER26H 0xc9a
+#define CSR_HPMCOUNTER27H 0xc9b
+#define CSR_HPMCOUNTER28H 0xc9c
+#define CSR_HPMCOUNTER29H 0xc9d
+#define CSR_HPMCOUNTER30H 0xc9e
+#define CSR_HPMCOUNTER31H 0xc9f
+
+/* Machine Timers and Counters */
+#define CSR_MCYCLE 0xb00
+#define CSR_MINSTRET 0xb02
+#define CSR_MCYCLEH 0xb80
+#define CSR_MINSTRETH 0xb82
+
+/* Machine Information Registers */
+#define CSR_MVENDORID 0xf11
+#define CSR_MARCHID 0xf12
+#define CSR_MIMPID 0xf13
+#define CSR_MHARTID 0xf14
+
+/* Machine Trap Setup */
+#define CSR_MSTATUS 0x300
+#define CSR_MISA 0x301
+#define CSR_MEDELEG 0x302
+#define CSR_MIDELEG 0x303
+#define CSR_MIE 0x304
+#define CSR_MTVEC 0x305
+#define CSR_MCOUNTEREN 0x306
+
+/* Legacy Counter Setup (priv v1.9.1) */
+#define CSR_MUCOUNTEREN 0x320
+#define CSR_MSCOUNTEREN 0x321
+
+/* Machine Trap Handling */
+#define CSR_MSCRATCH 0x340
+#define CSR_MEPC 0x341
+#define CSR_MCAUSE 0x342
+#define CSR_MBADADDR 0x343
+#define CSR_MIP 0x344
+
+/* Supervisor Trap Setup */
+#define CSR_SSTATUS 0x100
+#define CSR_SIE 0x104
+#define CSR_STVEC 0x105
+#define CSR_SCOUNTEREN 0x106
+
+/* Supervisor Trap Handling */
+#define CSR_SSCRATCH 0x140
+#define CSR_SEPC 0x141
+#define CSR_SCAUSE 0x142
+#define CSR_SBADADDR 0x143
+#define CSR_SIP 0x144
+
+/* Supervisor Protection and Translation */
+#define CSR_SPTBR 0x180
+#define CSR_SATP 0x180
+
+/* Physical Memory Protection */
+#define CSR_PMPCFG0 0x3a0
+#define CSR_PMPCFG1 0x3a1
+#define CSR_PMPCFG2 0x3a2
+#define CSR_PMPCFG3 0x3a3
+#define CSR_PMPADDR0 0x3b0
+#define CSR_PMPADDR1 0x3b1
+#define CSR_PMPADDR2 0x3b2
+#define CSR_PMPADDR3 0x3b3
+#define CSR_PMPADDR4 0x3b4
+#define CSR_PMPADDR5 0x3b5
+#define CSR_PMPADDR6 0x3b6
+#define CSR_PMPADDR7 0x3b7
+#define CSR_PMPADDR8 0x3b8
+#define CSR_PMPADDR9 0x3b9
+#define CSR_PMPADDR10 0x3ba
+#define CSR_PMPADDR11 0x3bb
+#define CSR_PMPADDR12 0x3bc
+#define CSR_PMPADDR13 0x3bd
+#define CSR_PMPADDR14 0x3be
+#define CSR_PMPADDR15 0x3bf
+
+/* Debug/Trace Registers (shared with Debug Mode) */
+#define CSR_TSELECT 0x7a0
+#define CSR_TDATA1 0x7a1
+#define CSR_TDATA2 0x7a2
+#define CSR_TDATA3 0x7a3
+
+/* Debug Mode Registers */
+#define CSR_DCSR 0x7b0
+#define CSR_DPC 0x7b1
+#define CSR_DSCRATCH 0x7b2
+
+/* Performance Counters */
+#define CSR_MHPMCOUNTER3 0xb03
+#define CSR_MHPMCOUNTER4 0xb04
+#define CSR_MHPMCOUNTER5 0xb05
+#define CSR_MHPMCOUNTER6 0xb06
+#define CSR_MHPMCOUNTER7 0xb07
+#define CSR_MHPMCOUNTER8 0xb08
+#define CSR_MHPMCOUNTER9 0xb09
+#define CSR_MHPMCOUNTER10 0xb0a
+#define CSR_MHPMCOUNTER11 0xb0b
+#define CSR_MHPMCOUNTER12 0xb0c
+#define CSR_MHPMCOUNTER13 0xb0d
+#define CSR_MHPMCOUNTER14 0xb0e
+#define CSR_MHPMCOUNTER15 0xb0f
+#define CSR_MHPMCOUNTER16 0xb10
+#define CSR_MHPMCOUNTER17 0xb11
+#define CSR_MHPMCOUNTER18 0xb12
+#define CSR_MHPMCOUNTER19 0xb13
+#define CSR_MHPMCOUNTER20 0xb14
+#define CSR_MHPMCOUNTER21 0xb15
+#define CSR_MHPMCOUNTER22 0xb16
+#define CSR_MHPMCOUNTER23 0xb17
+#define CSR_MHPMCOUNTER24 0xb18
+#define CSR_MHPMCOUNTER25 0xb19
+#define CSR_MHPMCOUNTER26 0xb1a
+#define CSR_MHPMCOUNTER27 0xb1b
+#define CSR_MHPMCOUNTER28 0xb1c
+#define CSR_MHPMCOUNTER29 0xb1d
+#define CSR_MHPMCOUNTER30 0xb1e
+#define CSR_MHPMCOUNTER31 0xb1f
+#define CSR_MHPMEVENT3 0x323
+#define CSR_MHPMEVENT4 0x324
+#define CSR_MHPMEVENT5 0x325
+#define CSR_MHPMEVENT6 0x326
+#define CSR_MHPMEVENT7 0x327
+#define CSR_MHPMEVENT8 0x328
+#define CSR_MHPMEVENT9 0x329
+#define CSR_MHPMEVENT10 0x32a
+#define CSR_MHPMEVENT11 0x32b
+#define CSR_MHPMEVENT12 0x32c
+#define CSR_MHPMEVENT13 0x32d
+#define CSR_MHPMEVENT14 0x32e
+#define CSR_MHPMEVENT15 0x32f
+#define CSR_MHPMEVENT16 0x330
+#define CSR_MHPMEVENT17 0x331
+#define CSR_MHPMEVENT18 0x332
+#define CSR_MHPMEVENT19 0x333
+#define CSR_MHPMEVENT20 0x334
+#define CSR_MHPMEVENT21 0x335
+#define CSR_MHPMEVENT22 0x336
+#define CSR_MHPMEVENT23 0x337
+#define CSR_MHPMEVENT24 0x338
+#define CSR_MHPMEVENT25 0x339
+#define CSR_MHPMEVENT26 0x33a
+#define CSR_MHPMEVENT27 0x33b
+#define CSR_MHPMEVENT28 0x33c
+#define CSR_MHPMEVENT29 0x33d
+#define CSR_MHPMEVENT30 0x33e
+#define CSR_MHPMEVENT31 0x33f
+#define CSR_MHPMCOUNTER3H 0xb83
+#define CSR_MHPMCOUNTER4H 0xb84
+#define CSR_MHPMCOUNTER5H 0xb85
+#define CSR_MHPMCOUNTER6H 0xb86
+#define CSR_MHPMCOUNTER7H 0xb87
+#define CSR_MHPMCOUNTER8H 0xb88
+#define CSR_MHPMCOUNTER9H 0xb89
+#define CSR_MHPMCOUNTER10H 0xb8a
+#define CSR_MHPMCOUNTER11H 0xb8b
+#define CSR_MHPMCOUNTER12H 0xb8c
+#define CSR_MHPMCOUNTER13H 0xb8d
+#define CSR_MHPMCOUNTER14H 0xb8e
+#define CSR_MHPMCOUNTER15H 0xb8f
+#define CSR_MHPMCOUNTER16H 0xb90
+#define CSR_MHPMCOUNTER17H 0xb91
+#define CSR_MHPMCOUNTER18H 0xb92
+#define CSR_MHPMCOUNTER19H 0xb93
+#define CSR_MHPMCOUNTER20H 0xb94
+#define CSR_MHPMCOUNTER21H 0xb95
+#define CSR_MHPMCOUNTER22H 0xb96
+#define CSR_MHPMCOUNTER23H 0xb97
+#define CSR_MHPMCOUNTER24H 0xb98
+#define CSR_MHPMCOUNTER25H 0xb99
+#define CSR_MHPMCOUNTER26H 0xb9a
+#define CSR_MHPMCOUNTER27H 0xb9b
+#define CSR_MHPMCOUNTER28H 0xb9c
+#define CSR_MHPMCOUNTER29H 0xb9d
+#define CSR_MHPMCOUNTER30H 0xb9e
+#define CSR_MHPMCOUNTER31H 0xb9f
+
+/* mstatus CSR bits */
#define MSTATUS_UIE 0x00000001
#define MSTATUS_SIE 0x00000002
#define MSTATUS_HIE 0x00000004
@@ -276,7 +317,7 @@
#define MSTATUS_SD MSTATUS64_SD
#endif
-/* sstatus bits */
+/* sstatus CSR bits */
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
@@ -297,83 +338,71 @@
#define SSTATUS_SD SSTATUS64_SD
#endif
-/* irqs */
-#define MIP_SSIP (1 << IRQ_S_SOFT)
-#define MIP_HSIP (1 << IRQ_H_SOFT)
-#define MIP_MSIP (1 << IRQ_M_SOFT)
-#define MIP_STIP (1 << IRQ_S_TIMER)
-#define MIP_HTIP (1 << IRQ_H_TIMER)
-#define MIP_MTIP (1 << IRQ_M_TIMER)
-#define MIP_SEIP (1 << IRQ_S_EXT)
-#define MIP_HEIP (1 << IRQ_H_EXT)
-#define MIP_MEIP (1 << IRQ_M_EXT)
-
-#define SIP_SSIP MIP_SSIP
-#define SIP_STIP MIP_STIP
-#define SIP_SEIP MIP_SEIP
-
+/* Privilege modes */
#define PRV_U 0
#define PRV_S 1
#define PRV_H 2
#define PRV_M 3
-/* privileged ISA 1.9.1 VM modes (mstatus.vm) */
-#define VM_1_09_MBARE 0
-#define VM_1_09_MBB 1
-#define VM_1_09_MBBID 2
-#define VM_1_09_SV32 8
-#define VM_1_09_SV39 9
-#define VM_1_09_SV48 10
-
-/* privileged ISA 1.10.0 VM modes (satp.mode) */
-#define VM_1_10_MBARE 0
-#define VM_1_10_SV32 1
-#define VM_1_10_SV39 8
-#define VM_1_10_SV48 9
-#define VM_1_10_SV57 10
-#define VM_1_10_SV64 11
-
-/* privileged ISA interrupt causes */
-#define IRQ_U_SOFT 0 /* since: priv-1.10 */
-#define IRQ_S_SOFT 1
-#define IRQ_H_SOFT 2 /* until: priv-1.9.1 */
-#define IRQ_M_SOFT 3 /* until: priv-1.9.1 */
-#define IRQ_U_TIMER 4 /* since: priv-1.10 */
-#define IRQ_S_TIMER 5
-#define IRQ_H_TIMER 6 /* until: priv-1.9.1 */
-#define IRQ_M_TIMER 7 /* until: priv-1.9.1 */
-#define IRQ_U_EXT 8 /* since: priv-1.10 */
-#define IRQ_S_EXT 9
-#define IRQ_H_EXT 10 /* until: priv-1.9.1 */
-#define IRQ_M_EXT 11 /* until: priv-1.9.1 */
-#define IRQ_X_COP 12 /* non-standard */
-
-/* Default addresses */
-#define DEFAULT_RSTVEC 0x00001000
-
-/* RV32 satp field masks */
-#define SATP32_MODE 0x80000000
-#define SATP32_ASID 0x7fc00000
-#define SATP32_PPN 0x003fffff
-
-/* RV64 satp field masks */
-#define SATP64_MODE 0xF000000000000000ULL
-#define SATP64_ASID 0x0FFFF00000000000ULL
-#define SATP64_PPN 0x00000FFFFFFFFFFFULL
+/* RV32 satp CSR field masks */
+#define SATP32_MODE 0x80000000
+#define SATP32_ASID 0x7fc00000
+#define SATP32_PPN 0x003fffff
+
+/* RV64 satp CSR field masks */
+#define SATP64_MODE 0xF000000000000000ULL
+#define SATP64_ASID 0x0FFFF00000000000ULL
+#define SATP64_PPN 0x00000FFFFFFFFFFFULL
#if defined(TARGET_RISCV32)
-#define SATP_MODE SATP32_MODE
-#define SATP_ASID SATP32_ASID
-#define SATP_PPN SATP32_PPN
+#define SATP_MODE SATP32_MODE
+#define SATP_ASID SATP32_ASID
+#define SATP_PPN SATP32_PPN
#endif
#if defined(TARGET_RISCV64)
-#define SATP_MODE SATP64_MODE
-#define SATP_ASID SATP64_ASID
-#define SATP_PPN SATP64_PPN
+#define SATP_MODE SATP64_MODE
+#define SATP_ASID SATP64_ASID
+#define SATP_PPN SATP64_PPN
#endif
-/* RISCV Exception Codes */
-#define EXCP_NONE -1 /* not a real RISCV exception code */
+/* VM modes (mstatus.vm) privileged ISA 1.9.1 */
+#define VM_1_09_MBARE 0
+#define VM_1_09_MBB 1
+#define VM_1_09_MBBID 2
+#define VM_1_09_SV32 8
+#define VM_1_09_SV39 9
+#define VM_1_09_SV48 10
+
+/* VM modes (satp.mode) privileged ISA 1.10 */
+#define VM_1_10_MBARE 0
+#define VM_1_10_SV32 1
+#define VM_1_10_SV39 8
+#define VM_1_10_SV48 9
+#define VM_1_10_SV57 10
+#define VM_1_10_SV64 11
+
+/* Page table entry (PTE) fields */
+#define PTE_V 0x001 /* Valid */
+#define PTE_R 0x002 /* Read */
+#define PTE_W 0x004 /* Write */
+#define PTE_X 0x008 /* Execute */
+#define PTE_U 0x010 /* User */
+#define PTE_G 0x020 /* Global */
+#define PTE_A 0x040 /* Accessed */
+#define PTE_D 0x080 /* Dirty */
+#define PTE_SOFT 0x300 /* Reserved for Software */
+
+/* Page table PPN shift amount */
+#define PTE_PPN_SHIFT 10
+
+/* Leaf page shift amount */
+#define PGSHIFT 12
+
+/* Default Reset Vector adress */
+#define DEFAULT_RSTVEC 0x1000
+
+/* Exception causes */
+#define EXCP_NONE -1 /* sentinel value */
#define RISCV_EXCP_INST_ADDR_MIS 0x0
#define RISCV_EXCP_INST_ACCESS_FAULT 0x1
#define RISCV_EXCP_ILLEGAL_INST 0x2
@@ -382,9 +411,7 @@
#define RISCV_EXCP_LOAD_ACCESS_FAULT 0x5
#define RISCV_EXCP_STORE_AMO_ADDR_MIS 0x6
#define RISCV_EXCP_STORE_AMO_ACCESS_FAULT 0x7
-#define RISCV_EXCP_U_ECALL 0x8 /* for convenience, report all
- ECALLs as this, handler
- fixes */
+#define RISCV_EXCP_U_ECALL 0x8
#define RISCV_EXCP_S_ECALL 0x9
#define RISCV_EXCP_H_ECALL 0xa
#define RISCV_EXCP_M_ECALL 0xb
@@ -395,15 +422,35 @@
#define RISCV_EXCP_INT_FLAG 0x80000000
#define RISCV_EXCP_INT_MASK 0x7fffffff
-/* page table entry (PTE) fields */
-#define PTE_V 0x001 /* Valid */
-#define PTE_R 0x002 /* Read */
-#define PTE_W 0x004 /* Write */
-#define PTE_X 0x008 /* Execute */
-#define PTE_U 0x010 /* User */
-#define PTE_G 0x020 /* Global */
-#define PTE_A 0x040 /* Accessed */
-#define PTE_D 0x080 /* Dirty */
-#define PTE_SOFT 0x300 /* Reserved for Software */
-
-#define PTE_PPN_SHIFT 10
+/* Interrupt causes */
+#define IRQ_U_SOFT 0
+#define IRQ_S_SOFT 1
+#define IRQ_H_SOFT 2 /* reserved */
+#define IRQ_M_SOFT 3
+#define IRQ_U_TIMER 4
+#define IRQ_S_TIMER 5
+#define IRQ_H_TIMER 6 /* reserved */
+#define IRQ_M_TIMER 7
+#define IRQ_U_EXT 8
+#define IRQ_S_EXT 9
+#define IRQ_H_EXT 10 /* reserved */
+#define IRQ_M_EXT 11
+
+/* mip masks */
+#define MIP_USIP (1 << IRQ_U_SOFT)
+#define MIP_SSIP (1 << IRQ_S_SOFT)
+#define MIP_HSIP (1 << IRQ_H_SOFT)
+#define MIP_MSIP (1 << IRQ_M_SOFT)
+#define MIP_UTIP (1 << IRQ_U_TIMER)
+#define MIP_STIP (1 << IRQ_S_TIMER)
+#define MIP_HTIP (1 << IRQ_H_TIMER)
+#define MIP_MTIP (1 << IRQ_M_TIMER)
+#define MIP_UEIP (1 << IRQ_U_EXT)
+#define MIP_SEIP (1 << IRQ_S_EXT)
+#define MIP_HEIP (1 << IRQ_H_EXT)
+#define MIP_MEIP (1 << IRQ_M_EXT)
+
+/* sip masks */
+#define SIP_SSIP MIP_SSIP
+#define SIP_STIP MIP_STIP
+#define SIP_SEIP MIP_SEIP
diff --git a/target/riscv/helper.c b/target/riscv/cpu_helper.c
index 63b3386b76..86f9f4730c 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1,5 +1,5 @@
/*
- * RISC-V emulation helpers for qemu.
+ * RISC-V CPU helpers for qemu.
*
* Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
* Copyright (c) 2017-2018 SiFive, Inc.
@@ -72,6 +72,39 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
#if !defined(CONFIG_USER_ONLY)
+/* iothread_mutex must be held */
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
+{
+ CPURISCVState *env = &cpu->env;
+ uint32_t old, new, cmp = atomic_read(&env->mip);
+
+ do {
+ old = cmp;
+ new = (old & ~mask) | (value & mask);
+ cmp = atomic_cmpxchg(&env->mip, old, new);
+ } while (old != cmp);
+
+ if (new && !old) {
+ cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+ } else if (!new && old) {
+ cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+ }
+
+ return old;
+}
+
+void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
+{
+ if (newpriv > PRV_M) {
+ g_assert_not_reached();
+ }
+ if (newpriv == PRV_H) {
+ newpriv = PRV_U;
+ }
+ /* tlb_flush is unnecessary as mode is contained in mmu_idx */
+ env->priv = newpriv;
+}
+
/* get_physical_address - get the physical address for this virtual address
*
* Do a page table walk to obtain the physical address corresponding to a
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index aec7558e1b..3726299d4a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -90,7 +90,7 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
target_ulong csrno)
{
#ifndef CONFIG_USER_ONLY
- uint64_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_X_COP);
+ uint64_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP;
uint64_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
#endif
@@ -171,10 +171,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
*/
qemu_mutex_lock_iothread();
RISCVCPU *cpu = riscv_env_get_cpu(env);
- riscv_set_local_interrupt(cpu, MIP_SSIP,
- (val_to_write & MIP_SSIP) != 0);
- riscv_set_local_interrupt(cpu, MIP_STIP,
- (val_to_write & MIP_STIP) != 0);
+ riscv_cpu_update_mip(cpu, MIP_SSIP | MIP_STIP,
+ (val_to_write & (MIP_SSIP | MIP_STIP)));
/*
* csrs, csrc on mip.SEIP is not decomposable into separate read and
* write steps, so a different implementation is needed
@@ -656,31 +654,6 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
#ifndef CONFIG_USER_ONLY
-/* iothread_mutex must be held */
-void riscv_set_local_interrupt(RISCVCPU *cpu, target_ulong mask, int value)
-{
- target_ulong old_mip = cpu->env.mip;
- cpu->env.mip = (old_mip & ~mask) | (value ? mask : 0);
-
- if (cpu->env.mip && !old_mip) {
- cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
- } else if (!cpu->env.mip && old_mip) {
- cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
- }
-}
-
-void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
-{
- if (newpriv > PRV_M) {
- g_assert_not_reached();
- }
- if (newpriv == PRV_H) {
- newpriv = PRV_U;
- }
- /* tlb_flush is unnecessary as mode is contained in mmu_idx */
- env->priv = newpriv;
-}
-
target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
{
if (!(env->priv >= PRV_S)) {
@@ -731,7 +704,6 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
return retpc;
}
-
void helper_wfi(CPURISCVState *env)
{
CPUState *cs = CPU(riscv_env_get_cpu(env));
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 7fe8578972..f77a495109 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -115,7 +115,7 @@ check-unit-$(CONFIG_GNUTLS) += tests/test-io-channel-tls$(EXESUF)
check-unit-y += tests/test-io-channel-command$(EXESUF)
check-unit-y += tests/test-io-channel-buffer$(EXESUF)
check-unit-y += tests/test-base64$(EXESUF)
-check-unit-$(if $(CONFIG_NETTLE_KDF),y,$(CONFIG_GCRYPT_KDF)) += tests/test-crypto-pbkdf$(EXESUF)
+check-unit-$(if $(CONFIG_NETTLE),y,$(CONFIG_GCRYPT)) += tests/test-crypto-pbkdf$(EXESUF)
check-unit-y += tests/test-crypto-ivgen$(EXESUF)
check-unit-y += tests/test-crypto-afsplit$(EXESUF)
check-unit-y += tests/test-crypto-xts$(EXESUF)
diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c
index f5a0d0bc32..67fdf8c31d 100644
--- a/tests/benchmark-crypto-cipher.c
+++ b/tests/benchmark-crypto-cipher.c
@@ -15,17 +15,27 @@
#include "crypto/init.h"
#include "crypto/cipher.h"
-static void test_cipher_speed(const void *opaque)
+static void test_cipher_speed(size_t chunk_size,
+ QCryptoCipherMode mode,
+ QCryptoCipherAlgorithm alg)
{
QCryptoCipher *cipher;
Error *err = NULL;
double total = 0.0;
- size_t chunk_size = (size_t)opaque;
uint8_t *key = NULL, *iv = NULL;
uint8_t *plaintext = NULL, *ciphertext = NULL;
- size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128);
- size_t niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
- QCRYPTO_CIPHER_MODE_CBC);
+ size_t nkey;
+ size_t niv;
+
+ if (!qcrypto_cipher_supports(alg, mode)) {
+ return;
+ }
+
+ nkey = qcrypto_cipher_get_key_len(alg);
+ niv = qcrypto_cipher_get_iv_len(alg, mode);
+ if (mode == QCRYPTO_CIPHER_MODE_XTS) {
+ nkey *= 2;
+ }
key = g_new0(uint8_t, nkey);
memset(key, g_test_rand_int(), nkey);
@@ -38,14 +48,14 @@ static void test_cipher_speed(const void *opaque)
plaintext = g_new0(uint8_t, chunk_size);
memset(plaintext, g_test_rand_int(), chunk_size);
- cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
- QCRYPTO_CIPHER_MODE_CBC,
+ cipher = qcrypto_cipher_new(alg, mode,
key, nkey, &err);
g_assert(cipher != NULL);
- g_assert(qcrypto_cipher_setiv(cipher,
- iv, niv,
- &err) == 0);
+ if (mode != QCRYPTO_CIPHER_MODE_ECB)
+ g_assert(qcrypto_cipher_setiv(cipher,
+ iv, niv,
+ &err) == 0);
g_test_timer_start();
do {
@@ -55,13 +65,26 @@ static void test_cipher_speed(const void *opaque)
chunk_size,
&err) == 0);
total += chunk_size;
- } while (g_test_timer_elapsed() < 5.0);
+ } while (g_test_timer_elapsed() < 1.0);
total /= MiB;
- g_print("cbc(aes128): ");
- g_print("Testing chunk_size %zu bytes ", chunk_size);
- g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());
- g_print("%.2f MB/sec\n", total / g_test_timer_last());
+ g_print("Enc chunk %zu bytes ", chunk_size);
+ g_print("%.2f MB/sec ", total / g_test_timer_last());
+
+ total = 0.0;
+ g_test_timer_start();
+ do {
+ g_assert(qcrypto_cipher_decrypt(cipher,
+ plaintext,
+ ciphertext,
+ chunk_size,
+ &err) == 0);
+ total += chunk_size;
+ } while (g_test_timer_elapsed() < 1.0);
+
+ total /= MiB;
+ g_print("Dec chunk %zu bytes ", chunk_size);
+ g_print("%.2f MB/sec ", total / g_test_timer_last());
qcrypto_cipher_free(cipher);
g_free(plaintext);
@@ -70,19 +93,99 @@ static void test_cipher_speed(const void *opaque)
g_free(key);
}
-int main(int argc, char **argv)
+
+static void test_cipher_speed_ecb_aes_128(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_ECB,
+ QCRYPTO_CIPHER_ALG_AES_128);
+}
+
+static void test_cipher_speed_ecb_aes_256(const void *opaque)
{
- size_t i;
- char name[64];
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_ECB,
+ QCRYPTO_CIPHER_ALG_AES_256);
+}
+
+static void test_cipher_speed_cbc_aes_128(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_CBC,
+ QCRYPTO_CIPHER_ALG_AES_128);
+}
+static void test_cipher_speed_cbc_aes_256(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_CBC,
+ QCRYPTO_CIPHER_ALG_AES_256);
+}
+
+static void test_cipher_speed_ctr_aes_128(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_CTR,
+ QCRYPTO_CIPHER_ALG_AES_128);
+}
+
+static void test_cipher_speed_ctr_aes_256(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_CTR,
+ QCRYPTO_CIPHER_ALG_AES_256);
+}
+
+static void test_cipher_speed_xts_aes_128(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_XTS,
+ QCRYPTO_CIPHER_ALG_AES_128);
+}
+
+static void test_cipher_speed_xts_aes_256(const void *opaque)
+{
+ size_t chunk_size = (size_t)opaque;
+ test_cipher_speed(chunk_size,
+ QCRYPTO_CIPHER_MODE_XTS,
+ QCRYPTO_CIPHER_ALG_AES_256);
+}
+
+
+int main(int argc, char **argv)
+{
g_test_init(&argc, &argv, NULL);
g_assert(qcrypto_init(NULL) == 0);
- for (i = 512; i <= 64 * KiB; i *= 2) {
- memset(name, 0 , sizeof(name));
- snprintf(name, sizeof(name), "/crypto/cipher/speed-%zu", i);
- g_test_add_data_func(name, (void *)i, test_cipher_speed);
- }
+#define ADD_TEST(mode, cipher, keysize, chunk) \
+ g_test_add_data_func( \
+ "/crypto/cipher/" #mode "-" #cipher "-" #keysize "/chunk-" #chunk, \
+ (void *)chunk, \
+ test_cipher_speed_ ## mode ## _ ## cipher ## _ ## keysize)
+
+#define ADD_TESTS(chunk) \
+ do { \
+ ADD_TEST(ecb, aes, 128, chunk); \
+ ADD_TEST(ecb, aes, 256, chunk); \
+ ADD_TEST(cbc, aes, 128, chunk); \
+ ADD_TEST(cbc, aes, 256, chunk); \
+ ADD_TEST(ctr, aes, 128, chunk); \
+ ADD_TEST(ctr, aes, 256, chunk); \
+ ADD_TEST(xts, aes, 128, chunk); \
+ ADD_TEST(xts, aes, 256, chunk); \
+ } while (0)
+
+ ADD_TESTS(512);
+ ADD_TESTS(4096);
+ ADD_TESTS(16384);
+ ADD_TESTS(65536);
return g_test_run();
}
diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c
index 3e93c8e096..f4a677d238 100644
--- a/tests/cpu-plug-test.c
+++ b/tests/cpu-plug-test.c
@@ -32,12 +32,12 @@ static void test_plug_with_cpu_add(gconstpointer data)
unsigned int i;
args = g_strdup_printf("-machine %s -cpu %s "
- "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
+ "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
s->machine, s->cpu_model,
s->sockets, s->cores, s->threads, s->maxcpus);
qtest_start(args);
- for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) {
+ for (i = 1; i < s->maxcpus; i++) {
response = qmp("{ 'execute': 'cpu-add',"
" 'arguments': { 'id': %d } }", i);
g_assert(response);
@@ -56,7 +56,7 @@ static void test_plug_without_cpu_add(gconstpointer data)
QDict *response;
args = g_strdup_printf("-machine %s -cpu %s "
- "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
+ "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
s->machine, s->cpu_model,
s->sockets, s->cores, s->threads, s->maxcpus);
qtest_start(args);
@@ -79,12 +79,12 @@ static void test_plug_with_device_add_x86(gconstpointer data)
unsigned int s, c, t;
args = g_strdup_printf("-machine %s -cpu %s "
- "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
+ "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
td->machine, td->cpu_model,
td->sockets, td->cores, td->threads, td->maxcpus);
qtest_start(args);
- for (s = td->sockets; s < td->maxcpus / td->cores / td->threads; s++) {
+ for (s = 1; s < td->sockets; s++) {
for (c = 0; c < td->cores; c++) {
for (t = 0; t < td->threads; t++) {
char *id = g_strdup_printf("id-%i-%i-%i", s, c, t);
@@ -113,7 +113,7 @@ static void test_plug_with_device_add_coreid(gconstpointer data)
td->sockets, td->cores, td->threads, td->maxcpus);
qtest_start(args);
- for (c = td->cores; c < td->maxcpus / td->sockets / td->threads; c++) {
+ for (c = 1; c < td->cores; c++) {
char *id = g_strdup_printf("id-%i", c);
qtest_qmp_device_add(td->device_model, id, "{'core-id':%u}", c);
g_free(id);
@@ -148,7 +148,7 @@ static void add_pc_test_case(const char *mname)
data->sockets = 1;
data->cores = 3;
data->threads = 2;
- data->maxcpus = data->sockets * data->cores * data->threads * 2;
+ data->maxcpus = data->sockets * data->cores * data->threads;
if (g_str_has_suffix(mname, "-1.4") ||
(strcmp(mname, "pc-1.3") == 0) ||
(strcmp(mname, "pc-1.2") == 0) ||
@@ -203,7 +203,7 @@ static void add_pseries_test_case(const char *mname)
data->sockets = 2;
data->cores = 3;
data->threads = 1;
- data->maxcpus = data->sockets * data->cores * data->threads * 2;
+ data->maxcpus = data->sockets * data->cores * data->threads;
path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
mname, data->sockets, data->cores,
@@ -229,7 +229,7 @@ static void add_s390x_test_case(const char *mname)
data->sockets = 1;
data->cores = 3;
data->threads = 1;
- data->maxcpus = data->sockets * data->cores * data->threads * 2;
+ data->maxcpus = data->sockets * data->cores * data->threads;
data2 = g_memdup(data, sizeof(PlugTestData));
data2->machine = g_strdup(data->machine);
diff --git a/tests/crypto-tls-x509-helpers.h b/tests/crypto-tls-x509-helpers.h
index 921341c649..88c30d7c94 100644
--- a/tests/crypto-tls-x509-helpers.h
+++ b/tests/crypto-tls-x509-helpers.h
@@ -22,8 +22,7 @@
#include <gnutls/x509.h>
#if !(defined WIN32) && \
- defined(CONFIG_TASN1) && \
- (LIBGNUTLS_VERSION_NUMBER >= 0x020600)
+ defined(CONFIG_TASN1)
# define QCRYPTO_HAVE_TLS_TEST_SUPPORT
#endif
diff --git a/tests/docker/dockerfiles/debian-bootstrap.pre b/tests/docker/dockerfiles/debian-bootstrap.pre
index 3b0ef95374..c164778c30 100755
--- a/tests/docker/dockerfiles/debian-bootstrap.pre
+++ b/tests/docker/dockerfiles/debian-bootstrap.pre
@@ -2,7 +2,7 @@
#
# Simple wrapper for debootstrap, run in the docker build context
#
-FAKEROOT=`which fakeroot 2> /dev/null`
+FAKEROOT=$(which fakeroot 2> /dev/null)
# debootstrap < 1.0.67 generates empty sources.list, see Debian#732255
MIN_DEBOOTSTRAP_VERSION=1.0.67
@@ -52,7 +52,7 @@ fi
if [ -z $DEBOOTSTRAP_DIR ]; then
NEED_DEBOOTSTRAP=false
- DEBOOTSTRAP=`which debootstrap 2> /dev/null`
+ DEBOOTSTRAP=$(which debootstrap 2> /dev/null)
if [ -z $DEBOOTSTRAP ]; then
echo "No debootstrap installed, attempting to install from SCM"
NEED_DEBOOTSTRAP=true
diff --git a/tests/docker/test-mingw b/tests/docker/test-mingw
index 7cca7e16a6..b078f22879 100755
--- a/tests/docker/test-mingw
+++ b/tests/docker/test-mingw
@@ -28,8 +28,7 @@ for prefix in x86_64-w64-mingw32- i686-w64-mingw32-; do
--enable-vnc \
--enable-bzip2 \
--enable-guest-agent \
- --with-sdlabi=2.0 \
- --with-gtkabi=3.0
+ --with-sdlabi=2.0
install_qemu
make clean
diff --git a/tests/migration-test.c b/tests/migration-test.c
index b7920255c5..06ca5068d8 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -803,6 +803,22 @@ int main(int argc, char **argv)
return 0;
}
+ /*
+ * Similar to ppc64, s390x seems to be touchy with TCG, so disable it
+ * there until the problems are resolved
+ */
+ if (g_str_equal(qtest_get_arch(), "s390x")) {
+#if defined(HOST_S390X)
+ if (access("/dev/kvm", R_OK | W_OK)) {
+ g_test_message("Skipping test: kvm not available");
+ return 0;
+ }
+#else
+ g_test_message("Skipping test: Need s390x host to work properly");
+ return 0;
+#endif
+ }
+
tmpfs = mkdtemp(template);
if (!tmpfs) {
g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 0871bff564..6b505408dd 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -95,35 +95,31 @@ qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1024
qemu-img: Image size must be less than 8 EiB!
qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
-qemu-img: Value '-1024' is out of range for parameter 'size'
-qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
+qemu-img: TEST_DIR/t.qcow2: Value '-1024' is out of range for parameter 'size'
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
qemu-img: Image size must be less than 8 EiB!
qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2
-qemu-img: Value '-1k' is out of range for parameter 'size'
-qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
+qemu-img: TEST_DIR/t.qcow2: Value '-1k' is out of range for parameter 'size'
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
-qemu-img: Parameter 'size' expects a non-negative number below 2^64
+qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
-qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for
qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
-qemu-img: Parameter 'size' expects a non-negative number below 2^64
+qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
-qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2'
== Check correct interpretation of suffixes for cluster size ==
diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile
new file mode 100644
index 0000000000..a1c388bc3c
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/Makefile
@@ -0,0 +1,30 @@
+-include ../../config-host.mak
+
+CROSS=mipsr5900el-unknown-linux-gnu-
+
+SIM=qemu-mipsel
+SIM_FLAGS=-cpu R5900
+
+CC = $(CROSS)gcc
+CFLAGS = -Wall -mabi=32 -march=r5900 -static
+
+TESTCASES = div1.tst
+TESTCASES += divu1.tst
+TESTCASES += mflohi1.tst
+TESTCASES += mtlohi1.tst
+TESTCASES += mult.tst
+TESTCASES += multu.tst
+
+all: $(TESTCASES)
+
+%.tst: %.c
+ $(CC) $(CFLAGS) $< -o $@
+
+check: $(TESTCASES)
+ @for case in $(TESTCASES); do \
+ echo $(SIM) $(SIM_FLAGS) ./$$case;\
+ $(SIM) $(SIM_FLAGS) ./$$case; \
+ done
+
+clean:
+ $(RM) -rf $(TESTCASES)
diff --git a/tests/tcg/mips/mipsr5900/div1.c b/tests/tcg/mips/mipsr5900/div1.c
new file mode 100644
index 0000000000..83dafa018b
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/div1.c
@@ -0,0 +1,73 @@
+/*
+ * Test R5900-specific DIV1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+struct quotient_remainder { int32_t quotient, remainder; };
+
+static struct quotient_remainder div1(int32_t rs, int32_t rt)
+{
+ int32_t lo, hi;
+
+ __asm__ __volatile__ (
+ " div1 $0, %2, %3\n"
+ " mflo1 %0\n"
+ " mfhi1 %1\n"
+ : "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+
+ assert(rs / rt == lo);
+ assert(rs % rt == hi);
+
+ return (struct quotient_remainder) { .quotient = lo, .remainder = hi };
+}
+
+static void verify_div1(int32_t rs, int32_t rt,
+ int32_t expected_quotient,
+ int32_t expected_remainder)
+{
+ struct quotient_remainder qr = div1(rs, rt);
+
+ assert(qr.quotient == expected_quotient);
+ assert(qr.remainder == expected_remainder);
+}
+
+static void verify_div1_negations(int32_t rs, int32_t rt,
+ int32_t expected_quotient,
+ int32_t expected_remainder)
+{
+ verify_div1(rs, rt, expected_quotient, expected_remainder);
+ verify_div1(rs, -rt, -expected_quotient, expected_remainder);
+ verify_div1(-rs, rt, -expected_quotient, -expected_remainder);
+ verify_div1(-rs, -rt, expected_quotient, -expected_remainder);
+}
+
+int main()
+{
+ verify_div1_negations(0, 1, 0, 0);
+ verify_div1_negations(1, 1, 1, 0);
+ verify_div1_negations(1, 2, 0, 1);
+ verify_div1_negations(17, 19, 0, 17);
+ verify_div1_negations(19, 17, 1, 2);
+ verify_div1_negations(77773, 101, 770, 3);
+
+ verify_div1(-0x80000000, 1, -0x80000000, 0);
+
+ /*
+ * Supplementary explanation from the Toshiba TX System RISC TX79 Core
+ * Architecture manual, A-38 and B-7, https://wiki.qemu.org/File:C790.pdf
+ *
+ * Normally, when 0x80000000 (-2147483648) the signed minimum value is
+ * divided by 0xFFFFFFFF (-1), the operation will result in an overflow.
+ * However, in this instruction an overflow exception doesn't occur and
+ * the result will be as follows:
+ *
+ * Quotient is 0x80000000 (-2147483648), and remainder is 0x00000000 (0).
+ */
+ verify_div1(-0x80000000, -1, -0x80000000, 0);
+
+ return 0;
+}
diff --git a/tests/tcg/mips/mipsr5900/divu1.c b/tests/tcg/mips/mipsr5900/divu1.c
new file mode 100644
index 0000000000..72aeed31de
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/divu1.c
@@ -0,0 +1,48 @@
+/*
+ * Test R5900-specific DIVU1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+struct quotient_remainder { uint32_t quotient, remainder; };
+
+static struct quotient_remainder divu1(uint32_t rs, uint32_t rt)
+{
+ uint32_t lo, hi;
+
+ __asm__ __volatile__ (
+ " divu1 $0, %2, %3\n"
+ " mflo1 %0\n"
+ " mfhi1 %1\n"
+ : "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+
+ assert(rs / rt == lo);
+ assert(rs % rt == hi);
+
+ return (struct quotient_remainder) { .quotient = lo, .remainder = hi };
+}
+
+static void verify_divu1(uint32_t rs, uint32_t rt,
+ uint32_t expected_quotient,
+ uint32_t expected_remainder)
+{
+ struct quotient_remainder qr = divu1(rs, rt);
+
+ assert(qr.quotient == expected_quotient);
+ assert(qr.remainder == expected_remainder);
+}
+
+int main()
+{
+ verify_divu1(0, 1, 0, 0);
+ verify_divu1(1, 1, 1, 0);
+ verify_divu1(1, 2, 0, 1);
+ verify_divu1(17, 19, 0, 17);
+ verify_divu1(19, 17, 1, 2);
+ verify_divu1(77773, 101, 770, 3);
+
+ return 0;
+}
diff --git a/tests/tcg/mips/mipsr5900/mflohi1.c b/tests/tcg/mips/mipsr5900/mflohi1.c
new file mode 100644
index 0000000000..eed3683dc5
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/mflohi1.c
@@ -0,0 +1,35 @@
+/*
+ * Test R5900-specific MFLO1 and MFHI1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+int main()
+{
+ int32_t rs = 12207031, rt = 305175781;
+ int32_t rs1 = 32452867, rt1 = 49979687;
+ int64_t lo, hi, lo1, hi1;
+ int64_t r, r1;
+
+ /* Test both LO/HI and LO1/HI1 to verify separation. */
+ __asm__ __volatile__ (
+ " mult $0, %4, %5\n"
+ " mult1 $0, %6, %7\n"
+ " mflo %0\n"
+ " mfhi %1\n"
+ " mflo1 %2\n"
+ " mfhi1 %3\n"
+ : "=r" (lo), "=r" (hi),
+ "=r" (lo1), "=r" (hi1)
+ : "r" (rs), "r" (rt),
+ "r" (rs1), "r" (rt1));
+ r = ((int64_t)hi << 32) | (uint32_t)lo;
+ r1 = ((int64_t)hi1 << 32) | (uint32_t)lo1;
+
+ assert(r == 3725290219116211);
+ assert(r1 == 1621984134912629);
+
+ return 0;
+}
diff --git a/tests/tcg/mips/mipsr5900/mtlohi1.c b/tests/tcg/mips/mipsr5900/mtlohi1.c
new file mode 100644
index 0000000000..7f3e72835a
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/mtlohi1.c
@@ -0,0 +1,40 @@
+/*
+ * Test R5900-specific MTLO1 and MTHI1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+int main()
+{
+ int32_t tlo = 12207031, thi = 305175781;
+ int32_t tlo1 = 32452867, thi1 = 49979687;
+ int32_t flo, fhi, flo1, fhi1;
+
+ /* Test both LO/HI and LO1/HI1 to verify separation. */
+ __asm__ __volatile__ (
+ " mtlo %4\n"
+ " mthi %5\n"
+ " mtlo1 %6\n"
+ " mthi1 %7\n"
+ " move %0, $0\n"
+ " move %1, $0\n"
+ " move %2, $0\n"
+ " move %3, $0\n"
+ " mflo %0\n"
+ " mfhi %1\n"
+ " mflo1 %2\n"
+ " mfhi1 %3\n"
+ : "=r" (flo), "=r" (fhi),
+ "=r" (flo1), "=r" (fhi1)
+ : "r" (tlo), "r" (thi),
+ "r" (tlo1), "r" (thi1));
+
+ assert(flo == 12207031);
+ assert(fhi == 305175781);
+ assert(flo1 == 32452867);
+ assert(fhi1 == 49979687);
+
+ return 0;
+}
diff --git a/tests/tcg/mips/mipsr5900/mult.c b/tests/tcg/mips/mipsr5900/mult.c
new file mode 100644
index 0000000000..5710b395e6
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/mult.c
@@ -0,0 +1,76 @@
+/*
+ * Test R5900-specific three-operand MULT and MULT1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+static int64_t mult(int32_t rs, int32_t rt)
+{
+ int32_t rd, lo, hi;
+ int64_t r;
+
+ __asm__ __volatile__ (
+ " mult %0, %3, %4\n"
+ " mflo %1\n"
+ " mfhi %2\n"
+ : "=r" (rd), "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+ r = ((int64_t)hi << 32) | (uint32_t)lo;
+
+ assert((int64_t)rs * rt == r);
+ assert(rd == lo);
+
+ return r;
+}
+
+static int64_t mult1(int32_t rs, int32_t rt)
+{
+ int32_t rd, lo, hi;
+ int64_t r;
+
+ __asm__ __volatile__ (
+ " mult1 %0, %3, %4\n"
+ " mflo1 %1\n"
+ " mfhi1 %2\n"
+ : "=r" (rd), "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+ r = ((int64_t)hi << 32) | (uint32_t)lo;
+
+ assert((int64_t)rs * rt == r);
+ assert(rd == lo);
+
+ return r;
+}
+
+static int64_t mult_variants(int32_t rs, int32_t rt)
+{
+ int64_t rd = mult(rs, rt);
+ int64_t rd1 = mult1(rs, rt);
+
+ assert(rd == rd1);
+
+ return rd;
+}
+
+static void verify_mult_negations(int32_t rs, int32_t rt, int64_t expected)
+{
+ assert(mult_variants(rs, rt) == expected);
+ assert(mult_variants(-rs, rt) == -expected);
+ assert(mult_variants(rs, -rt) == -expected);
+ assert(mult_variants(-rs, -rt) == expected);
+}
+
+int main()
+{
+ verify_mult_negations(17, 19, 323);
+ verify_mult_negations(77773, 99991, 7776600043);
+ verify_mult_negations(12207031, 305175781, 3725290219116211);
+
+ assert(mult_variants(-0x80000000, 0x7FFFFFFF) == -0x3FFFFFFF80000000);
+ assert(mult_variants(-0x80000000, -0x7FFFFFFF) == 0x3FFFFFFF80000000);
+ assert(mult_variants(-0x80000000, -0x80000000) == 0x4000000000000000);
+
+ return 0;
+}
diff --git a/tests/tcg/mips/mipsr5900/multu.c b/tests/tcg/mips/mipsr5900/multu.c
new file mode 100644
index 0000000000..f043904d69
--- /dev/null
+++ b/tests/tcg/mips/mipsr5900/multu.c
@@ -0,0 +1,68 @@
+/*
+ * Test R5900-specific three-operand MULTU and MULTU1.
+ */
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <assert.h>
+
+static uint64_t multu(uint32_t rs, uint32_t rt)
+{
+ uint32_t rd, lo, hi;
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ " multu %0, %3, %4\n"
+ " mflo %1\n"
+ " mfhi %2\n"
+ : "=r" (rd), "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+ r = ((uint64_t)hi << 32) | (uint32_t)lo;
+
+ assert((uint64_t)rs * rt == r);
+ assert(rd == lo);
+
+ return r;
+}
+
+static uint64_t multu1(uint32_t rs, uint32_t rt)
+{
+ uint32_t rd, lo, hi;
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ " multu1 %0, %3, %4\n"
+ " mflo1 %1\n"
+ " mfhi1 %2\n"
+ : "=r" (rd), "=r" (lo), "=r" (hi)
+ : "r" (rs), "r" (rt));
+ r = ((uint64_t)hi << 32) | (uint32_t)lo;
+
+ assert((uint64_t)rs * rt == r);
+ assert(rd == lo);
+
+ return r;
+}
+
+static uint64_t multu_variants(uint32_t rs, uint32_t rt)
+{
+ uint64_t rd = multu(rs, rt);
+ uint64_t rd1 = multu1(rs, rt);
+
+ assert(rd == rd1);
+
+ return rd;
+}
+
+int main()
+{
+ assert(multu_variants(17, 19) == 323);
+ assert(multu_variants(77773, 99991) == 7776600043);
+ assert(multu_variants(12207031, 305175781) == 3725290219116211);
+
+ assert(multu_variants(0x80000000U, 0x7FFFFFFF) == 0x3FFFFFFF80000000);
+ assert(multu_variants(0x80000000U, 0x80000000U) == 0x4000000000000000);
+ assert(multu_variants(0xFFFFFFFFU, 0xFFFFFFFFU) == 0xFFFFFFFE00000001U);
+
+ return 0;
+}
diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c
index fd29a045d2..fae4ffc453 100644
--- a/tests/test-crypto-block.c
+++ b/tests/test-crypto-block.c
@@ -29,7 +29,7 @@
#endif
#if (defined(_WIN32) || defined RUSAGE_THREAD) && \
- (defined(CONFIG_NETTLE_KDF) || defined(CONFIG_GCRYPT_KDF))
+ (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT))
#define TEST_LUKS
#else
#undef TEST_LUKS
diff --git a/tests/test-crypto-tlscredsx509.c b/tests/test-crypto-tlscredsx509.c
index 30f9ac4bbf..940a026c6e 100644
--- a/tests/test-crypto-tlscredsx509.c
+++ b/tests/test-crypto-tlscredsx509.c
@@ -283,14 +283,8 @@ int main(int argc, char **argv)
true, true, GNUTLS_KP_TLS_WWW_SERVER, NULL,
0, 0);
- /* Technically a CA cert with basic constraints
- * key purpose == key signing + non-critical should
- * be rejected. GNUTLS < 3.1 does not reject it and
- * we don't anticipate them changing this behaviour
- */
TLS_TEST_REG(badca1, true, cacert4req.filename, servercert4req.filename,
- (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR >= 1) ||
- GNUTLS_VERSION_MAJOR > 3);
+ true);
TLS_TEST_REG(badca2, true,
cacert5req.filename, servercert5req.filename, true);
TLS_TEST_REG(badca3, true,
diff --git a/tests/test-crypto-xts.c b/tests/test-crypto-xts.c
index 1f1412c45a..6fb61cf635 100644
--- a/tests/test-crypto-xts.c
+++ b/tests/test-crypto-xts.c
@@ -1,7 +1,7 @@
/*
* QEMU Crypto XTS cipher mode
*
- * Copyright (c) 2015-2016 Red Hat, Inc.
+ * Copyright (c) 2015-2018 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -340,70 +340,161 @@ static void test_xts_aes_decrypt(const void *ctx,
static void test_xts(const void *opaque)
{
const QCryptoXTSTestData *data = opaque;
- unsigned char out[512], Torg[16], T[16];
+ uint8_t out[512], Torg[16], T[16];
uint64_t seq;
- int j;
- unsigned long len;
struct TestAES aesdata;
struct TestAES aestweak;
- for (j = 0; j < 2; j++) {
- /* skip the cases where
- * the length is smaller than 2*blocklen
- * or the length is not a multiple of 32
- */
- if ((j == 1) && ((data->PTLEN < 32) || (data->PTLEN % 32))) {
- continue;
- }
- len = data->PTLEN / 2;
-
- AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.enc);
- AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.dec);
- AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.enc);
- AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.dec);
-
- seq = data->seqnum;
- STORE64L(seq, Torg);
- memset(Torg + 8, 0, 8);
-
- memcpy(T, Torg, sizeof(T));
- if (j == 0) {
- xts_encrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, data->PTLEN, out, data->PTX);
- } else {
- xts_encrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, len, out, data->PTX);
- xts_encrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, len, &out[len], &data->PTX[len]);
- }
+ AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.enc);
+ AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.dec);
+ AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.enc);
+ AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.dec);
- g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
-
- memcpy(T, Torg, sizeof(T));
- if (j == 0) {
- xts_decrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, data->PTLEN, out, data->CTX);
- } else {
- xts_decrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, len, out, data->CTX);
- xts_decrypt(&aesdata, &aestweak,
- test_xts_aes_encrypt,
- test_xts_aes_decrypt,
- T, len, &out[len], &data->CTX[len]);
- }
+ seq = data->seqnum;
+ STORE64L(seq, Torg);
+ memset(Torg + 8, 0, 8);
- g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
- }
+ memcpy(T, Torg, sizeof(T));
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out, data->PTX);
+
+ g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
+
+ memcpy(T, Torg, sizeof(T));
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out, data->CTX);
+
+ g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
+}
+
+
+static void test_xts_split(const void *opaque)
+{
+ const QCryptoXTSTestData *data = opaque;
+ uint8_t out[512], Torg[16], T[16];
+ uint64_t seq;
+ unsigned long len = data->PTLEN / 2;
+ struct TestAES aesdata;
+ struct TestAES aestweak;
+
+ AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.enc);
+ AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.dec);
+ AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.enc);
+ AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.dec);
+
+ seq = data->seqnum;
+ STORE64L(seq, Torg);
+ memset(Torg + 8, 0, 8);
+
+ memcpy(T, Torg, sizeof(T));
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, len, out, data->PTX);
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, len, &out[len], &data->PTX[len]);
+
+ g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
+
+ memcpy(T, Torg, sizeof(T));
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, len, out, data->CTX);
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, len, &out[len], &data->CTX[len]);
+
+ g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
+}
+
+
+static void test_xts_unaligned(const void *opaque)
+{
+#define BAD_ALIGN 3
+ const QCryptoXTSTestData *data = opaque;
+ uint8_t in[512 + BAD_ALIGN], out[512 + BAD_ALIGN];
+ uint8_t Torg[16], T[16 + BAD_ALIGN];
+ uint64_t seq;
+ struct TestAES aesdata;
+ struct TestAES aestweak;
+
+ AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.enc);
+ AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, &aesdata.dec);
+ AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.enc);
+ AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, &aestweak.dec);
+
+ seq = data->seqnum;
+ STORE64L(seq, Torg);
+ memset(Torg + 8, 0, 8);
+
+ /* IV not aligned */
+ memcpy(T + BAD_ALIGN, Torg, 16);
+ memcpy(in, data->PTX, data->PTLEN);
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T + BAD_ALIGN, data->PTLEN, out, in);
+
+ g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
+
+ /* plain text not aligned */
+ memcpy(T, Torg, 16);
+ memcpy(in + BAD_ALIGN, data->PTX, data->PTLEN);
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out, in + BAD_ALIGN);
+
+ g_assert(memcmp(out, data->CTX, data->PTLEN) == 0);
+
+ /* cipher text not aligned */
+ memcpy(T, Torg, 16);
+ memcpy(in, data->PTX, data->PTLEN);
+ xts_encrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out + BAD_ALIGN, in);
+
+ g_assert(memcmp(out + BAD_ALIGN, data->CTX, data->PTLEN) == 0);
+
+
+ /* IV not aligned */
+ memcpy(T + BAD_ALIGN, Torg, 16);
+ memcpy(in, data->CTX, data->PTLEN);
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T + BAD_ALIGN, data->PTLEN, out, in);
+
+ g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
+
+ /* cipher text not aligned */
+ memcpy(T, Torg, 16);
+ memcpy(in + BAD_ALIGN, data->CTX, data->PTLEN);
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out, in + BAD_ALIGN);
+
+ g_assert(memcmp(out, data->PTX, data->PTLEN) == 0);
+
+ /* plain text not aligned */
+ memcpy(T, Torg, 16);
+ memcpy(in, data->CTX, data->PTLEN);
+ xts_decrypt(&aesdata, &aestweak,
+ test_xts_aes_encrypt,
+ test_xts_aes_decrypt,
+ T, data->PTLEN, out + BAD_ALIGN, in);
+
+ g_assert(memcmp(out + BAD_ALIGN, data->PTX, data->PTLEN) == 0);
}
@@ -416,7 +507,22 @@ int main(int argc, char **argv)
g_assert(qcrypto_init(NULL) == 0);
for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
- g_test_add_data_func(test_data[i].path, &test_data[i], test_xts);
+ gchar *path = g_strdup_printf("%s/basic", test_data[i].path);
+ g_test_add_data_func(path, &test_data[i], test_xts);
+ g_free(path);
+
+ /* skip the cases where the length is smaller than 2*blocklen
+ * or the length is not a multiple of 32
+ */
+ if ((test_data[i].PTLEN >= 32) && !(test_data[i].PTLEN % 32)) {
+ path = g_strdup_printf("%s/split", test_data[i].path);
+ g_test_add_data_func(path, &test_data[i], test_xts_split);
+ g_free(path);
+ }
+
+ path = g_strdup_printf("%s/unaligned", test_data[i].path);
+ g_test_add_data_func(path, &test_data[i], test_xts_unaligned);
+ g_free(path);
}
return g_test_run();
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index cafbc6b3a5..5caf77d6b8 100755
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -18,7 +18,7 @@ import logging
import time
import datetime
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
-from qemu import QEMUMachine
+from qemu import QEMUMachine, kvm_available
import subprocess
import hashlib
import optparse
@@ -42,6 +42,8 @@ class BaseVM(object):
BUILD_SCRIPT = ""
# The guest name, to be overridden by subclasses
name = "#base"
+ # The guest architecture, to be overridden by subclasses
+ arch = "#arch"
def __init__(self, debug=False, vcpus=None):
self._guest = None
self._tmpdir = os.path.realpath(tempfile.mkdtemp(prefix="vm-test-",
@@ -70,9 +72,9 @@ class BaseVM(object):
"-device", "virtio-net-pci,netdev=vnet",
"-vnc", "127.0.0.1:0,to=20",
"-serial", "file:%s" % os.path.join(self._tmpdir, "serial.out")]
- if vcpus:
+ if vcpus and vcpus > 1:
self._args += ["-smp", str(vcpus)]
- if os.access("/dev/kvm", os.R_OK | os.W_OK):
+ if kvm_available(self.arch):
self._args += ["-enable-kvm"]
else:
logging.info("KVM not available, not using -enable-kvm")
@@ -151,7 +153,7 @@ class BaseVM(object):
"-device", "virtio-blk,drive=drive0,bootindex=0"]
args += self._data_args + extra_args
logging.debug("QEMU args: %s", " ".join(args))
- qemu_bin = os.environ.get("QEMU", "qemu-system-x86_64")
+ qemu_bin = os.environ.get("QEMU", "qemu-system-" + self.arch)
guest = QEMUMachine(binary=qemu_bin, args=args)
try:
guest.launch()
@@ -177,11 +179,14 @@ class BaseVM(object):
def wait_ssh(self, seconds=300):
starttime = datetime.datetime.now()
+ endtime = starttime + datetime.timedelta(seconds=seconds)
guest_up = False
- while (datetime.datetime.now() - starttime).total_seconds() < seconds:
+ while datetime.datetime.now() < endtime:
if self.ssh("exit 0") == 0:
guest_up = True
break
+ seconds = (endtime - datetime.datetime.now()).total_seconds()
+ logging.debug("%ds before timeout", seconds)
time.sleep(1)
if not guest_up:
raise Exception("Timeout while waiting for guest ssh")
@@ -195,7 +200,14 @@ class BaseVM(object):
def qmp(self, *args, **kwargs):
return self._guest.qmp(*args, **kwargs)
-def parse_args(vm_name):
+def parse_args(vmcls):
+
+ def get_default_jobs():
+ if kvm_available(vmcls.arch):
+ return multiprocessing.cpu_count() / 2
+ else:
+ return 1
+
parser = optparse.OptionParser(
description="VM test utility. Exit codes: "
"0 = success, "
@@ -204,11 +216,11 @@ def parse_args(vm_name):
"3 = test command failed")
parser.add_option("--debug", "-D", action="store_true",
help="enable debug output")
- parser.add_option("--image", "-i", default="%s.img" % vm_name,
+ parser.add_option("--image", "-i", default="%s.img" % vmcls.name,
help="image file name")
parser.add_option("--force", "-f", action="store_true",
help="force build image even if image exists")
- parser.add_option("--jobs", type=int, default=multiprocessing.cpu_count() / 2,
+ parser.add_option("--jobs", type=int, default=get_default_jobs(),
help="number of virtual CPUs")
parser.add_option("--verbose", "-V", action="store_true",
help="Pass V=1 to builds within the guest")
@@ -225,7 +237,7 @@ def parse_args(vm_name):
def main(vmcls):
try:
- args, argv = parse_args(vmcls.name)
+ args, argv = parse_args(vmcls)
if not argv and not args.build_qemu and not args.build_image:
print("Nothing to do?")
return 1
diff --git a/tests/vm/centos b/tests/vm/centos
index afd560c564..daa2dbca03 100755
--- a/tests/vm/centos
+++ b/tests/vm/centos
@@ -19,6 +19,7 @@ import time
class CentosVM(basevm.BaseVM):
name = "centos"
+ arch = "x86_64"
BUILD_SCRIPT = """
set -e;
cd $(mktemp -d);
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index b6983127d0..19a3729172 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -18,6 +18,7 @@ import basevm
class FreeBSDVM(basevm.BaseVM):
name = "freebsd"
+ arch = "x86_64"
BUILD_SCRIPT = """
set -e;
rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/netbsd b/tests/vm/netbsd
index a4e25820d5..fac6a7ce51 100755
--- a/tests/vm/netbsd
+++ b/tests/vm/netbsd
@@ -18,6 +18,7 @@ import basevm
class NetBSDVM(basevm.BaseVM):
name = "netbsd"
+ arch = "x86_64"
BUILD_SCRIPT = """
set -e;
rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/openbsd b/tests/vm/openbsd
index 52500ee52b..cfe0572c59 100755
--- a/tests/vm/openbsd
+++ b/tests/vm/openbsd
@@ -18,6 +18,7 @@ import basevm
class OpenBSDVM(basevm.BaseVM):
name = "openbsd"
+ arch = "x86_64"
BUILD_SCRIPT = """
set -e;
rm -rf /var/tmp/qemu-test.*
diff --git a/tests/vm/ubuntu.i386 b/tests/vm/ubuntu.i386
index 3f6ed48b74..1b7e1ab8f0 100755
--- a/tests/vm/ubuntu.i386
+++ b/tests/vm/ubuntu.i386
@@ -19,6 +19,7 @@ import time
class UbuntuX86VM(basevm.BaseVM):
name = "ubuntu.i386"
+ arch = "i386"
BUILD_SCRIPT = """
set -e;
cd $(mktemp -d);
diff --git a/tpm.c b/tpm.c
index 93031723ad..9c9e20bbb7 100644
--- a/tpm.c
+++ b/tpm.c
@@ -89,19 +89,19 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
int i;
if (!QLIST_EMPTY(&tpm_backends)) {
- error_report("Only one TPM is allowed.");
+ error_setg(errp, "Only one TPM is allowed.");
return 1;
}
id = qemu_opts_id(opts);
if (id == NULL) {
- error_report(QERR_MISSING_PARAMETER, "id");
+ error_setg(errp, QERR_MISSING_PARAMETER, "id");
return 1;
}
value = qemu_opt_get(opts, "type");
if (!value) {
- error_report(QERR_MISSING_PARAMETER, "type");
+ error_setg(errp, QERR_MISSING_PARAMETER, "type");
tpm_display_backend_drivers();
return 1;
}
@@ -109,8 +109,8 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
i = qapi_enum_parse(&TpmType_lookup, value, -1, NULL);
be = i >= 0 ? tpm_be_find_by_type(i) : NULL;
if (be == NULL) {
- error_report(QERR_INVALID_PARAMETER_VALUE,
- "type", "a TPM backend type");
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type",
+ "a TPM backend type");
tpm_display_backend_drivers();
return 1;
}
@@ -118,7 +118,7 @@ static int tpm_init_tpmdev(void *dummy, QemuOpts *opts, Error **errp)
/* validate backend specific opts */
qemu_opts_validate(opts, be->opts, &local_err);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
return 1;
}
@@ -151,14 +151,10 @@ void tpm_cleanup(void)
* Initialize the TPM. Process the tpmdev command line options describing the
* TPM backend.
*/
-int tpm_init(void)
+void tpm_init(void)
{
- if (qemu_opts_foreach(qemu_find_opts("tpmdev"),
- tpm_init_tpmdev, NULL, NULL)) {
- return -1;
- }
-
- return 0;
+ qemu_opts_foreach(qemu_find_opts("tpmdev"),
+ tpm_init_tpmdev, NULL, &error_fatal);
}
/*
diff --git a/ui/curses.c b/ui/curses.c
index 59d819fd4d..f4e7a12f74 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -28,6 +28,7 @@
#include <termios.h>
#endif
+#include "qapi/error.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
@@ -421,9 +422,8 @@ static void curses_keyboard_setup(void)
keyboard_layout = "en-us";
#endif
if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
- if (!kbd_layout)
- exit(1);
+ kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout,
+ &error_fatal);
}
}
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 43fe604724..085889b555 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -27,6 +27,7 @@
#include "sysemu/sysemu.h"
#include "trace.h"
#include "qemu/error-report.h"
+#include "qapi/error.h"
struct keysym2code {
uint32_t count;
@@ -79,10 +80,11 @@ static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k)
trace_keymap_add(keysym, keycode, line);
}
-static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
- const char *language,
- kbd_layout_t *k)
+static int parse_keyboard_layout(kbd_layout_t *k,
+ const name2keysym_t *table,
+ const char *language, Error **errp)
{
+ int ret;
FILE *f;
char * filename;
char line[1024];
@@ -94,13 +96,8 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
f = filename ? fopen(filename, "r") : NULL;
g_free(filename);
if (!f) {
- fprintf(stderr, "Could not read keymap file: '%s'\n", language);
- return NULL;
- }
-
- if (!k) {
- k = g_new0(kbd_layout_t, 1);
- k->hash = g_hash_table_new(NULL, NULL);
+ error_setg(errp, "could not read keymap file: '%s'", language);
+ return -1;
}
for(;;) {
@@ -118,7 +115,10 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
continue;
}
if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(table, line + 8, k);
+ if (parse_keyboard_layout(k, table, line + 8, errp) < 0) {
+ ret = -1;
+ goto out;
+ }
} else {
int offset = 0;
while (line[offset] != 0 &&
@@ -164,15 +164,27 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
}
}
}
+
+ ret = 0;
+out:
fclose(f);
- return k;
+ return ret;
}
kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
- const char *language)
+ const char *language, Error **errp)
{
- return parse_keyboard_layout(table, language, NULL);
+ kbd_layout_t *k;
+
+ k = g_new0(kbd_layout_t, 1);
+ k->hash = g_hash_table_new(NULL, NULL);
+ if (parse_keyboard_layout(k, table, language, errp) < 0) {
+ g_hash_table_unref(k->hash);
+ g_free(k);
+ return NULL;
+ }
+ return k;
}
diff --git a/ui/keymaps.h b/ui/keymaps.h
index 0693588225..98213a4191 100644
--- a/ui/keymaps.h
+++ b/ui/keymaps.h
@@ -53,7 +53,7 @@ typedef struct {
typedef struct kbd_layout_t kbd_layout_t;
kbd_layout_t *init_keyboard_layout(const name2keysym_t *table,
- const char *language);
+ const char *language, Error **errp);
int keysym2scancode(kbd_layout_t *k, int keysym,
bool shift, bool altgr, bool ctrl);
int keycode_is_keypad(kbd_layout_t *k, int keycode);
diff --git a/ui/sdl.c b/ui/sdl.c
index a5fd503c25..190b16f575 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -29,6 +29,7 @@
#include <SDL.h>
#include <SDL_syswm.h>
+#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/cutils.h"
#include "ui/console.h"
@@ -917,9 +918,8 @@ static void sdl1_display_init(DisplayState *ds, DisplayOptions *o)
keyboard_layout = "en-us";
#endif
if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
- if (!kbd_layout)
- exit(1);
+ kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout,
+ &error_fatal);
}
g_printerr("Running QEMU with SDL 1.2 is deprecated, and will be removed\n"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index a4fbbc3898..ebaae24643 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -597,9 +597,9 @@ static int add_channel(void *opaque, const char *name, const char *value,
if (strcmp(name, "tls-channel") == 0) {
int *tls_port = opaque;
if (!*tls_port) {
- error_report("spice: tried to setup tls-channel"
- " without specifying a TLS port");
- exit(1);
+ error_setg(errp, "spice: tried to setup tls-channel"
+ " without specifying a TLS port");
+ return -1;
}
security = SPICE_CHANNEL_SECURITY_SSL;
}
@@ -615,8 +615,9 @@ static int add_channel(void *opaque, const char *name, const char *value,
rc = spice_server_set_channel_security(spice_server, value, security);
}
if (rc != 0) {
- error_report("spice: failed to set channel security for %s", value);
- exit(1);
+ error_setg(errp, "spice: failed to set channel security for %s",
+ value);
+ return -1;
}
return 0;
}
@@ -787,7 +788,7 @@ void qemu_spice_init(void)
spice_server_set_playback_compression
(spice_server, qemu_opt_get_bool(opts, "playback-compression", 1));
- qemu_opt_foreach(opts, add_channel, &tls_port, NULL);
+ qemu_opt_foreach(opts, add_channel, &tls_port, &error_fatal);
spice_server_set_name(spice_server, qemu_name);
spice_server_set_uuid(spice_server, (unsigned char *)&qemu_uuid);
diff --git a/ui/vnc.c b/ui/vnc.c
index cf221c83cc..0c1b477425 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3205,7 +3205,7 @@ static const DisplayChangeListenerOps dcl_ops = {
.dpy_cursor_define = vnc_dpy_cursor_define,
};
-void vnc_display_init(const char *id)
+void vnc_display_init(const char *id, Error **errp)
{
VncDisplay *vd;
@@ -3222,13 +3222,14 @@ void vnc_display_init(const char *id)
if (keyboard_layout) {
trace_vnc_key_map_init(keyboard_layout);
- vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
+ vd->kbd_layout = init_keyboard_layout(name2keysym,
+ keyboard_layout, errp);
} else {
- vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
+ vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
}
if (!vd->kbd_layout) {
- exit(1);
+ return;
}
vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
@@ -4079,11 +4080,15 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
char *id = (char *)qemu_opts_id(opts);
assert(id);
- vnc_display_init(id);
+ vnc_display_init(id, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return -1;
+ }
vnc_display_open(id, &local_err);
if (local_err != NULL) {
- error_reportf_err(local_err, "Failed to start VNC server: ");
- exit(1);
+ error_propagate(errp, local_err);
+ return -1;
}
return 0;
}
diff --git a/util/error.c b/util/error.c
index 3efdd69162..b5ccbd8eac 100644
--- a/util/error.c
+++ b/util/error.c
@@ -292,3 +292,16 @@ void error_propagate(Error **dst_errp, Error *local_err)
error_free(local_err);
}
}
+
+void error_propagate_prepend(Error **dst_errp, Error *err,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ if (dst_errp && !*dst_errp) {
+ va_start(ap, fmt);
+ error_vprepend(&err, fmt, ap);
+ va_end(ap);
+ } /* else error is being ignored, don't bother with prepending */
+ error_propagate(dst_errp, err);
+}
diff --git a/util/qemu-error.c b/util/qemu-error.c
index 4ab428f7e4..fcbe8a1f74 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -194,7 +194,6 @@ bool enable_timestamp_msg;
* Format arguments like vsprintf(). The resulting message should be
* a single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use error_setg() there.
*/
static void vreport(report_type type, const char *fmt, va_list ap)
{
@@ -242,7 +241,6 @@ void error_vreport(const char *fmt, va_list ap)
* Format arguments like vsprintf(). The resulting message should be
* a single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use error_setg() there.
*/
void warn_vreport(const char *fmt, va_list ap)
{
@@ -255,7 +253,6 @@ void warn_vreport(const char *fmt, va_list ap)
* Format arguments like vsprintf(). The resulting message should be
* a single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use error_setg() there.
*/
void info_vreport(const char *fmt, va_list ap)
{
@@ -283,7 +280,6 @@ void error_report(const char *fmt, ...)
* Format arguments like sprintf(). The resulting message should be a
* single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use error_setg() there.
*/
void warn_report(const char *fmt, ...)
{
@@ -300,7 +296,6 @@ void warn_report(const char *fmt, ...)
* Format arguments like sprintf(). The resulting message should be a
* single phrase, with no newline or trailing punctuation.
* Prepend the current location and append a newline.
- * It's wrong to call this in a QMP monitor. Use error_setg() there.
*/
void info_report(const char *fmt, ...)
{
diff --git a/vl.c b/vl.c
index 9c345223a0..1fcacc5caa 100644
--- a/vl.c
+++ b/vl.c
@@ -1093,12 +1093,12 @@ static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
fd_opaque = qemu_opt_get(opts, "opaque");
if (fd < 0) {
- error_report("fd option is required and must be non-negative");
+ error_setg(errp, "fd option is required and must be non-negative");
return -1;
}
if (fd <= STDERR_FILENO) {
- error_report("fd cannot be a standard I/O stream");
+ error_setg(errp, "fd cannot be a standard I/O stream");
return -1;
}
@@ -1108,12 +1108,12 @@ static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
*/
flags = fcntl(fd, F_GETFD);
if (flags == -1 || (flags & FD_CLOEXEC)) {
- error_report("fd is not valid or already in use");
+ error_setg(errp, "fd is not valid or already in use");
return -1;
}
if (fdset_id < 0) {
- error_report("set option is required and must be non-negative");
+ error_setg(errp, "set option is required and must be non-negative");
return -1;
}
@@ -1126,7 +1126,7 @@ static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp)
}
#endif
if (dupfd == -1) {
- error_report("error duplicating fd: %s", strerror(errno));
+ error_setg(errp, "error duplicating fd: %s", strerror(errno));
return -1;
}
@@ -1163,7 +1163,7 @@ static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
BlockInterfaceType *block_default_type = opaque;
- return drive_new(opts, *block_default_type) == NULL;
+ return drive_new(opts, *block_default_type, errp) == NULL;
}
static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
@@ -1189,10 +1189,7 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type,
drive_enable_snapshot(NULL, opts, NULL);
}
- dinfo = drive_new(opts, type);
- if (!dinfo) {
- exit(1);
- }
+ dinfo = drive_new(opts, type, &error_abort);
dinfo->is_default = true;
}
@@ -1233,11 +1230,14 @@ static void smp_parse(QemuOpts *opts)
/* compute missing values, prefer sockets over cores over threads */
if (cpus == 0 || sockets == 0) {
- sockets = sockets > 0 ? sockets : 1;
cores = cores > 0 ? cores : 1;
threads = threads > 0 ? threads : 1;
if (cpus == 0) {
+ sockets = sockets > 0 ? sockets : 1;
cpus = cores * threads * sockets;
+ } else {
+ max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
+ sockets = max_cpus / (cores * threads);
}
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
@@ -1269,6 +1269,13 @@ static void smp_parse(QemuOpts *opts)
exit(1);
}
+ if (sockets * cores * threads != max_cpus) {
+ warn_report("Invalid CPU topology deprecated: "
+ "sockets (%u) * cores (%u) * threads (%u) "
+ "!= maxcpus (%u)",
+ sockets, cores, threads, max_cpus);
+ }
+
smp_cpus = cpus;
smp_cores = cores;
smp_threads = threads;
@@ -2036,15 +2043,10 @@ static void select_vgahw(const char *p)
static void parse_display_qapi(const char *optarg)
{
- Error *err = NULL;
DisplayOptions *opts;
Visitor *v;
- v = qobject_input_visitor_new_str(optarg, "type", &err);
- if (!v) {
- error_report_err(err);
- exit(1);
- }
+ v = qobject_input_visitor_new_str(optarg, "type", &error_fatal);
visit_type_DisplayOptions(v, NULL, &opts, &error_fatal);
QAPI_CLONE_MEMBERS(DisplayOptions, &dpy, opts);
@@ -2213,7 +2215,7 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
FWCfgState *fw_cfg = (FWCfgState *) opaque;
if (fw_cfg == NULL) {
- error_report("fw_cfg device not available");
+ error_setg(errp, "fw_cfg device not available");
return -1;
}
name = qemu_opt_get(opts, "name");
@@ -2222,15 +2224,16 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
/* we need name and either a file or the content string */
if (!(nonempty_str(name) && (nonempty_str(file) || nonempty_str(str)))) {
- error_report("invalid argument(s)");
+ error_setg(errp, "invalid argument(s)");
return -1;
}
if (nonempty_str(file) && nonempty_str(str)) {
- error_report("file and string are mutually exclusive");
+ error_setg(errp, "file and string are mutually exclusive");
return -1;
}
if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) {
- error_report("name too long (max. %d char)", FW_CFG_MAX_FILE_PATH - 1);
+ error_setg(errp, "name too long (max. %d char)",
+ FW_CFG_MAX_FILE_PATH - 1);
return -1;
}
if (strncmp(name, "opt/", 4) != 0) {
@@ -2242,7 +2245,7 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
buf = g_memdup(str, size);
} else {
if (!g_file_get_contents(file, &buf, &size, NULL)) {
- error_report("can't load %s", file);
+ error_setg(errp, "can't load %s", file);
return -1;
}
}
@@ -2260,12 +2263,10 @@ static int device_help_func(void *opaque, QemuOpts *opts, Error **errp)
static int device_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
- Error *err = NULL;
DeviceState *dev;
- dev = qdev_device_add(opts, &err);
+ dev = qdev_device_add(opts, errp);
if (!dev) {
- error_report_err(err);
return -1;
}
object_unref(OBJECT(dev));
@@ -2278,7 +2279,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
if (!qemu_chr_new_from_opts(opts, &local_err)) {
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
return -1;
}
exit(0);
@@ -2289,7 +2290,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp)
#ifdef CONFIG_VIRTFS
static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
- return qemu_fsdev_add(opts);
+ return qemu_fsdev_add(opts, errp);
}
#endif
@@ -2309,8 +2310,8 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
} else if (strcmp(mode, "control") == 0) {
flags = MONITOR_USE_CONTROL;
} else {
- error_report("unknown monitor mode \"%s\"", mode);
- exit(1);
+ error_setg(errp, "unknown monitor mode \"%s\"", mode);
+ return -1;
}
if (qemu_opt_get_bool(opts, "pretty", 0))
@@ -2324,8 +2325,8 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
chardev = qemu_opt_get(opts, "chardev");
chr = qemu_chr_find(chardev);
if (chr == NULL) {
- error_report("chardev \"%s\" not found", chardev);
- exit(1);
+ error_setg(errp, "chardev \"%s\" not found", chardev);
+ return -1;
}
monitor_init(chr, flags);
@@ -2500,6 +2501,7 @@ static int debugcon_parse(const char *devname)
QemuOpts *opts;
if (!qemu_chr_new_mux_mon("debugcon", devname)) {
+ error_report("invalid character backend '%s'", devname);
exit(1);
}
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
@@ -2715,7 +2717,7 @@ static int machine_set_property(void *opaque,
g_free(qom_name);
if (local_err) {
- error_report_err(local_err);
+ error_propagate(errp, local_err);
return -1;
}
@@ -4011,26 +4013,20 @@ int main(int argc, char **argv, char **envp)
#ifdef CONFIG_SECCOMP
olist = qemu_find_opts_err("sandbox", NULL);
- if (olist && qemu_opts_foreach(olist, parse_sandbox, NULL, NULL)) {
- exit(1);
+ if (olist) {
+ qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal);
}
#endif
- if (qemu_opts_foreach(qemu_find_opts("name"),
- parse_name, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("name"),
+ parse_name, NULL, &error_fatal);
#ifndef _WIN32
- if (qemu_opts_foreach(qemu_find_opts("add-fd"),
- parse_add_fd, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("add-fd"),
+ parse_add_fd, NULL, &error_fatal);
- if (qemu_opts_foreach(qemu_find_opts("add-fd"),
- cleanup_add_fd, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("add-fd"),
+ cleanup_add_fd, NULL, &error_fatal);
#endif
current_machine = MACHINE(object_new(object_class_get_name(
@@ -4271,22 +4267,16 @@ int main(int argc, char **argv, char **envp)
page_size_init();
socket_init();
- if (qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_initial, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("object"),
+ user_creatable_add_opts_foreach,
+ object_create_initial, &error_fatal);
- if (qemu_opts_foreach(qemu_find_opts("chardev"),
- chardev_init_func, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("chardev"),
+ chardev_init_func, NULL, &error_fatal);
#ifdef CONFIG_VIRTFS
- if (qemu_opts_foreach(qemu_find_opts("fsdev"),
- fsdev_init_func, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("fsdev"),
+ fsdev_init_func, NULL, &error_fatal);
#endif
if (qemu_opts_foreach(qemu_find_opts("device"),
@@ -4295,11 +4285,8 @@ int main(int argc, char **argv, char **envp)
}
machine_opts = qemu_get_machine_opts();
- if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
- NULL)) {
- object_unref(OBJECT(current_machine));
- exit(1);
- }
+ qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
+ &error_fatal);
configure_accelerator(current_machine);
@@ -4404,15 +4391,11 @@ int main(int argc, char **argv, char **envp)
exit(1);
}
- if (qemu_opts_foreach(qemu_find_opts("object"),
- user_creatable_add_opts_foreach,
- object_create_delayed, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("object"),
+ user_creatable_add_opts_foreach,
+ object_create_delayed, &error_fatal);
- if (tpm_init() < 0) {
- exit(1);
- }
+ tpm_init();
/* init the bluetooth world */
if (foreach_device_config(DEV_BT, bt_parse))
@@ -4453,8 +4436,9 @@ int main(int argc, char **argv, char **envp)
NULL, NULL);
}
if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
- &machine_class->block_default_type, NULL)) {
- exit(1);
+ &machine_class->block_default_type, &error_fatal)) {
+ /* We printed help */
+ exit(0);
}
default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2,
@@ -4462,10 +4446,8 @@ int main(int argc, char **argv, char **envp)
default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS);
default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS);
- if (qemu_opts_foreach(qemu_find_opts("mon"),
- mon_init_func, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("mon"),
+ mon_init_func, NULL, &error_fatal);
if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
exit(1);
@@ -4528,10 +4510,8 @@ int main(int argc, char **argv, char **envp)
hax_sync_vcpus();
}
- if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
- parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("fw_cfg"),
+ parse_fw_cfg, fw_cfg_find(), &error_fatal);
/* init USB devices */
if (machine_usb(current_machine)) {
@@ -4544,10 +4524,8 @@ int main(int argc, char **argv, char **envp)
/* init generic devices */
rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE);
- if (qemu_opts_foreach(qemu_find_opts("device"),
- device_init_func, NULL, NULL)) {
- exit(1);
- }
+ qemu_opts_foreach(qemu_find_opts("device"),
+ device_init_func, NULL, &error_fatal);
cpu_synchronize_all_post_init();
@@ -4583,7 +4561,7 @@ int main(int argc, char **argv, char **envp)
/* init remote displays */
#ifdef CONFIG_VNC
qemu_opts_foreach(qemu_find_opts("vnc"),
- vnc_init_func, NULL, NULL);
+ vnc_init_func, NULL, &error_fatal);
#endif
if (using_spice) {